934a51aa2ebc7e11bfba57804642cd03e4e1e60a braney Tue Aug 18 11:45:11 2026 -0700 trackHub: tighten group name validation, refs #38123 diff --git src/hg/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c index 71f2ae89df5..422915607e3 100644 --- src/hg/hgTracks/hgTracks.c +++ src/hg/hgTracks/hgTracks.c @@ -8883,31 +8883,33 @@ if (sameOk(track->groupName, "user") || sameOk(track->groupName, "blat")) printTrackDelIcon(track); char *quickLiftSourceDb = (track->tdb != NULL) ? trackDbSetting(track->tdb, "quickLiftDb") : NULL; /* skip the synthetic "Alignment Differences" track -- it's added at runtime * by hubConnect, not from the hub file, so removing it from the file is a * no-op and it would reappear on the next page load. */ if (quickLiftSourceDb != NULL && (track->tdb->type == NULL || !startsWith("bigQuickLiftChain", track->tdb->type))) printQuickLiftDelIcon(track, quickLiftSourceDb); if (track->hasUi) { char *url = trackUrl(track->track, chromName); - char *longLabel = replaceChars(track->longLabel, "\"", """); + // longLabel comes from trackDb, which a track hub controls, so encode it to match the + // shortLabel below. + char *longLabel = htmlEncode(track->longLabel); struct dyString *dsMouseOver = dyStringCreate("%s", longLabel); struct trackDb *tdb = track->tdb; if (tdbIsSuper(tdb)) dyStringPrintf(dsMouseOver, " - container, %d tracks ", slCount(tdb->children)); else if (tdbIsComposite(tdb)) dyStringPrintf(dsMouseOver, " - container, %d subtracks ", slCount(tdb->subtracks)); // Print icons before the title when any are defined hPrintIcons(track->tdb); hPrintf("", url, track->groupName, track->track, dyStringCannibalize(&dsMouseOver)); freeMem(url);