Skip to content

Commit

Permalink
Fix and refactor xjsonEscape() / xjsonUnescape() and site update
Browse files Browse the repository at this point in the history
  • Loading branch information
attipaci committed Dec 13, 2024
1 parent 75f1e64 commit 434193c
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 41 deletions.
4 changes: 2 additions & 2 deletions include/xjson.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ XStructure *xjsonParseAt(char **src, int *lineNumber);
XField *xjsonParseFieldAt(char **src, int *lineNumber);
void xjsonSetErrorStream(FILE *fp);

char *xjsonEscapeString(const char *src, int maxLength);
char *xjsonUnescapeString(const char *json);
char *xjsonEscape(const char *src, int maxLength);
char *xjsonUnescape(const char *json);

#endif /* XJSON_H_ */
105 changes: 66 additions & 39 deletions src/xjson.c
Original file line number Diff line number Diff line change
Expand Up @@ -583,9 +583,35 @@ static char UnescapedChar(char c) {
return c;
}

static int json2raw(const char *json, int maxlen, char *dst) {
int isEscaped = 0;
int i, l = 0;

for(i = 0; l < maxlen; i++) {
char c = json[i];

if(isEscaped) {
isEscaped = FALSE;
if(c == 'u') {
dst[l++] = '\\'; // Keep unicode as is...
dst[l++] = 'u';
}
else {
dst[l++] = UnescapedChar(c);
}
}
else if(c == '\0') break;
else if(c == '\\') isEscaped = TRUE;
else dst[l++] = c;
}

dst[l] = '\0';
return l;
}

static char *ParseString(char **pos, int *lineNumber) {
int isEscaped = 0;
int i, k, l;
int i, l;
char *next, *dst;

next = *pos = SkipSpaces(*pos, lineNumber);
Expand Down Expand Up @@ -624,24 +650,7 @@ static char *ParseString(char **pos, int *lineNumber) {
return NULL;
}

for(i = k = 0; k < l; i++) {
char c = next[i];

if(isEscaped) {
isEscaped = FALSE;
if(c == 'u') {
dst[k++] = '\\'; // Keep unicode as is...
dst[k++] = 'u';
}
else {
dst[k++] = UnescapedChar(c);
}
}
else if(c == '\\') isEscaped = TRUE;
else dst[k++] = c;
}

dst[l] = '\0';
json2raw(next, l, dst);

return dst;
}
Expand Down Expand Up @@ -1250,24 +1259,34 @@ static char GetEscapedChar(char c) {
}


static int PrintString(const char *src, int maxLength, char *json) {
int i;
static int raw2json(const char *src, int maxlen, char *json) {
char *next = json;
int i;

if(maxLength < 0) maxLength = INT_MAX;

*(next++) = '"';

for(i = 0; i < maxLength && src[i]; i++) switch(GetJsonBytes(src[i])) {
for(i = 0; i < maxlen && src[i]; i++) switch(GetJsonBytes(src[i])) {
case 2:
*(next++) = '\\';
*(next++) = GetEscapedChar(src[i]);
break;
break;
case 1:
*(next++) = src[i];
break;
}

*(next++) = '\0';

return next - json - 1;
}

static int PrintString(const char *src, int maxLength, char *json) {
char *next = json;

if(maxLength < 0) maxLength = INT_MAX;

*(next++) = '"';

next += raw2json(src, maxLength, next);

*(next++) = '"';
*(next++) = '\0';

Expand All @@ -1284,10 +1303,10 @@ static int PrintString(const char *src, int maxLength, char *json) {
* @return The JSON representation of the original string, in which special characters
* appear in escaped form (without the surrounding double quotes).
*
* @sa xjsonUnescapeString()
* @sa xjsonUnescape()
*/
char *xjsonEscapeString(const char *src, int maxLength) {
static const char *fn = "xjsonEscapeString";
char *xjsonEscape(const char *src, int maxLength) {
static const char *fn = "xjsonEscape";

int size;
char *json;
Expand All @@ -1305,10 +1324,7 @@ char *xjsonEscapeString(const char *src, int maxLength) {
return NULL;
}

if(PrintString(src, maxLength, json) != X_SUCCESS) {
free(json);
return x_trace_null(fn, NULL);
}
raw2json(src, maxLength, json);

return json;
}
Expand All @@ -1320,15 +1336,26 @@ char *xjsonEscapeString(const char *src, int maxLength) {
* appear in escaped form (without the surrounding double quotes).
* @return The native string, which may contain special characters.
*
* @sa xjsonEscapeString()
* @sa xjsonEscape()
*/
char *xjsonUnescapeString(const char *str) {
int lineNumber = 0;
char *xjsonUnescape(const char *str) {
static const char *fn = "xjsonUnescape";

char *raw;
int l;

if(!str) {
x_error(0, EINVAL, "xjsonUnescapeString", "input string is NULL");
x_error(0, EINVAL, fn, "input string is NULL");
return NULL;
}

l = strlen(str);
raw = (char *) malloc(l + 1);
if(!raw) {
x_error(0, errno, fn, "alloc error (%ld bytes)", (l + 1));
return NULL;
}

return ParseString((char **) &str, &lineNumber);
json2raw(str, l, raw);
return raw;
}

0 comments on commit 434193c

Please sign in to comment.