a8349f676d1dad81ee90c58605ecbd69453666b1 chmalee Mon Jul 27 15:14:21 2026 -0700 Fixed a bug in hubspace uploads where the unencoded parentDir was used by tusd for the upload location while the encoded path was set in the hubSpace table. Also validate and trim parentDir in the pre-create hook and in hgMyData.js, refs #34962 Co-Authored-By: Claude Opus 5 (1M context) diff --git src/hg/hgHubConnect/hooks/pre-create.c src/hg/hgHubConnect/hooks/pre-create.c index 78303754b89..d731b6d29ee 100644 --- src/hg/hgHubConnect/hooks/pre-create.c +++ src/hg/hgHubConnect/hooks/pre-create.c @@ -89,30 +89,41 @@ } fprintf(stderr, "userName='%s'\n'", userName); long reqFileSize = jsonQueryInt(req, "", "Event.Upload.Size", 0, NULL); // Check multiple possible metadata keys for filename (Uppy sends 'filename' and 'name' by default, // our JS code also sets 'fileName' - try all to handle resumed uploads with old metadata) char *reqFileName = jsonQueryString(req, "", "Event.Upload.MetaData.fileName", NULL); if (!reqFileName) reqFileName = jsonQueryString(req, "", "Event.Upload.MetaData.filename", NULL); if (!reqFileName) reqFileName = jsonQueryString(req, "", "Event.Upload.MetaData.name", NULL); if (!reqFileName) { errAbort("No filename found in upload metadata (checked fileName, filename, and name)"); } char *reqParentDir = jsonQueryString(req, "", "Event.Upload.MetaData.parentDir", NULL); + // Trim first, a hub name with a trailing space is impossible to spot in an error + // message, then check what is left. The browser does this too, but hubtools and + // any other tus client post here directly + reqParentDir = normalizeParentDir(reqParentDir); + if (reqParentDir && isEmpty(reqParentDir)) + errAbort("Hub name for file '%s' is only whitespace, please give the hub a name", + reqFileName); + if (!isValidParentDir(reqParentDir)) + errAbort("Hub name '%s' for file '%s' can only contain letters, numbers, periods " + "and underscores, in '/' separated components. Please rename the hub.", + reqParentDir, reqFileName); boolean isHubToolsUpload = FALSE; char *hubtoolsStr = jsonQueryString(req, "", "Event.Upload.MetaData.hubtools", NULL); if (hubtoolsStr) isHubToolsUpload = sameString(hubtoolsStr, "TRUE") || sameString(hubtoolsStr, "true"); // Check for allowOverwrite metadata from JavaScript (for hub.txt overwrites) char *allowOverwriteStr = jsonQueryString(req, "", "Event.Upload.MetaData.allowOverwrite", NULL); boolean allowOverwrite = (allowOverwriteStr && (sameString(allowOverwriteStr, "TRUE") || sameString(allowOverwriteStr, "true"))); boolean forceOverwrite = isHubToolsUpload || allowOverwrite; long currQuota = checkUserQuota(userName); long newQuota = currQuota + reqFileSize; long maxQuota = getMaxUserQuota(userName); if (newQuota > maxQuota) { errAbort("File '%s' is too large, need %s free space but current used space is %s out of %s", reqFileName, prettyFileSize(reqFileSize), prettyFileSize(currQuota), prettyFileSize(maxQuota)); }