From 1871bafb1c78df6f1639eb1855af507094886502 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?=
 <grubba@grubba.org>
Date: Mon, 22 Oct 2018 16:38:41 +0200
Subject: [PATCH] combine_path: Fixed corner case (take 2).

The previous "fix" broke handling of paths starting with "./" in
cases other than "./../".

Fixes [PIKE-137] some more.
---
 src/combine_path.h | 49 +++++++++++++++++++++-------------------------
 1 file changed, 22 insertions(+), 27 deletions(-)

diff --git a/src/combine_path.h b/src/combine_path.h
index 909dfef27a..1b2884c7e2 100644
--- a/src/combine_path.h
+++ b/src/combine_path.h
@@ -180,9 +180,27 @@ static void APPEND_PATH(struct string_builder *s,
 	continue;
       }
 #else /* !AMIGAOS_COMBINE_PATH */
-      while(s->s->len && IS_SEP(LAST_PUSHED()))
-	s->s->len--;
-      PUSH('/');
+      do {
+	/* Remove sequences of ending slashes and single dots
+	 * from the result path.
+	 */
+	while(s->s->len && IS_SEP(LAST_PUSHED()))
+	  s->s->len--;
+	if (LAST_PUSHED() == '.') {
+	  if (s->s->len == 1) {
+	    /* Result path started with "./". */
+	    s->s->len = 0;
+	    break;
+	  } else if (IS_SEP(index_shared_string(s->s, s->s->len-2))) {
+	    /* Result path ended with "/./". */
+	    s->s->len -= 2;
+	    continue;
+	  }
+	}
+	/* Restore a single slash as directory separator. */
+	PUSH('/');
+	break;
+      } while (1);
       if(from<len && INDEX_PCHARP(path, from) == '.')
       {
 	int c3;
@@ -198,7 +216,7 @@ static void APPEND_PATH(struct string_builder *s,
 	{
 	  case '.':
 	    c3=INDEX_PCHARP(path, from+2);
-	    if(IS_SEP(c3) || !c3)
+	    if(s->s->len && (IS_SEP(c3) || !c3))
 	    {
 	      /* Handle "..". */
 	      int tmp=s->s->len-1;
@@ -220,29 +238,6 @@ static void APPEND_PATH(struct string_builder *s,
 		      ( (tmp+2 == s->s->len) ||
 			IS_SEP(index_shared_string(s->s,tmp+2)))) {
 		    break;
-		  } else if ((tmp+1 == s->s->len) ||
-			     IS_SEP(index_shared_string(s->s,tmp+1))) {
-		    /* Previous is "." or "./".
-		     * Replace it with "..".
-		     */
-		    if (tmp+1 != s->s->len) {
-		      /* Remove the separator. */
-		      s->s->len--;
-		    }
-		    PUSH('.');
-		    from += 2;
-		    if (c3) {
-		      PUSH('/');
-		      from++;
-		    }
-#if COMBINE_PATH_DEBUG > 0
-		    /* s->s->str[s->s->len]=0; */
-		    fprintf(stderr,"combine_path(2),   TO: %s[%d]\n",
-			    s->s->str, s->s->len);
-		    fprintf(stderr,"combine_path(2), FROM (%d): %s[%d]\n",
-			    from, path.ptr+from, len-from);
-#endif
-		    continue;
 		  }
 		}
 	      }
-- 
GitLab