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/jsonWrite.c src/lib/jsonWrite.c
index df7e9fb..8ed3e02 100644
--- src/lib/jsonWrite.c
+++ src/lib/jsonWrite.c
@@ -70,35 +70,41 @@
     dyStringAppendC(jw->dy, jw->sep);
     }
 else
     jw->objStack[jw->stackIx].isNotEmpty = TRUE;
 }
 
 void jsonWriteTag(struct jsonWrite *jw, char *var)
 /* Print out preceding comma if necessary, and if var is non-NULL, quoted tag followed by colon. */
 {
 jsonWriteMaybeComma(jw);
 if (var != NULL)
     dyStringPrintf(jw->dy, "\"%s\": ", var);
 }
 
 void jsonWriteString(struct jsonWrite *jw, char *var, char *string)
-/* Print out "var": "val".  If var is NULL, print val only.  If string is NULL, "var": null . */
+/* Print out "var": "val" -- or rather, jsonStringEscape(val).
+ * If var is NULL, print val only.  If string is NULL, "var": null . */
 {
 jsonWriteTag(jw, var);
 if (string)
-    dyStringPrintf(jw->dy, "\"%s\"", string);
+    {
+    size_t encSize = jsonStringEscapeSize(string);
+    char encoded[encSize];
+    jsonStringEscapeBuf(string, encoded, encSize);
+    dyStringPrintf(jw->dy, "\"%s\"", encoded);
+    }
 else
     dyStringAppend(jw->dy, "null");
 }
 
 void jsonWriteDateFromUnix(struct jsonWrite *jw, char *var, long long unixTimeVal)
 /* Add "var": YYYY-MM-DDT-HH:MM:SSZ given a Unix time stamp. Var may be NULL. */
 {
 struct dyString *dy = jw->dy;
 time_t timeStamp = unixTimeVal;
 struct tm tm;
 gmtime_r(&timeStamp, &tm);
 jsonWriteTag(jw, var);
 dyStringPrintf(dy, "\"%d:%02d:%02dT%02d:%02d:%02dZ\"",
     1900+tm.tm_year, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
 }
@@ -166,40 +172,38 @@
 jsonWritePushObjStack(jw, FALSE, TRUE);
 }
 
 void jsonWriteObjectEnd(struct jsonWrite *jw)
 /* End object in JSON */
 {
 struct dyString *dy = jw->dy;
 dyStringAppendC(dy, '}');
 dyStringAppendC(dy, jw->sep);
 jsonWritePopObjStack(jw, TRUE);
 }
 
 void jsonWriteStringf(struct jsonWrite *jw, char *var, char *format, ...)
 /* Write "var": "val" where val is jsonStringEscape'd formatted string. */
 {
-// Since we're using jsonStringEscape(), we need to use a temporary dyString
-// instead of jw->dy.
+// In order to use jsonStringEscape(), we need to use a temporary dyString
+// instead of jw->dy in the dyStringVaPrintf, and pass that to jsonWriteString.
 struct dyString *tmpDy = dyStringNew(0);
 va_list args;
 va_start(args, format);
 dyStringVaPrintf(tmpDy, format, args);
 va_end(args);
-char *escaped = jsonStringEscape(tmpDy->string);
-jsonWriteString(jw, var, escaped);
-freeMem(escaped);
+jsonWriteString(jw, var, tmpDy->string);
 dyStringFree(&tmpDy);
 }
 
 void jsonWriteBoolean(struct jsonWrite *jw, char *var, boolean val)
 /* Write out "var": true or "var": false depending on val (no quotes around true/false). */
 {
 jsonWriteTag(jw, var);
 dyStringAppend(jw->dy, val ? "true" : "false");
 }
 
 void jsonWriteValueLabelList(struct jsonWrite *jw, char *var, struct slPair *pairList)
 /* Print out a named list of {"value": "<pair->name>", "label": "<pair->val>"} objects. */
 {
 jsonWriteListStart(jw, var);
 struct slPair *pair;