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/userRegions.c src/hg/hgTables/userRegions.c
index 74480fedf03..bd72b6ae8b1 100644
--- src/hg/hgTables/userRegions.c
+++ src/hg/hgTables/userRegions.c
@@ -160,30 +160,35 @@
     mainPageAfterOpen(conn);
 else
     doSetUserRegionsAfterOpen(conn);
 htmlClose();
 }
 
 char *userRegionsFileName()
 /* File name defined regions are in, or NULL if no such file. */
 {
 char *fileName = cartOptionalString(cart, hgtaUserRegionsFile);
 char *db = cartOptionalString(cart, hgtaUserRegionsDb);
 if (db && !sameString(database, db))
     return NULL;
 if (fileName == NULL)
     return NULL;
+if (!isServerUserFilePath(fileName))
+    // Not a file we made, so don't read it and don't let the caller delete it.  Leave the
+    // cart alone as well -- cartRemoveUserRegions() here would throw away a region list
+    // that the user can still fix by re-entering it.
+    return NULL;
 if (fileExists(fileName))
     return fileName;
 else
     {
     cartRemoveUserRegions();
     return NULL;
     }
 }
 
 struct region *getUserRegions(char *fileName)
 /* Get user defined regions from fileName. */
 {
 struct region *list = NULL, *region;
 struct lineFile *lf;
 char *words[4];