From 39548a7712879446115dcf7621d2aa05b1ccdab3 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Mon, 10 Oct 2022 20:35:23 -0500 Subject: [PATCH] Have tar handle / and .. at / as ./ and let -P retain .. --- tests/tar.test | 6 ++++++ toys/posix/tar.c | 24 ++++++++++++++---------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/tests/tar.test b/tests/tar.test index 5846ffbb..df63c2ff 100755 --- a/tests/tar.test +++ b/tests/tar.test @@ -324,6 +324,12 @@ testing "--xform" "$TAR one --xform=s@three/four/@zero@ | tar t | grep six" \ rm -rf one SKIP=0 +testing '-P' "$TAR -P --no-recursion -C / /// .. | SUM 3" \ + "a3e94211582da121845d823374d8f41ead62d7bd\n" "" "" + +testing 'without -P' "$TAR --no-recursion -C / /// .. | SUM 3" \ + "077d03243e247b074806904885e6da272fd5857a\n" "" "" + if false then # Sequencing issues that leak implementation details out the interface diff --git a/toys/posix/tar.c b/toys/posix/tar.c index 6930df8e..f75b33fd 100644 --- a/toys/posix/tar.c +++ b/toys/posix/tar.c @@ -239,18 +239,22 @@ static int add_to_tar(struct dirtree *node) if (S_ISDIR(st->st_mode) && name[i-1] != '/') strcat(name, "/"); // remove leading / and any .. entries from saved name - if (!FLAG(P)) while (*hname == '/') hname++; - for (lnk = hname;;) { - if (!(lnk = strstr(lnk, ".."))) break; - if (lnk == hname || lnk[-1] == '/') { - if (!lnk[2]) goto done; - if (lnk[2]=='/') { - lnk = hname = lnk+3; - continue; + if (!FLAG(P)) { + while (*hname == '/') hname++; + for (lnk = hname;;) { + if (!(lnk = strstr(lnk, ".."))) break; + if (lnk == hname || lnk[-1] == '/') { + if (!lnk[2]) goto done; + if (lnk[2]=='/') { + lnk = hname = lnk+3; + continue; + } } + lnk += 2; } - lnk += 2; + if (!*hname) hname = "./"; } + if (!*hname) goto done; if (TT.warn && hname != name) { @@ -881,7 +885,7 @@ static void trim2list(void *list, char *pline) dlist_add(list, n); if (i && n[i-1]=='\n') i--; - while (i && n[i-1] == '/') i--; + while (i>1 && n[i-1] == '/') i--; n[i] = 0; } -- 2.39.2