1ee99ce653ae839e4774120c3f3923dc129c8533 angie Fri Mar 16 14:41:14 2018 -0700 Moved jsonStringEscape inside jsonWriteString because it's silly to have to remember to call it first every time. tagStorm programs were doing their own limited escaping (double-quotes only); now they get the same escaping as everywhere else. refs MLQ #21113 diff --git src/lib/jsonParse.c src/lib/jsonParse.c index 29216c2..a7bd90e 100644 --- src/lib/jsonParse.c +++ src/lib/jsonParse.c @@ -359,98 +359,116 @@ } return NULL; } struct jsonElement *jsonParse(char *str) { // parse string into an in-memory json representation int pos = 0; struct jsonElement *ele = jsonParseExpression(str, &pos); skipLeadingSpacesWithPos(str, &pos); if(str[pos]) errAbort("Invalid JSON: unprocessed trailing string at position: %d: %s", pos, str + pos); return ele; } -char *jsonStringEscape(char *inString) -/* backslash escape a string for use in a double quoted json string. - * More conservative than javaScriptLiteralEncode because - * some json parsers complain if you escape & or ' */ +int jsonStringEscapeSize(char *inString) +/* Return the size in bytes including terminal '\0' for escaped string. */ { -char c; -int outSize = 0; -char *outString, *out, *in; - if (inString == NULL) - return(cloneString("")); - -/* Count up how long it will be */ -in = inString; + // Empty string + return 1; +int outSize = 0; +char *in = inString, c; while ((c = *in++) != 0) { switch(c) { case '\"': case '\\': case '/': case '\b': case '\f': outSize += 2; break; case '\r': case '\t': case '\n': outSize += 3; break; default: outSize += 1; } } -outString = needMem(outSize+1); +return outSize + 1; +} +void jsonStringEscapeBuf(char *inString, char *buf, size_t bufSize) +/* backslash escape a string for use in a double quoted json string. + * More conservative than javaScriptLiteralEncode because + * some json parsers complain if you escape & or '. + * bufSize must be at least jsonStringEscapeSize(inString). */ +{ +if (inString == NULL) + { + // Empty string + buf[0] = 0; + return; + } /* Encode string */ -in = inString; -out = outString; +char *in = inString, *out = buf, c; while ((c = *in++) != 0) { + if (out - buf >= bufSize-1) + errAbort("jsonStringEscapeBuf: insufficient buffer size"); switch(c) { case '\"': case '\\': case '/': case '\b': case '\f': *out++ = '\\'; *out++ = c; break; case '\r': *out++ = '\\'; *out++ = 'r'; break; case '\t': *out++ = '\\'; *out++ = 't'; break; case '\n': *out++ = '\\'; *out++ = 'n'; break; default: *out++ = c; } } *out++ = 0; +} + +char *jsonStringEscape(char *inString) +/* backslash escape a string for use in a double quoted json string. + * More conservative than javaScriptLiteralEncode because + * some json parsers complain if you escape & or ' */ +{ +int outSize = jsonStringEscapeSize(inString); +char *outString = needMem(outSize); +jsonStringEscapeBuf(inString, outString, outSize); return outString; } void jsonFindNameRecurse(struct jsonElement *ele, char *jName, struct slName **pList) // Search the JSON tree recursively to find all the values associated to // the name, and add them to head of the list. { switch (ele->type) { case jsonObject: { if(hashNumEntries(ele->val.jeHash)) { struct hashEl *el, *list = hashElListHash(ele->val.jeHash); slSort(&list, hashElCmp);