ca23d9f5054fc863beb18d7ef4919b550b2f8d9c chmalee Mon Jun 1 10:45:37 2026 -0700 Allow dot in genome names in hubspace uploads, refs #37665 diff --git src/hg/hgHubConnect/hooks/pre-finish.c src/hg/hgHubConnect/hooks/pre-finish.c index 1a5ade8b314..ca5ba1323a8 100644 --- src/hg/hgHubConnect/hooks/pre-finish.c +++ src/hg/hgHubConnect/hooks/pre-finish.c @@ -93,36 +93,38 @@ } fprintf(stderr, "userName='%s'\n", userName); // NOTE: All Upload.MetaData values are strings // 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 *rawFileName = jsonQueryString(req, "", "Event.Upload.MetaData.fileName", NULL); if (!rawFileName) rawFileName = jsonQueryString(req, "", "Event.Upload.MetaData.filename", NULL); if (!rawFileName) rawFileName = jsonQueryString(req, "", "Event.Upload.MetaData.name", NULL); fileName = rawFileName ? cgiEncodeFull(rawFileName) : NULL; fileSize = jsonQueryInt(req, "", "Event.Upload.Size", 0, NULL); fileType = jsonQueryString(req, "", "Event.Upload.MetaData.fileType", NULL); db = jsonQueryString(req, "", "Event.Upload.MetaData.genome", NULL); // Blocks newline injection into the synthesized hub.txt. + // The allowed character class must match sanitizeGenomeName() in + // src/hg/js/hgMyData.js. if (db && db[0]) { char *p; for (p = db; *p; p++) - if (!(isalnum((unsigned char)*p) || *p == '_' || *p == '-')) - errAbort("Invalid genome name '%s': only letters, digits, '_' and '-' are allowed", db); + if (!(isalnum((unsigned char)*p) || *p == '_' || *p == '-' || *p == '.')) + errAbort("Invalid genome name '%s': only letters, digits, '.', '_' and '-' are allowed", db); } reqLm = jsonQueryString(req, "", "Event.Upload.MetaData.lastModified", NULL); if (reqLm) lastModified = sqlLongLong(reqLm) / 1000; // yes Javascript dates are in millis else lastModified = time(NULL); // fallback to current time if not provided parentDir = jsonQueryString(req, "", "Event.Upload.MetaData.parentDir", NULL); fprintf(stderr, "parentDir = '%s'\n", parentDir ? parentDir : "(null)"); // strip out plain leading '.' and '/' components // middle '.' components are dealt with later if (parentDir && (startsWith("./", parentDir) || startsWith("/", parentDir))) parentDir = skipBeyondDelimit(parentDir, '/'); tusFile = jsonQueryString(req, "", "Event.Upload.Storage.Path", NULL); tusInfo = jsonQueryString(req, "", "Event.Upload.Storage.InfoPath", NULL); if (fileName == NULL)