2cdae04ddc1e46cdfc2e5e8cf479cbbbb616ad10 chmalee Tue Sep 22 15:55:10 2026 -0700 htmlSanitize tooltips before printing them into the page, refs #38226 diff --git src/hg/hgTracks/simpleTracks.c src/hg/hgTracks/simpleTracks.c index c82fcfef41b..9e026bdb55b 100644 --- src/hg/hgTracks/simpleTracks.c +++ src/hg/hgTracks/simpleTracks.c @@ -29,30 +29,31 @@ #include "grp.h" #include "chromColors.h" #include "hgTracks.h" #include "subText.h" #include "cds.h" #include "mafTrack.h" #include "wigCommon.h" #include "hui.h" #include "imageV2.h" #include "bigBed.h" #include "htmshell.h" #include "kxTok.h" #include "hash.h" #include "decorator.h" #include "decoratorUi.h" +#include "htmlSanitize.h" #ifndef GBROWSE #include "encode.h" #include "expRatioTracks.h" #include "hapmapTrack.h" #include "retroGene.h" #include "switchGear.h" #include "variation.h" #include "wiki.h" #include "wormdna.h" #include "aliType.h" #include "agpGap.h" #include "cgh.h" #include "bactigPos.h" #include "genePred.h" @@ -1125,33 +1126,37 @@ return TRUE; if (isCenterLabelConditionallySeen(track)) return TRUE; return FALSE; } void mapStatusMessage(char *format, ...) /* Write out stuff that will cause a status message to * appear when the mouse is over this box. */ { va_list args; va_start(args, format); struct dyString *dy = dyStringNew(0); dyStringVaPrintf(dy, format, args); va_end(args); +char *sanitized = htmlSanitize(dy->string); char *encoded = attributeEncode(dy->string); -hPrintf(" TITLE=\"%s\" data-tooltip=\"%s\"", encoded, encoded); +char *encSanitized = attributeEncode(sanitized); +hPrintf(" TITLE=\"%s\" data-tooltip=\"%s\"", encoded, encSanitized); freeMem(encoded); +freeMem(sanitized); +freeMem(encSanitized); dyStringFree(&dy); } void mapBoxReinvoke(struct hvGfx *hvg, int x, int y, int width, int height, struct track *track, boolean toggle, char *chrom, long start, long end, char *message, char *extra) /* Print out image map rectangle that would invoke this program again. * If track is non-NULL then put that track's id in the map item. * if toggle is true, then toggle track between full and dense. * If chrom is non-null then jump to chrom:start-end. * Add extra string to the URL if it's not NULL */ { struct dyString *ui = uiStateUrlPart(toggle ? track : NULL); struct dyString *id = dyStringNew(0); if(track) @@ -1320,31 +1325,37 @@ if (withHgsid) hPrintf("&%s", cartSidUrlString(cart)); } else { hPrintf("HREF=\"%s&o=%d&t=%d&g=%s&i=%s&c=%s&l=%d&r=%d&db=%s&pix=%d", hgcNameAndSettings(), start, end, encodedTrack, encodedItem, chromName, winStart, winEnd, database, tl.picWidth); } if (extra != NULL) hPrintf("&%s", extra); hPrintf("\" "); if (statusLine != NULL) { - hPrintf(" TITLE='%s' data-tooltip='%s' ", item, statusLine); + char *encItem = attributeEncode(item); + char *sanitized = htmlSanitize(statusLine); + char *encoded = attributeEncode(sanitized); + hPrintf(" TITLE='%s' data-tooltip='%s' ", encItem, encoded); + freeMem(sanitized); + freeMem(encoded); + freeMem(encItem); } hPrintf("%s>\n", dyStringContents(id)); } freeMem(encodedItem); freeMem(encodedTrack); } dyStringFree(&id); } void mapBoxHc(struct hvGfx *hvg, int start, int end, int x, int y, int width, int height, char *track, char *item, char *statusLine) /* Print out image map rectangle that would invoke the hgc (human genome click) * program. */ { mapBoxHgcOrHgGene(hvg, start, end, x, y, width, height, track, item, statusLine, NULL, FALSE, NULL);