e6b0dc7877ae4b24f56682885e03263fd2da3582 braney Tue Aug 18 11:37:04 2026 -0700 lib, hgc: encode barChart, BAM and VCF detail text consistently, refs #38123 diff --git src/hg/lib/barChartUi.c src/hg/lib/barChartUi.c index 3bcbecf4071..70410a14e4c 100644 --- src/hg/lib/barChartUi.c +++ src/hg/lib/barChartUi.c @@ -1,90 +1,93 @@ /* Bar chart track controls */ /* Copyright (C) 2015 The Regents of the University of California * See kent/LICENSE or http://genome.ucsc.edu/license/ for licensing information. */ #include "cheapcgi.h" +#include "htmshell.h" #include "cart.h" #include "net.h" #include "errCatch.h" #include "web.h" #include "hui.h" #include "trackDb.h" #include "jsHelper.h" #include "hCommon.h" #include "rainbow.h" #include "htmlColor.h" #include "barChartCategory.h" #include "barChartUi.h" #include "facetedTable.h" #include "tablesTables.h" /* Restrict features on right-click (popup) version */ static boolean isPopup = FALSE; /* Convenience functions for category filter controls */ char *makeCategoryLabel(struct barChartCategory *categ) /* Display category color and label */ { -char buf[256]; -safef(buf, sizeof(buf), "" +// the label comes from the barChartBars setting, which a track hub controls, escape it. +// A dyString rather than a fixed buffer, since escaping can grow a long label past 256 bytes. +struct dyString *dy = dyStringNew(256); +dyStringPrintf(dy, "" " %s", - categ->color, categ->label); -return(cloneString(buf)); + categ->color, htmlEncode(categ->label)); +return(dyStringCannibalize(&dy)); } struct categorySelect { struct categorySelect *next; char *name; char *label; boolean checked; }; static void makeGroupCheckboxes(char *name, char *title, struct categorySelect *selects) { #define TABLE_COLUMNS 1 if (title != NULL) - printf("%s\n", title); + printf("%s\n", htmlEncode(title)); int count = slCount(selects); struct categorySelect **categArray; AllocArray(categArray, count); int i=0; struct categorySelect *sel; for (i=0, sel = selects; sel != NULL; sel = sel->next, i++) categArray[i] = sel; int col=0; int row=0; int tableColumns=1; for (i=0; i=count) { printf(""); row++; col = 0; } j = row + col*(count/tableColumns+1); if (!isPopup) { printf("" "%s\n", - name, categArray[j]->name, categArray[j]->checked ? "checked" : "", - categArray[j]->label); + name, htmlEncode(categArray[j]->name), categArray[j]->checked ? "checked" : "", + categArray[j]->label); // label is escaped html already, from makeCategoryLabel } col++; } if ((i % tableColumns) != 0) while ((i++ % tableColumns) != 0) printf(""); printf("\n"); } static void makeCategoryCheckboxes(char *name, struct barChartCategory *categs, struct slName *checked) { puts("\n"); @@ -167,31 +170,32 @@ } void barChartUiViewLimits(struct cart *cart, char *track, struct trackDb *tdb) /* Set viewing limits if log transform not checked */ /* NOTE: this code from gtexUi.c. Consider sharing. */ { char buf[512]; boolean isLogTransform = barChartIsLogTransformed(cart, track, tdb); safef(buf, sizeof buf, "%sViewLimitsMaxLabel %s", track, isLogTransform ? "disabled" : ""); printf("View limits maximum:\n", buf); double viewMax = barChartCurViewMax(cart, track, tdb); char cartVar[1024]; safef(cartVar, sizeof(cartVar), "%s.%s", track, BAR_CHART_MAX_VIEW_LIMIT); cgiMakeDoubleVarWithExtra(cartVar, viewMax, 4, isLogTransform ? "disabled" : ""); char *unit = trackDbSettingClosestToHomeOrDefault(tdb, BAR_CHART_UNIT, ""); -printf(" %s (range 0-%d)\n", buf, unit, +// barChartUnit comes from trackDb, which a track hub controls, escape it +printf(" %s (range 0-%d)\n", buf, htmlEncode(unit), round(barChartUiMaxMedianScore(tdb))); } // TODO: libify static boolean isUrl(char *url) { return startsWith("http://", url) || startsWith("https://", url) || startsWith("ftp://", url); } static void getCategsFromSettings(char *track, char *labelSetting, char *colorSetting, struct slName **retLabels, struct slName **colors) /* Get category labels and optionally colors, from track settings */ { @@ -400,31 +404,31 @@ puts("
"); barChartUiLogTransform(cart, track, tdb); /* Viewing limits max. This control is disabled if log transform is selected */ // construct class so JS can toggle puts("  "); barChartUiViewLimits(cart, track, tdb); puts("
"); /* Category filter */ printf("
"); char *categoryLabel = trackDbSettingClosestToHomeOrDefault(tdb, BAR_CHART_CATEGORY_LABEL, BAR_CHART_CATEGORY_LABEL_DEFAULT); char *db = cartString(cart, "db"); struct barChartCategory *categs = barChartUiGetCategories(db, tdb, NULL); -printf("
%s:\n", categoryLabel); +printf("
%s:\n", htmlEncode(categoryLabel)); // barChartLabel is hub supplied char cartVar[1024]; safef(cartVar, sizeof(cartVar), "%s.%s", track, BAR_CHART_CATEGORY_SELECT); if (isPopup) { printf("", hTrackUiForTrack(track), database, track); } else { jsMakeCheckboxGroupSetClearButton(cartVar, TRUE); puts(" "); jsMakeCheckboxGroupSetClearButton(cartVar, FALSE); } printf("
"); struct slName *selectedValues = NULL; @@ -444,31 +448,31 @@ } void barChartFacetedUi(char *database, struct cart *cart, struct trackDb *tdb, char *track, char *title, boolean boxed) /* Bar chart track type that has an associated facets tables */ { puts("
"); barChartUiLogTransform(cart, track, tdb); puts("  "); barChartUiViewLimits(cart, track, tdb); if (isPopup) { char *categoryLabel = trackDbSettingClosestToHomeOrDefault(tdb, BAR_CHART_CATEGORY_LABEL, BAR_CHART_CATEGORY_LABEL_DEFAULT); - printf("
%s:\n", categoryLabel); + printf("
%s:\n", htmlEncode(categoryLabel)); // barChartLabel is hub supplied printf("", hTrackUiForTrack(track), database, track); } else { char *facets = trackDbSetting(tdb, "barChartFacets"); char *statsFile = hReplaceGbdb(trackDbRequiredSetting(tdb, "barChartStatsUrl")); /* Write html to make white background */ hInsideStyleToWhite(); /* Set up url that has enough context to get back to us. */ struct dyString *returnUrl = dyStringNew(0); dyStringPrintf(returnUrl, "../cgi-bin/hgTrackUi?db=%s&g=%s", database, track); dyStringPrintf(returnUrl, "&%s", cartSidUrlString(cart));