13e088f3619ab994fda1c766473b2132c09eb852
larrym
  Wed May 16 15:18:11 2012 -0700
add jsonStringEscape; make .h header comments match .c file
diff --git src/hg/lib/jsHelper.c src/hg/lib/jsHelper.c
index 44d3afe..b9e29b9 100644
--- src/hg/lib/jsHelper.c
+++ src/hg/lib/jsHelper.c
@@ -594,31 +594,31 @@
         if(ele->val.jeList)
             {
             for (el = ele->val.jeList; el != NULL; el = el->next)
                 {
                 struct jsonElement *val = el->val;
                 hPrintf("%s%s", indentBuf,tab);
                 jsonPrintRecurse(val, indentLevel);
                 hPrintf("%s%s", el->next == NULL ? "" : ",",nl);
                 }
             }
         hPrintf("%s]", indentBuf);
         break;
         }
     case jsonString:
         {
-        hPrintf("\"%s\"", javaScriptLiteralEncode(ele->val.jeString));
+        hPrintf("\"%s\"", jsonStringEscape(ele->val.jeString));
         break;
         }
     case jsonBoolean:
         {
         hPrintf("%s", ele->val.jeBoolean ? "true" : "false");
         break;
         }
     case jsonNumber:
         {
         char buf[256];
         safef(buf, sizeof(buf), "%ld", ele->val.jeNumber);
         hPrintf("%s", buf);
         break;
         }
     case jsonDouble:
@@ -671,31 +671,31 @@
     jsonPrint(jsonGlobalsHash, "common", 0);
     if (wrapWithScriptTags)
         printf("</script>\n");
     }
 }
 
 void jsonErrPrintf(struct dyString *ds, char *format, ...)
 //  Printf a json error to a dyString for communicating with ajax code; format is:
 //  {"error": error message here}
 {
 va_list args;
 va_start(args, format);
 dyStringPrintf(ds, "{\"error\": \"");
 struct dyString *buf = newDyString(1000);
 dyStringVaPrintf(buf, format, args);
-dyStringAppend(ds, javaScriptLiteralEncode(dyStringCannibalize(&buf)));
+dyStringAppend(ds, jsonStringEscape(dyStringCannibalize(&buf)));
 dyStringPrintf(ds, "\"}");
 va_end(args);
 }
 
 static void skipLeadingSpacesWithPos(char *s, int *posPtr)
 /* skip leading white space. */
 {
 for (;;)
     {
     char c = s[*posPtr];
     if (!isspace(c))
 	return;
     (*posPtr)++;
     }
 }
@@ -884,15 +884,73 @@
 else
     return jsonParseBoolean(str, posPtr);
 // XXXX support 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 ' */
+{
+char c;
+int outSize = 0;
+char *outString, *out, *in;
+
+if (inString == NULL)
+    return(cloneString(""));
+
+/* Count up how long it will be */
+in = inString;
+while ((c = *in++) != 0)
+    {
+    switch(c)
+        {
+        case '\"':
+        case '\\':
+        case '/':
+        case '\b':
+        case '\f':
+        case '\n':
+        case '\r':
+        case '\t':
+            outSize += 2;
+            break;
+        default:
+            outSize += 1;
+        }
+    }
+outString = needMem(outSize+1);
+
+/* Encode string */
+in = inString;
+out = outString;
+while ((c = *in++) != 0)
+    {
+    switch(c)
+        {
+        case '\"':
+        case '\\':
+        case '/':
+        case '\b':
+        case '\f':
+        case '\n':
+        case '\r':
+        case '\t':
+            *out++ = '\\';
+            break;
+        }
+    *out++ = c;
+    }
+*out++ = 0;
+return outString;
+}