From 4d5106f2b5e48a34ec0e341974737252ed5aae84 Mon Sep 17 00:00:00 2001 From: Stephane Chazelas Date: Fri, 27 Dec 2024 23:20:16 +0000 Subject: [PATCH] tar: fix bug when -s/a/b/ used more than once with b flag (#2435) When the -s/regexp/replacement/ option was used with the b flag more than once, the result of the previous substitution was appended to the previous subject instead of replacing it. Fixed it by making sure the subject is made the empty string before the call to realloc_strcat(). That in effect makes it more like a realloc_strcpy(), but creating a new realloc_strcpy() function for that one usage doesn't feel worth it. Resolves Issue libarchive/libarchive#2414 Co-authored-by: Stephane Chazelas --- tar/subst.c | 1 + tar/test/test_option_s.c | 14 +++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/tar/subst.c b/tar/subst.c index 0194cc84b..5546b5f93 100644 --- a/tar/subst.c +++ b/tar/subst.c @@ -229,6 +229,7 @@ apply_substitution(struct bsdtar *bsdtar, const char *name, char **result, if (rule->from_begin && *result) { realloc_strcat(result, name); + if (buffer) buffer[0] = 0; realloc_strcat(&buffer, *result); name = buffer; (*result)[0] = 0; diff --git a/tar/test/test_option_s.c b/tar/test/test_option_s.c index 1a36280c1..125e971d3 100644 --- a/tar/test/test_option_s.c +++ b/tar/test/test_option_s.c @@ -70,7 +70,7 @@ DEFINE_TEST(test_option_s) assertFileContents("bar", 3, "test4/in/d1/baz"); /* - * Test 4b: Multiple substitutions behavior with option b). + * Test 4b: Multiple substitutions behavior with option b. */ assertMakeDir("test4b", 0755); systemf("%s -cf test4b.tar in/d1/foo in/d1/bar", @@ -80,6 +80,18 @@ DEFINE_TEST(test_option_s) assertFileContents("foo", 3, "test4b/in/d1/faz"); assertFileContents("bar", 3, "test4b/in/d1/baz"); + /* + * Test 4bb: Multiple substitutions with option b + * (libarchive/libarchive#2414 GitHub issue regression test). + */ + assertMakeDir("test4bb", 0755); + systemf("%s -cf test4bb.tar in/d1/foo in/d1/bar", + testprog); + systemf("%s -xf test4bb.tar -s /oo/ar/ -s }ar}az}b -s :az:end:b -C test4bb", + testprog); + assertFileContents("foo", 3, "test4bb/in/d1/fend"); + assertFileContents("bar", 3, "test4bb/in/d1/bend"); + /* * Test 5: Name-switching substitutions when extracting archive. */ -- 2.47.2