20ca104b9897669e127e4ec8675321b12f780cff braney Tue Aug 18 11:19:44 2026 -0700 lib, hgTracks: encode JSON object keys and configure/search text, refs #38123 diff --git src/hg/hgTracks/config.c src/hg/hgTracks/config.c index fecdf3b03bf..52f5dcdd8bb 100644 --- src/hg/hgTracks/config.c +++ src/hg/hgTracks/config.c @@ -345,31 +345,32 @@ &indicator, &otherState); hPrintf("<TR NOWRAP class='nativeToggleBar'>"); hPrintf("<TH NOWRAP align='left' colspan=3>"); hPrintf("<table style='width:100%%;'><tr class='noData'><td style='text-align:left;'>"); hPrintf("\n<A NAME='%sGroup'></A>",group->name); hPrintf("<input type=hidden name='%s' id='%s' value=%d>", collapseGroupVar(group->name),collapseGroupVar(group->name), (isOpen?0:1)); char idText[256]; safef(idText, sizeof idText, "%s_button", group->name); hPrintf("<IMG class='toggleButton' " "id='%s' src='%s' alt='%s' title='%s this group'> ", idText, indicatorImg, indicator,isOpen?"Collapse":"Expand"); // TODO XSS filter group->name jsOnEventByIdF("click", idText, "return vis.toggleForGroup(this,'%s');", group->name); - hPrintf("<B> %s</B> ", group->label); + // a hub group's label is built from the hub's shortLabel and its groups.txt label + hPrintf("<B> %s</B> ", htmlEncode(group->label)); hPrintf(" "); hPrintf("</td><td style='text-align:right;'>\n"); safef(idText, sizeof idText, "%s_hideAllBut", group->name); hPrintf("<INPUT TYPE=SUBMIT NAME=\"%s\" id='%s' VALUE=\"%s\" " "title='Hide all tracks in this group'>", configHideAll, idText, "Hide all"); // TODO XSS filter configGroupTarget char jsText[256]; // used several times safef(jsText, sizeof jsText, "document.mainForm.%s.value='%s'; %s", configGroupTarget, group->name, jsSetVerticalPosition("mainForm")); jsOnEventById("click", idText, jsText); hPrintf(" "); safef(idText, sizeof idText, "%s_showAllBut", group->name); hPrintf("<INPUT TYPE=SUBMIT NAME=\"%s\" id='%s' VALUE=\"%s\" " @@ -461,36 +462,37 @@ for (tr = group->trackList; tr != NULL; tr = tr->next) { struct track *track = tr->track; struct trackDb *tdb = track->tdb; hPrintf("<TR %sid='%s-%d'>",(isOpen ? "" : "style='display: none;'"), group->name, rowCount++); hPrintf("<TD NOWRAP>"); if (tdbIsSuperTrackChild(tdb)) /* indent members of a supertrack */ hPrintf(" "); hPrintIcons(tdb); if (track->hasUi) + // the labels come from trackDb, which a track hub controls, escape them hPrintf("<A TITLE='%s%s...' HREF='%s?%s=%s&db=%s&g=%s&hgTracksConfigPage=configure'>", tdb->parent ? "Part of super track: " : "Configure ", - tdb->parent ? tdb->parent->shortLabel : tdb->shortLabel, + htmlEncode(tdb->parent ? tdb->parent->shortLabel : tdb->shortLabel), hTrackUiForTrack(tdb->track), cartSessionVarName(), cartSessionId(cart), database, track->track); - hPrintf(" %s", tdb->shortLabel); + hPrintf(" %s", htmlEncode(tdb->shortLabel)); if (track->hasUi) hPrintf("</A>"); hPrintf("</TD><TD NOWRAP>"); if (tdbIsSuperTrackChild(tdb)) /* indent members of a supertrack */ hPrintf(" "); /* If track is not on this chrom print an informational message for the user. */ if (tdbIsDownloadsOnly(tdb)) // No vis display for downloadsOnly hPrintf("<A TITLE='Downloadable files...' HREF='%s?%s=%s&g=%s'>Downloads</A>", hgFileUiName(),cartSessionVarName(), cartSessionId(cart), tdb->track); else if (hTrackOnChrom(track->tdb, chromName)) { if (tdbIsSuper(track->tdb)) @@ -499,31 +501,31 @@ superTrackDropDown(cart, track->tdb, 1); } else { /* check for option of limiting visibility to one mode */ hTvDropDownClassVisOnlyWithLabel(track->track, track->visibility, rTdbTreeCanPack(track->tdb), (track->visibility == tvHide) ? "hiddenText trackVis" : "normalText trackVis", trackDbSetting(track->tdb, "onlyVisibility"), tdb->shortLabel); } } else hPrintf("[No data-%s]", chromName); hPrintf("</TD><TD NOWRAP>"); - hPrintf("%s", tdb->longLabel); + hPrintf("%s", htmlEncode(tdb->longLabel)); hPrintf("</TD></TR>\n"); } hPrintf("<tr class='noData'><td colspan=3>"); cgiDown(0.9); hPrintf("</td></tr>\n"); } hashFree(&superHash); hPrintf("</TABLE>\n"); jsInline("$(document).ready( cfgPageAddListeners )"); } static int addDownloadOnlyTracks(char *db,struct group **pGroupList,struct track **pTrackList) // Download only tracks are not normaly incorporated into the grou and track lists {