ce2f414131cc49f0cdd0799a8a0d6a3f94f75e9a chmalee Thu Sep 17 11:57:42 2026 -0700 hubspace: double-encode the user name when building hub URLs Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> diff --git src/hg/lib/userdata.c src/hg/lib/userdata.c index 4617b662ff6..2256f84954f 100644 --- src/hg/lib/userdata.c +++ src/hg/lib/userdata.c @@ -181,32 +181,37 @@ { if (!hubSpaceUrl) hubSpaceUrl = cfgOption("hubSpaceUrl"); return hubSpaceUrl; } char *webDataDir(char *userName) /* Return a web accesible path to the userDataDir, this is different from the full path tusd uses */ { char *retUrl = NULL; if (userName) { char *encUserName = cgiEncode(userName); char *userPrefix = md5HexForString(encUserName); userPrefix[2] = '\0'; + // the directory on disk is named encUserName, so a user name like "abc-def" is + // stored as the literal characters "abc%2Ddef". Encode a second time so apache + // looks for that literal '%': the URL component must be "abc%252Ddef". + // writeHubStanzasForFile does the same thing to a file name for bigDataUrl struct dyString *userDirDy = dyStringNew(0); - dyStringPrintf(userDirDy, "%s/%s/%s/", getHubSpaceUrl(), userPrefix, encUserName); + dyStringPrintf(userDirDy, "%s/%s/%s/", getHubSpaceUrl(), userPrefix, + cgiEncodeFull(encUserName)); retUrl = dyStringCannibalize(&userDirDy); } return retUrl; } char *urlForFile(char *userName, char *filePath) /* Return a web accessible URL to filePath */ { char *webDataUrl = webDataDir(userName); if (webDataUrl) { return catTwoStrings(webDataUrl, filePath); } return NULL; }