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("<H3>Links to sequence:</H3>\n"); printf("<UL>\n"); puts("<LI>\n"); hgcAnchorSomewhere("htcTranslatedPredMRna", item, "translate", seqName); printf("Translated Protein</A> from genomic DNA\n"); puts("</LI>\n"); puts("<LI>\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.<plotType>.<field> 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.