72a39a73f65feecd86b7e6cf20bdd346fcad4868
chmalee
  Thu Jan 23 13:09:33 2025 -0800
Fix bug in handling non alphanum characters in filenames in hubspace. I was mistakenly double encoding the filenames when creating trackDb stanzas. Also on client side, prevent users from even submitting files with weird characters to start with, refs #35064

diff --git src/hg/lib/userdata.c src/hg/lib/userdata.c
index 0bfbdf86897..6de5d1b893d 100644
--- src/hg/lib/userdata.c
+++ src/hg/lib/userdata.c
@@ -291,35 +291,39 @@
     "bigDataUrl %s\n"
     "type %s\n"
     "shortLabel %s\n"
     "longLabel %s\n"
     "\n",
     track, bigDataUrl, trackDbType, label, label);
 carefulClose(&f);
 }
 
 static char *writeHubStanzasForFile(struct hubSpace *rowForFile, char *userDataDir, char *parentDir)
 /* Create a hub.txt (if necessary) and add track stanzas for the file described by rowForFile.
  * Returns the path to the hub.txt */
 {
 char *hubFileName = NULL;
 char *hubDir = hubPathFromParentDir(rowForFile->parentDir, userDataDir);
-fprintf(stderr, "hubDir: %s\n", hubDir);
 hubFileName = writeHubText(hubDir, rowForFile->userName, rowForFile->db);
 
-char *encodedTrack = cgiEncodeFull(rowForFile->fileName);
-writeTrackStanza(hubFileName, encodedTrack, encodedTrack, rowForFile->fileType, encodedTrack, rowForFile->location);
+// NOTE: even though rowForFile->fileName was already cgiEncoded by the pre-finish hook,
+// we still must cgiEncode again to make the bigDataUrl setting work, as apache needs
+// to look for a literal '%' in a filename if there was a character encoded. For example,
+// if the filename from tus was &.bb, tus encodes this to "\u0026.bb", which we write to
+// disk as %5Cu0026.bb, and apache needs to find at:
+// https://url/hash/userName/%25Cu0026.bb in order to work in hgTracks
+writeTrackStanza(hubFileName, rowForFile->fileName, cgiEncodeFull(rowForFile->fileName), rowForFile->fileType, rowForFile->fileName, rowForFile->location);
 return hubFileName;
 }
 
 void createNewTempHubForUpload(char *requestId, struct hubSpace *rowForFile, char *userDataDir, char *parentDir)
 /* Creates a hub.txt for this upload, and updates the hubSpace table for the
  * hub.txt and any parentDirs we need to create. */
 {
 // first create the hub.txt if necessary and write the stanza for this track
 char *hubPath = writeHubStanzasForFile(rowForFile, userDataDir, parentDir);
 
 // update the mysql table with a record of the hub.txt:
 struct hubSpace *hubTextRow = NULL;
 AllocVar(hubTextRow);
 hubTextRow->userName = rowForFile->userName;
 hubTextRow->fileName = "hub.txt";