9ad04e0a0b06ec3c4f09ef1b6c3ce6be79b61c68 braney Sun Aug 16 11:56:56 2026 -0700 cart: validate file names read back out of the cart Several cart variables hold the name of a file the server created for a user. Route them through one shared check, isServerUserFilePath(), which accepts the trash directory, the session-data directories and myVariantsDataDir, and apply it both where values enter the cart and where the file names are used. A few of these variables may instead hold a remote URL. Those get their own list and isServerUserFileOrUrl(), because the code that reads them chooses between a fetch and a local open by looking for a protocol. Consolidates two hand-rolled copies of the same test in blatShare.c and customFactory.c, and drops the weaker private copy in sessionData.c. Adds hg/utils/cartFileVarCatalog, a registry that scans the tree for a cart value reaching a file call and reconciles what it finds against the lists in cart.c, so a new one of these cannot be added without somebody noticing. Its --reconcile is quiet enough for the nightly cron the other catalogs use, and it is what turned up seven of the names now on those lists. refs #37623 diff --git src/hg/hgTables/identifiers.c src/hg/hgTables/identifiers.c index 21b58c99408..4603e0a2ab7 100644 --- src/hg/hgTables/identifiers.c +++ src/hg/hgTables/identifiers.c @@ -532,30 +532,34 @@ { cartRemove(cart, hgtaIdentifierFile); } mainPageAfterOpen(conn); htmlClose(); } char *identifierFileName() /* File name identifiers are in, or NULL if not for curTable or no such file. */ { char *fileName = cartOptionalString(cart, hgtaIdentifierFile); if (fileName == NULL) return NULL; if (! forCurTable()) return NULL; +if (!isServerUserFilePath(fileName)) + // Not a file we made, so don't read it. Leave the cart alone: a cartRemove() here would + // throw away a list the user can still fix by pasting it again. + return NULL; if (fileExists(fileName)) return fileName; else { cartRemove(cart, hgtaIdentifierFile); return NULL; } } struct hash *identifierHash(char *db, char *table) /* Return hash full of identifiers from the given table (or NULL). */ { char dbDotTable[2048]; if (sameString(table, WIKI_TRACK_TABLE)) safecpy(dbDotTable, sizeof(dbDotTable), table);