fa416c484061b1e44519962435588916dc14a1f7
markd
  Wed Dec 9 22:04:07 2020 -0800
added isSafeRelativePath and removed way too low-level verbose logging

diff --git src/lib/filePath.c src/lib/filePath.c
index 7da8293..30a0d0d 100644
--- src/lib/filePath.c
+++ src/lib/filePath.c
@@ -109,59 +109,57 @@
     memcpy(result, baseDir, baseSize);
     result[baseSize] = '/';
     strcpy(result + baseSize + 1, rel);
     }
 else
     result = cloneString(rel);
 return result;
 }
 
 char *mustExpandRelativePath(char *dir, char* relPath)
 /* Given a dir and relative path, expand path.
  * Handy for processing symlinks. errAbort if expand fails.
  * Result should be freeMem'd.*/
 {
 char *path = expandRelativePath(dir, relPath);
-verbose(3, "dir=%s\nrelPath=%s\npath=%s\n", dir, relPath, path);
 if (!path)
     errAbort("Too many .. in path %s to make relative to submitDir %s\n", relPath, dir);
 return path;
 }
 
 char *pathRelativeToFile(char *baseFile, char *relPath)
 /* Given a base file name and a path relative to that, return
  * relative path interpreted as if it were seen from the
  * same directory holding the baseFile.  
  *   An example of using this would be in processing include
  * files.  In this case the baseFile would be the current
  * source file, and the relPath would be from the include
  * statement.  The returned result could then be used to
  * open the include file. */
 {
 char dir[PATH_LEN];
 splitPath(baseFile, dir, NULL, NULL);
 int dirLen = strlen(dir);
 if (dirLen > 0 && dir[dirLen-1] == '/')
      dir[dirLen-1] = 0;
 return expandRelativePath(dir, relPath);
 }
 
 char *mustPathRelativeToFile(char *baseFile, char *relPath)
 /* Make Path Relative To File or Abort. */
 {
 char *path = pathRelativeToFile(baseFile, relPath);
-verbose(3, "baseFile=%s\nrelPath=%s\npath=%s\n", baseFile, relPath, path);
 if (!path)
     errAbort("Too many .. in symlink path %s to make relative to %s\n", relPath, baseFile);
 return path;
 }
 
 char *makeRelativePath(char *from, char *to)
 /* Calculate a relative path from one absolute directory/file to another.
  * Assumptions: both from and to are canonicalized absolute paths beginning
  * at "/" or "//".  Filenames are okay, but all directory names must end with
  * a "/" to distinguish them from files.
  * e.g., /test/dir/ is a directory, but /test/dir is a file.
  */
 {
 int i, j, toCount, fromCount;
 char fromDir[PATH_LEN];
@@ -201,15 +199,39 @@
 for (j=i; j < fromCount-1; j++)
     {
     safecat(relPath, sizeof relPath, "../");
     }
 for (j=i; j < toCount-1; j++)
     {
     safecat(relPath, sizeof relPath, toDirList[j]);
     safecat(relPath, sizeof relPath, "/");
     }
 
 safecat(relPath, sizeof relPath, toFile);
 safecat(relPath, sizeof relPath, toExt);
 
 return cloneString(relPath);
 }
+
+boolean isSafeRelativePath(char *path)
+/* check that path is relative and contains no ".." elements */
+{
+if (startsWith("/", path))
+    return FALSE;
+char tmpPath[PATH_LEN];
+safecpy(tmpPath, sizeof(tmpPath), path);
+
+char *p = tmpPath;
+while (TRUE)
+    {
+    char *end = strchr(p, '/');
+    if (end != NULL)
+        *end = '\0';
+    if (sameString(p, ".."))
+        return FALSE;
+    if (end == NULL)
+        break;
+    else
+        p = end++;
+    }
+return TRUE;
+}