cc9a51b3c9de74d78a0c7eeedb2b83d6336108c5
max
Mon Mar 23 04:36:13 2026 -0700
automated code review found that we already have an escape function, so asked Claude to us it, refs #37273
diff --git src/hg/hgc/bigBedClick.c src/hg/hgc/bigBedClick.c
index 23c972f03f3..6df3282ae3c 100644
--- src/hg/hgc/bigBedClick.c
+++ src/hg/hgc/bigBedClick.c
@@ -5,30 +5,31 @@
#include "common.h"
#include "wiggle.h"
#include "cart.h"
#include "hgc.h"
#include "hCommon.h"
#include "hgColors.h"
#include "bigBed.h"
#include "hui.h"
#include "subText.h"
#include "web.h"
#include "chromAlias.h"
#include "quickLift.h"
#include "hgConfig.h"
#include "jsHelper.h"
+#include "jsonParse.h"
static void bigGenePredLinks(char *track, char *item)
/* output links to genePred driven sequence dumps */
{
printf("
Links to sequence:
\n");
printf("\n");
puts("- \n");
hgcAnchorSomewhere("htcTranslatedPredMRna", item, "translate", seqName);
printf("Translated Protein from genomic DNA\n");
puts("
\n");
puts("- \n");
hgcAnchorSomewhere("htcGeneMrna", item, track, seqName);
printf("Predicted mRNA \n");
puts("
\n");
@@ -569,46 +570,33 @@
{
dyStringAppend(ds, ",\"fields\":{");
char *fieldsCopy = cloneString(detailsJsFieldsStr);
char *fieldNames[256];
int nFields = chopCommas(fieldsCopy, fieldNames);
boolean first = TRUE;
int fi;
for (fi = 0; fi < nFields; fi++)
{
char *fn = trimSpaces(fieldNames[fi]);
char *fv = slPairFindVal(extraFieldPairs, fn);
if (fv == NULL)
fv = "";
if (!first)
dyStringAppendC(ds, ',');
- dyStringPrintf(ds, "\"%s\":", fn);
- dyStringAppendC(ds, '"');
- // JSON-escape the value
- char *c;
- for (c = fv; *c; c++)
- {
- if (*c == '"')
- dyStringAppend(ds, "\\\"");
- else if (*c == '\\')
- dyStringAppend(ds, "\\\\");
- else if (*c == '\n')
- dyStringAppend(ds, "\\n");
- else
- dyStringAppendC(ds, *c);
- }
- dyStringAppendC(ds, '"');
+ char *escaped = jsonStringEscape(fv);
+ dyStringPrintf(ds, "\"%s\":\"%s\"", fn, escaped);
+ freeMem(escaped);
first = FALSE;
}
dyStringAppendC(ds, '}');
}
// Include detailsJsArgs if present
char *detailsJsArgs = trackDbSetting(tdb, "detailsJsArgs");
if (detailsJsArgs)
dyStringPrintf(ds, ",\"args\":%s", detailsJsArgs);
dyStringAppend(ds, "};\n");
// Call the default function derived from each JS filename (strip .js)
// e.g. barChart.js -> barChart(bedDetails)
for (ji = 0; ji < jsFileCount; ji++)