4a642d5f4c2a3102d5c2620af754d876146d7c24 max Sat Sep 26 21:53:49 2026 -0700 trackHub: restrict a hub genome's organism/description to a plain display-label character set diff --git src/hg/lib/hVarSubst.c src/hg/lib/hVarSubst.c index 39c95fdd367..c4cc5e51868 100644 --- src/hg/lib/hVarSubst.c +++ src/hg/lib/hVarSubst.c @@ -348,34 +348,35 @@ if (*(next+1) == '$') { // $$ is a literal $ dyStringAppendC(dest, '$'); start = next = next + 2; } else if (htmlVars != NULL) { // variable reference, or just a dollar sign in the text char *after = parseVarNameMaybe(next, varName, sizeof(varName)); if ((after != NULL) && isHtmlVar(tdb, varName, htmlVars, htmlVarCount)) { /* Escape the value before it goes into the page. A hub's description html was * sanitized once, when the hub was read (trackHub.c, htmlSanitize); this pass * runs at render time, long after, so anything it inserted raw would be markup - * that nothing had ever looked at. Two of the variables are exactly that: - * $organism and $date come straight out of a hub's genomes.txt with no - * validation. None of the variables in either list is meant to carry markup, - * so escaping them all costs nothing and leaves no gap to keep track of. */ + * that nothing had ever looked at. $organism and $date come straight out of a + * hub's genomes.txt, restricted at parse time (trackHub.c, + * checkHubDisplayText) to a safe display-label character set. None of the + * variables in either list is meant to carry markup, so escaping them all here + * too costs nothing. */ struct dyString *raw = dyStringNew(64); substVar(desc, tdb, database, varName, raw); char *escaped = htmlEncode(raw->string); dyStringAppend(dest, escaped); freeMem(escaped); dyStringFree(&raw); start = next = after; } else { dyStringAppendC(dest, '$'); start = next = next + 1; } } else