]> git.ipfire.org Git - thirdparty/git.git/commitdiff
apply: normalize path in --directory argument
authorJoaquim Rocha <joaquim@amutable.com>
Wed, 18 Feb 2026 00:15:32 +0000 (00:15 +0000)
committerJunio C Hamano <gitster@pobox.com>
Fri, 20 Feb 2026 18:12:58 +0000 (10:12 -0800)
When passing a relative path like --directory=./some/sub, the leading
"./" caused apply to prepend it literally to patch filenames, resulting
in an error (invalid path).
There may be more cases like this where users pass some/./path to the
directory which can easily be normalized to an acceptable path, so
these changes try to normalize the path before using it.

Signed-off-by: Joaquim Rocha <joaquim@amutable.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
apply.c
t/t4128-apply-root.sh

diff --git a/apply.c b/apply.c
index a2ceb3fb40d3b5eae9b524008a1781ea91d87ecf..7c07d124f4afb290df04ec33c85d5f2998836296 100644 (file)
--- a/apply.c
+++ b/apply.c
@@ -4963,6 +4963,10 @@ static int apply_option_parse_directory(const struct option *opt,
 
        strbuf_reset(&state->root);
        strbuf_addstr(&state->root, arg);
+
+       if (strbuf_normalize_path(&state->root) < 0)
+               return error(_("unable to normalize directory: '%s'"), arg);
+
        strbuf_complete(&state->root, '/');
        return 0;
 }
index f6db5a79dd9d356c93a935374c4c27520ecf6593..5eba15fa66b956554147a253f72bc03c29598d78 100755 (executable)
@@ -43,6 +43,47 @@ test_expect_success 'apply --directory -p (2) ' '
 
 '
 
+test_expect_success 'apply --directory (./ prefix)' '
+       git reset --hard initial &&
+       git apply --directory=./some/sub -p3 --index patch &&
+       echo Bello >expect &&
+       git show :some/sub/dir/file >actual &&
+       test_cmp expect actual &&
+       test_cmp expect some/sub/dir/file
+'
+
+test_expect_success 'apply --directory (double slash)' '
+       git reset --hard initial &&
+       git apply --directory=some//sub -p3 --index patch &&
+       echo Bello >expect &&
+       git show :some/sub/dir/file >actual &&
+       test_cmp expect actual &&
+       test_cmp expect some/sub/dir/file
+'
+
+test_expect_success 'apply --directory (./ in the middle)' '
+       git reset --hard initial &&
+       git apply --directory=some/./sub -p3 --index patch &&
+       echo Bello >expect &&
+       git show :some/sub/dir/file >actual &&
+       test_cmp expect actual &&
+       test_cmp expect some/sub/dir/file
+'
+
+test_expect_success 'apply --directory (../ in the middle)' '
+       git reset --hard initial &&
+       git apply --directory=some/../some/sub -p3 --index patch &&
+       echo Bello >expect &&
+       git show :some/sub/dir/file >actual &&
+       test_cmp expect actual &&
+       test_cmp expect some/sub/dir/file
+'
+
+test_expect_success 'apply --directory rejects leading ../' '
+       test_must_fail git apply --directory=../foo -p3 patch 2>err &&
+       test_grep "unable to normalize directory" err
+'
+
 cat > patch << EOF
 diff --git a/newfile b/newfile
 new file mode 100644