24a1b93cb1cb3590e987bf5c2910fed600d44a66
max
Tue Sep 15 05:48:40 2026 -0700
hgc: a mistyped detailsScript setting must not take down the details page, refs #38353
The null case was covered but nothing else was. jsonParse() aborts on malformed JSON and
jsonObjectVal() aborts on any value that is not an object, so a hub with
"detailsScript.histogram.myField 5" in its trackDb lost the whole details page, not just
that one plot. Caught now: the setting is dropped and the rest of the page is drawn.
diff --git src/hg/hgc/bigBedClick.c src/hg/hgc/bigBedClick.c
index 45dd8e7b564..c403b709d14 100644
--- src/hg/hgc/bigBedClick.c
+++ src/hg/hgc/bigBedClick.c
@@ -7,30 +7,31 @@
#include "wiggle.h"
#include "cart.h"
#include "hgc.h"
#include "hubConnect.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"
+#include "errCatch.h"
#include "jsonWrite.h"
#include "net.h"
#include "trackHub.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");
@@ -636,35 +637,44 @@
jsonWriteObjectStart(jw, NULL);
jsonWriteString(jw, "field", fp->name);
// Look up field value from bigBed extra fields
char *fv = "";
if (extraFieldPairs)
{
char *found = slPairFindVal(extraFieldPairs, fp->name);
if (found)
fv = found;
}
jsonWriteString(jw, "value", fv);
// Parse trackDb JSON config and merge its keys into this object
char *jsonConfig = fp->val;
if (isNotEmpty(jsonConfig))
{
- struct jsonElement *configEl = jsonParse(jsonConfig);
- // jsonObjectVal hands back NULL for a JSON null, and the hash
- // routines below dereference their argument, so a hub writing
- // "detailsScript.. null" would crash us.
- struct hash *configHash = jsonObjectVal(configEl, "detailsScript config");
+ /* This text comes out of a hub's trackDb, so it may be anything at
+ * all. jsonParse aborts on malformed JSON and jsonObjectVal aborts on
+ * a value that is not an object, so one mistyped setting - "histogram
+ * myField 5" - would otherwise take down the whole details page.
+ * jsonObjectVal also hands back NULL for a JSON null, and the hash
+ * routines below dereference their argument. Catch all of it, drop
+ * the setting and carry on with the rest of the page. */
+ struct hash *configHash = NULL;
+ struct errCatch *errCatch = errCatchNew();
+ if (errCatchStart(errCatch))
+ configHash = jsonObjectVal(jsonParse(jsonConfig),
+ "detailsScript config");
+ errCatchEnd(errCatch);
+ errCatchFree(&errCatch);
if (configHash == NULL)
{
jsonWriteObjectEnd(jw);
continue;
}
struct hashEl *cel, *celList = hashElListHash(configHash);
for (cel = celList; cel != NULL; cel = cel->next)
{
// A config key ending in "Url" names a file, by the same convention
// trackSettingIsFile() uses. The JS does not fetch it directly: it
// asks hgTrackUi for it, which checks the path against the hubs on
// this cart and reads it with udc. So resolve a relative path here
// against the track's own bigDataUrl, which works whether the hub
// was loaded over http or from a local path. A path the author
// already made absolute is left alone.