074ea922bc80e0c46b93fb22b91426770022e4e2
braney
  Tue Aug 18 10:59:40 2026 -0700
lib, cheapcgi: encode some JSON tags and HTML attributes consistently, refs #38123

diff --git src/lib/jsonWrite.c src/lib/jsonWrite.c
index 5f271e5174e..4b90f9447d9 100644
--- src/lib/jsonWrite.c
+++ src/lib/jsonWrite.c
@@ -66,31 +66,37 @@
 {
 if (jw->objStack[jw->stackIx].isNotEmpty)
     {
     dyStringAppendC(jw->dy, ',');
     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);
+    {
+    // tags are not always literals: hub assembly and track names end up here, so a tag is
+    // encoded the same way a value is.
+    char *encoded = jsonStringEscape(var);
+    dyStringPrintf(jw->dy, "\"%s\": ", encoded);
+    freeMem(encoded);
+    }
 }
 
 void jsonWriteString(struct jsonWrite *jw, char *var, char *string)
 /* 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)
     {
     size_t encSize = jsonStringEscapeSize(string);
     char *encoded = needMem(encSize);  /* needMem limit is 500,000,000 */
     jsonStringEscapeBuf(string, encoded, encSize);
     dyStringPrintf(jw->dy, "\"%s\"", encoded);
     freeMem(encoded);
     }