3d91dda86ff75aa59b6095ae6bcab96d72f99656
jcasper
  Wed Mar 18 22:45:15 2026 -0700
eatExcessDotDotInPath does unexpected things with inputs like ../../ and
/a/./.. .  Adding an alternate version until we can assess the impacts of changing.  refs #36320, #37263

diff --git src/inc/portable.h src/inc/portable.h
index 0015e96e433..661bc845a40 100644
--- src/inc/portable.h
+++ src/inc/portable.h
@@ -60,30 +60,39 @@
 boolean maybeSetCurrentDir(char *newDir);
 /* Change directory, return FALSE (and set errno) if fail. */
 
 boolean makeDir(char *dirName);
 /* Make dir.  Returns TRUE on success.  Returns FALSE
  * if failed because directory exists.  Prints error
  * message and aborts on other error. */
 
 void makeDirsOnPath(char *pathName);
 /* Create directory specified by pathName.  If pathName contains
  * slashes, create directory at each level of path if it doesn't
  * already exist.  Abort with error message if there's a problem.
  * (It's not considered a problem for the directory to already
  * exist. ) */
 
+void eatSlashSlashInPath(char *path);
+/* Convert multiple // to single / in path.  Warning: do not use on URLs
+ * as it would eat the :// in the protocol. */
+
+void eatExcessDotsInPath(char *path);
+/* Remove . and .. components from path in place, e.g.
+ *   'this/long/../dir/file' becomes 'this/dir/file'
+ *   'a/./b' becomes 'a/b' */
+
 char *simplifyPathToDir(char *path);
 /* Return path with ~ (for home) and .. taken out.   freeMem result when done. */
 
 long clock1000();
 /* 1000 hz clock */
 
 void sleep1000(int milli);
 /* Sleep for given number of milliseconds. */
 
 long clock1();
 /* A 1 hz clock. */
 
 char *getTempDir(void);
 /* get temporary directory to use for programs.  This first checks TMPDIR environment
  * variable, then /data/tmp, /scratch/tmp, /var/tmp, /tmp.  Return is static and