f247b79b61ca172b3146284594b97c848db4c8bf braney Wed Sep 2 11:20:43 2026 -0700 hgSession, hgGenome: tighten handling of an uploaded file's name, refs #38172 Both CGIs print the name that arrives with an upload straight into the page. hgSession prints it in four of its load messages, so encode it once where it is read; the sibling URL message three lines above already did the same for the URL. hgGenome puts it in a quoted attribute, which wants attributeEncode. Raised in the v503 Preview II code review. diff --git src/hg/hgSession/hgSession.c src/hg/hgSession/hgSession.c index 11a3538c8d8..31227944837 100644 --- src/hg/hgSession/hgSession.c +++ src/hg/hgSession/hgSession.c @@ -1693,30 +1693,34 @@ "previously saved browser settings, and then click " "\"submit\" again."); if (!startsWith("http://",url) && !startsWith("https://",url) && !startsWith("ftp://",url)) errAbort("Unsupported protocol for loading a file via URL. Please use http, https, or ftp"); lf = netLineFileOpen(url); dyStringPrintf(dyMessage, "Loaded settings from URL %s . %s %s", htmlEncode(url), getUrlLink(url), getUrlEmailLink(url)); } else { char *filePlainContents = cartOptionalString(cart, hgsLoadLocalFileName); char *fileBinaryCoords = cartOptionalString(cart, hgsLoadLocalFileName "__binary"); char *fileName = cartOptionalString(cart, hgsLoadLocalFileName "__filename"); + /* The name arrives with the upload and is printed in four of the messages below, + * so encode it once here rather than at each one. */ + if (isNotEmpty(fileName)) + fileName = htmlEncode(fileName); if (isNotEmpty(filePlainContents)) { char *settings = trimSpaces(filePlainContents); dyStringAppend(dyMessage, "Loaded settings from local file "); if (isNotEmpty(fileName)) dyStringPrintf(dyMessage, "%s ", fileName); dyStringPrintf(dyMessage, "(%lu bytes).", (unsigned long)strlen(settings)); lf = lineFileOnString("settingsFromFile", TRUE, cloneString(settings)); } else if (isNotEmpty(fileBinaryCoords)) { /* The cart holds the address and size of the uploaded bytes, but any * request can set that variable, so only use a block cheapcgi * handed out. */