As demonstrated in the previous commit, `git log --invert-grep` without a `--grep` argument causes a segfault after f41fb662f5 (revisions API: have release_revisions() release "grep_filter", 2022-04-13). The segfault occurs in `free_pattern_expr()`, which crashes on trying to switch on `x->node` when given a NULL pointer. Usually we avoid calling `free_pattern_expr()` without a pattern as indicated by the `extended` bit being zero. But it is possible to get into a state where the `extended` bit is non-zero, but the `pattern_expression` is still NULL. This happens because the `--invert-grep` option sets the `no_body_match` bit. When we call `compile_grep_patterns()`, we set `opt->extended = 1`. But the `pattern_expression` is left as NULL, since we return with a NULL `header_expr`. So when we try to call `free_pattern_expr()`, things go awry, since `free_grep_patterns()` expects a non-NULL argument. Instead, teach `free_grep_patterns()` to tolerate a NULL argument (treating it as a noop), and avoid checking whether or not the `extended` bit is set, since `free_pattern_expr()` will handle its argument regardless. Signed-off-by: Taylor Blau <me@xxxxxxxxxxxx> --- grep.c | 5 +++-- t/t4202-log.sh | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/grep.c b/grep.c index 52a894c989..bcc6e63365 100644 --- a/grep.c +++ b/grep.c @@ -752,6 +752,9 @@ void compile_grep_patterns(struct grep_opt *opt) static void free_pattern_expr(struct grep_expr *x) { + if (!x) + return; + switch (x->node) { case GREP_NODE_TRUE: case GREP_NODE_ATOM: @@ -790,8 +793,6 @@ void free_grep_patterns(struct grep_opt *opt) free(p); } - if (!opt->extended) - return; free_pattern_expr(opt->pattern_expression); } diff --git a/t/t4202-log.sh b/t/t4202-log.sh index e3ec5f5661..44f7ef0ea2 100755 --- a/t/t4202-log.sh +++ b/t/t4202-log.sh @@ -297,7 +297,7 @@ test_expect_success 'log --invert-grep --grep -i' ' fi ' -test_expect_failure 'log --invert-grep (no --grep)' ' +test_expect_success 'log --invert-grep (no --grep)' ' git log --pretty="tformat:%s" >expect && git log --invert-grep --pretty="tformat:%s" >actual && test_cmp expect actual -- 2.37.0.1.g1379af2e9d