diff options
author | Junio C Hamano <gitster@pobox.com> | 2022-01-10 22:52:49 +0300 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2022-01-10 22:52:49 +0300 |
commit | 09481fec21f339d980fca369be3936964003d38b (patch) | |
tree | 744caf847eb0c3da06a9bd80132c95882e3c57f4 | |
parent | e83ba647f7c61cf945690d6a0bd8c172a6498dc8 (diff) | |
parent | a3eca5844526fd6111e7a1e8bdfa9813673a6f23 (diff) |
Merge branch 'ds/sparse-checkout-malformed-pattern-fix'
Certain sparse-checkout patterns that are valid in non-cone mode
led to segfault in cone mode, which has been corrected.
* ds/sparse-checkout-malformed-pattern-fix:
sparse-checkout: refuse to add to bad patterns
sparse-checkout: fix OOM error with mixed patterns
sparse-checkout: fix segfault on malformed patterns
-rw-r--r-- | builtin/sparse-checkout.c | 5 | ||||
-rw-r--r-- | dir.c | 6 | ||||
-rwxr-xr-x | t/t1091-sparse-checkout-builtin.sh | 37 |
3 files changed, 42 insertions, 6 deletions
diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c index 45e838d8f8..679c107036 100644 --- a/builtin/sparse-checkout.c +++ b/builtin/sparse-checkout.c @@ -504,7 +504,7 @@ static void insert_recursive_pattern(struct pattern_list *pl, struct strbuf *pat char *oldpattern = e->pattern; size_t newlen; - if (slash == e->pattern) + if (!slash || slash == e->pattern) break; newlen = slash - e->pattern; @@ -612,6 +612,9 @@ static void add_patterns_cone_mode(int argc, const char **argv, die(_("unable to load existing sparse-checkout patterns")); free(sparse_filename); + if (!existing.use_cone_patterns) + die(_("existing sparse-checkout patterns do not use cone mode")); + hashmap_for_each_entry(&existing.recursive_hashmap, &iter, pe, ent) { if (!hashmap_contains_parent(&pl->recursive_hashmap, pe->pattern, &buffer) || @@ -727,7 +727,7 @@ static void add_pattern_to_hashsets(struct pattern_list *pl, struct path_pattern } if (given->patternlen < 2 || - *given->pattern == '*' || + *given->pattern != '/' || strstr(given->pattern, "**")) { /* Not a cone pattern. */ warning(_("unrecognized pattern: '%s'"), given->pattern); @@ -819,9 +819,7 @@ static void add_pattern_to_hashsets(struct pattern_list *pl, struct path_pattern /* we already included this at the parent level */ warning(_("your sparse-checkout file may have issues: pattern '%s' is repeated"), given->pattern); - hashmap_remove(&pl->parent_hashmap, &translated->ent, &data); - free(data); - free(translated); + goto clear_hashmaps; } return; diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh index 833fcadd5c..32a6328ddb 100755 --- a/t/t1091-sparse-checkout-builtin.sh +++ b/t/t1091-sparse-checkout-builtin.sh @@ -111,6 +111,18 @@ test_expect_success 'clone --sparse' ' check_files clone a ' +test_expect_success 'switching to cone mode with non-cone mode patterns' ' + git init bad-patterns && + ( + cd bad-patterns && + git sparse-checkout init && + git sparse-checkout add dir && + git config core.sparseCheckoutCone true && + test_must_fail git sparse-checkout add dir 2>err && + grep "existing sparse-checkout patterns do not use cone mode" err + ) +' + test_expect_success 'interaction with clone --no-checkout (unborn index)' ' git clone --no-checkout "file://$(pwd)/repo" clone_no_checkout && git -C clone_no_checkout sparse-checkout init --cone && @@ -173,12 +185,14 @@ test_expect_success 'set sparse-checkout using --stdin' ' ' test_expect_success 'add to sparse-checkout' ' - cat repo/.git/info/sparse-checkout >expect && + cat repo/.git/info/sparse-checkout >old && + test_when_finished cp old repo/.git/info/sparse-checkout && cat >add <<-\EOF && pattern1 /folder1/ pattern2 EOF + cat old >expect && cat add >>expect && git -C repo sparse-checkout add --stdin <add && git -C repo sparse-checkout list >actual && @@ -716,4 +730,25 @@ test_expect_success 'cone mode clears ignored subdirectories' ' test_cmp expect out ' +test_expect_success 'malformed cone-mode patterns' ' + git -C repo sparse-checkout init --cone && + mkdir -p repo/foo/bar && + touch repo/foo/bar/x repo/foo/y && + cat >repo/.git/info/sparse-checkout <<-\EOF && + /* + !/*/ + /foo/ + !/foo/*/ + /foo/\*/ + EOF + + # Listing the patterns will notice the duplicate pattern and + # emit a warning. It will list the patterns directly instead + # of using the cone-mode translation to a set of directories. + git -C repo sparse-checkout list >actual 2>err && + test_cmp repo/.git/info/sparse-checkout actual && + grep "warning: your sparse-checkout file may have issues: pattern .* is repeated" err && + grep "warning: disabling cone pattern matching" err +' + test_done |