diff --git a/src/combine_path.h b/src/combine_path.h index 988f55eca49a1ef17249a1878518d1f20723138e..909dfef27a945330e269be1b3fef6f8ae14cc8a4 100644 --- a/src/combine_path.h +++ b/src/combine_path.h @@ -210,16 +210,42 @@ static void APPEND_PATH(struct string_builder *s, } else if (IS_SEP(index_shared_string(s->s, 0))) { tmp++; } - + if (tmp < abs) tmp = abs; - else - if ((tmp+1 < s->s->len) && - (index_shared_string(s->s,tmp)=='.') && - (index_shared_string(s->s,tmp+1)=='.') && - ( (tmp+2 == s->s->len) || - IS_SEP(index_shared_string(s->s,tmp+2)))) - break; + else { + if (index_shared_string(s->s,tmp)=='.') { + if ((tmp+1 < s->s->len) && + (index_shared_string(s->s,tmp+1)=='.') && + ( (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; + } + } + } from+=(c3? 3:2); s->s->len=tmp; diff --git a/src/testsuite.in b/src/testsuite.in index 91cacc8849e6bf8061ae22c23b3408dbdc06124c..8e87b0e01f834b68d4fa85edab8b2df2d23507fe 100644 --- a/src/testsuite.in +++ b/src/testsuite.in @@ -10750,6 +10750,9 @@ test_eq([[combine_path(".", "bar")]],"bar") test_eq([[combine_path("./", "bar")]],"bar") test_eq([[combine_path(".", "../bar")]],"../bar") test_eq([[combine_path("./", "../bar")]],"../bar") +test_eq([[combine_path("./bar")]],"bar") +test_eq([[combine_path("./bar")]],"bar") +test_eq([[combine_path("./../bar")]],"../bar") // - combine_path_nt test_eq([[combine_path_nt("/","/fo\1111/bar/gazonk/../../")]],"/fo\1111/")