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/lib/sessionData.c src/hg/lib/sessionData.c index b0ebd403aa4..97d1895b279 100644 --- src/hg/lib/sessionData.c +++ src/hg/lib/sessionData.c @@ -3,36 +3,30 @@ * Copyright (C) 2019-2024 The Regents of the University of California * See kent/LICENSE or http://genome.ucsc.edu/license/ for licensing information. */ #include "common.h" #include "cart.h" #include "cheapcgi.h" #include "customComposite.h" #include "customTrack.h" #include "hdb.h" #include "hgConfig.h" #include "md5.h" #include "trashDir.h" #include "sessionData.h" #include "quickLift.h" -INLINE boolean isTrashPath(char *path) -/* Return TRUE if path starts with trashDir. */ -{ -return startsWith(trashDir(), path); -} - static char *sessionDataPathFromTrash(char *trashPath, char *sessionDir) /* Make a new path from a trash path -- replace "../trash" with safe location. */ { if (!isTrashPath(trashPath)) errAbort("sessionDataPathFromTrash: input is non-trash path '%s'", trashPath); return replaceChars(trashPath, trashDir(), sessionDir); } static char *maybeReadlink(char *path) /* If path is a symbolic link, then alloc & return the link target, otherwise NULL. */ { char *linkTarget = NULL; struct stat stat; if (lstat(path, &stat) != 0) // expired file