139e158c2b2817ea64048290f046105d25f97198 braney Tue Aug 18 11:15:51 2026 -0700 hgHubConnect: encode hub label and contact fields consistently, refs #38123 diff --git src/hg/hgHubConnect/hgHubConnect.c src/hg/hgHubConnect/hgHubConnect.c index 65d37febc54..45270e54649 100644 --- src/hg/hgHubConnect/hgHubConnect.c +++ src/hg/hgHubConnect/hgHubConnect.c @@ -82,33 +82,34 @@ static void ourCellStart() { fputs("<TD>", stdout); // do not add a newline } static void ourCellEnd() { puts("</TD>"); } static void ourPrintCellLink(char *str, char *url) { ourCellStart(); -printf("<A class=\"cv\" HREF=\"%s\" TARGET=_BLANK>\n", url); +// every caller passes a hub label and a hub url, both text from a stranger, so escape +printf("<A class=\"cv\" HREF=\"%s\" TARGET=_BLANK>\n", htmlEncode(url)); if (str != NULL) - fputs(str, stdout); // do not add a newline -- was causing trailing blanks get copied in cut and paste + fputs(htmlEncode(str), stdout); // do not add a newline -- was causing trailing blanks get copied in cut and paste puts("</A>"); ourCellEnd(); } static void ourPrintCell(char *str) { ourCellStart(); if (str != NULL) fputs(str, stdout); // do not add a newline -- was causing trailing blanks get copied in cut and paste ourCellEnd(); } static char *removeLastComma(char *string) { if (string != NULL) @@ -363,31 +364,31 @@ safef(id, sizeof id, "hubClearButton%d", count); // give people a chance to clear the error printf("<input name=\"hubClearButton\" id='%s' " "class=\"hubButton\" type=\"button\" value=\"Retry Hub\">" , id); jsOnEventByIdF("click", id, "document.resetHubForm.elements['hubCheckUrl'].value='%s';" "document.resetHubForm.submit(); return true;", javaScriptLiteralEncode(hub->hubUrl)); ourCellEnd(); } else if (hub->trackHub != NULL) { if (hub->trackHub->descriptionUrl != NULL) ourPrintCellLink(hub->trackHub->longLabel, hub->trackHub->descriptionUrl); else - ourPrintCell(hub->trackHub->longLabel); + ourPrintCell(htmlEncode(hub->trackHub->longLabel)); // hub supplied } else ourPrintCell(""); if (hub->trackHub != NULL) printGenomes(hub->trackHub, count, !hubHasError); else ourPrintCell(""); puts("</tr>"); } printf("</tbody></TABLE>\n"); puts("</FORM>"); @@ -686,31 +687,31 @@ } ourCellEnd(); } else errAbort("cannot get id for hub with url %s\n", hubInfo->hubUrl); ourPrintCellLink(hubInfo->shortLabel, hubInfo->hubUrl); boolean hubHasNoError = isEmpty(hubInfo->errorMessage); if (hubHasNoError) { if (hubInfo->tableHasDescriptionField && !isEmpty(hubInfo->descriptionUrl)) ourPrintCellLink(hubInfo->longLabel, hubInfo->descriptionUrl); else - ourPrintCell(hubInfo->longLabel); + ourPrintCell(htmlEncode(hubInfo->longLabel)); // hub supplied } else { ourCellStart(); printf("<span class=\"hubError\">ERROR: %s </span>" "<a href=\"../goldenPath/help/hgTrackHubHelp.html#Debug\">Debug Help</a>", hubInfo->errorMessage); safef(jsId, sizeof jsId, "hubClearButton%d", count); printf( "<input name=\"hubClearButton\" id='%s' " "class=\"hubButton\" type=\"button\" value=\"Retry Hub\">" , jsId); jsOnEventByIdF("click", jsId, "document.resetHubForm.elements['hubCheckUrl'].value='%s';" "document.resetHubForm.submit();return true;", hubInfo->hubUrl); @@ -1432,52 +1433,54 @@ char *errorMessage; hubFindOrAddUrlInStatusTable(cart, hub->hubUrl, &errorMessage); // if there is an error message, we stay in hgHubConnect if (errorMessage != NULL) return 0; getDbAndGenome(cart, &database, &organism, oldVars); char headerText[1024]; safef(headerText, sizeof(headerText), "Hub Connect Successful"); cartWebStart(cart, NULL, "%s", headerText); struct trackHub *tHub = hub->trackHub; -hPrintf("<P><B>Connected Hub: </B>%s</P>", tHub->shortLabel); +// the labels, the email and the per genome organism and description all come out of the +// hub's own text files, so escape them before printing +hPrintf("<P><B>Connected Hub: </B>%s</P>", htmlEncode(tHub->shortLabel)); -hPrintf("<P><B>Hub Description:</B> %s</P>", tHub->longLabel); -hPrintf("<P><B>Contact email:</B> <A HREF=\"mailto:%s\">%s</A>.</B> Use this contact for all data questions.</P>", tHub->email, tHub->email); +hPrintf("<P><B>Hub Description:</B> %s</P>", htmlEncode(tHub->longLabel)); +hPrintf("<P><B>Contact email:</B> <A HREF=\"mailto:%s\">%s</A>.</B> Use this contact for all data questions.</P>", htmlEncode(tHub->email), htmlEncode(tHub->email)); struct trackHubGenome *genomeList = tHub->genomeList; hPrintf("<P><B>Assemblies:</B> Select an assembly below to start browsing the tracks of this hub:<P>"); hPrintf("<ul>"); for(; genomeList; genomeList = genomeList->next) { char *desc = genomeList->description; if (desc==NULL) desc = hFreezeFromDb(genomeList->name); char *org = trackHubSkipHubName( genomeList->organism ); if (org==NULL) org = trackHubSkipHubName(hOrganism(genomeList->name)); - hPrintf("<li>Open: <A href=\"../cgi-bin/hgTracks?db=%s&%s&position=lastDbPos\">%s: %s</A></li>",genomeList->name, - cartSidUrlString(cart), org, desc); + hPrintf("<li>Open: <A href=\"../cgi-bin/hgTracks?db=%s&%s&position=lastDbPos\">%s: %s</A></li>", + htmlEncode(genomeList->name), cartSidUrlString(cart), htmlEncode(org), htmlEncode(desc)); } hPrintf("</ul>"); hPrintf("<P><A href=\"./hgHubConnect#unlistedHubs\">Connect another hub</A> to add more tracks.</P>"); hPrintf("<P><I>Hubs are created and maintained by external sources. UCSC is not responsible for their content and status.</I></P>"); return 1; } static void doResetHub(struct cart *theCart) { char *url = cartOptionalString(cart, hgHubCheckUrl); if (url != NULL)