# git grep '(' = segfault

9 messages from 2009-04-27 to 2009-04-27. Participants: Dmitry Potapov, Linus Torvalds, Michał Kiedrowicz, Erik Faye-Lund, Matthieu Moy, Junio C Hamano.
Thread: https://gitlist.dev/t/19089

## Dmitry Potapov, 2009-04-27 17:46

Subject: git grep '(' = segfault
Message-ID: <37fcd2780904271046r7740ed42t3c9438e7aa93374@mail.gmail.com>
URL: https://gitlist.dev/e/37fcd2780904271046r7740ed42t3c9438e7aa93374%40mail.gmail.com

```
Hi,

I have tried a few version of Git and got "Segmentation fault" when
run:

$ git grep '('

I am not very familiar with grep code and don't have time to dig
into it right now. So, maybe someone else can take a look at it.

Thanks,
Dmitry

```

## Linus Torvalds, 2009-04-27 18:10

Subject: Re: git grep '(' = segfault
Message-ID: <alpine.LFD.2.00.0904271059060.22156@localhost.localdomain>
URL: https://gitlist.dev/e/alpine.LFD.2.00.0904271059060.22156%40localhost.localdomain
In-Reply-To: <37fcd2780904271046r7740ed42t3c9438e7aa93374@mail.gmail.com>

```


On Mon, 27 Apr 2009, Dmitry Potapov wrote:
> 
> I have tried a few version of Git and got "Segmentation fault" when
> run:
> 
> $ git grep '('
> 
> I am not very familiar with grep code and don't have time to dig
> into it right now. So, maybe someone else can take a look at it.

Good job.

Something like this should fix it.

		Linus

---
 grep.c |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/grep.c b/grep.c
index f3a27d7..04c777a 100644
--- a/grep.c
+++ b/grep.c
@@ -72,6 +72,8 @@ static struct grep_expr *compile_pattern_atom(struct grep_pat **list)
 	struct grep_expr *x;
 
 	p = *list;
+	if (!p)
+		return NULL;
 	switch (p->token) {
 	case GREP_PATTERN: /* atom */
 	case GREP_PATTERN_HEAD:
@@ -84,8 +86,6 @@ static struct grep_expr *compile_pattern_atom(struct grep_pat **list)
 	case GREP_OPEN_PAREN:
 		*list = p->next;
 		x = compile_pattern_or(list);
-		if (!x)
-			return NULL;
 		if (!*list || (*list)->token != GREP_CLOSE_PAREN)
 			die("unmatched parenthesis");
 		*list = (*list)->next;
@@ -101,6 +101,8 @@ static struct grep_expr *compile_pattern_not(struct grep_pat **list)
 	struct grep_expr *x;
 
 	p = *list;
+	if (!p)
+		return NULL;
 	switch (p->token) {
 	case GREP_NOT:
 		if (!p->next)
@@ -372,6 +374,8 @@ static int match_expr_eval(struct grep_expr *x, char *bol, char *eol,
 	int h = 0;
 	regmatch_t match;
 
+	if (!x)
+		die("Not a valid grep expression");
 	switch (x->node) {
 	case GREP_NODE_ATOM:
 		h = match_one_pattern(x->u.atom, bol, eol, ctx, &match, 0);

```

## Michał Kiedrowicz, 2009-04-27 18:15

Subject: Re: git grep '(' = segfault
Message-ID: <20090427201513.5d598e3c@gmail.com>
URL: https://gitlist.dev/e/20090427201513.5d598e3c%40gmail.com
In-Reply-To: <37fcd2780904271046r7740ed42t3c9438e7aa93374@mail.gmail.com>

```
Dmitry Potapov <dpotapov@gmail.com> wrote:

> Hi,
> 
> I have tried a few version of Git and got "Segmentation fault" when
> run:
> 
> $ git grep '('
> 
> I am not very familiar with grep code and don't have time to dig
> into it right now. So, maybe someone else can take a look at it.
> 
> Thanks,
> Dmitry
> --

Try this patch, however I'm not sure if it is correct.

---

diff --git a/grep.c b/grep.c
index f3a27d7..5748355 100644
--- a/grep.c
+++ b/grep.c
@@ -84,10 +84,10 @@ static struct grep_expr *compile_pattern_atom(struct grep_pat **list)
 	case GREP_OPEN_PAREN:
 		*list = p->next;
 		x = compile_pattern_or(list);
-		if (!x)
-			return NULL;
 		if (!*list || (*list)->token != GREP_CLOSE_PAREN)
 			die("unmatched parenthesis");
+		if (!x)
+			return NULL;
 		*list = (*list)->next;
 		return x;
 	default:

```

## Erik Faye-Lund, 2009-04-27 18:42

Subject: Re: git grep '(' = segfault
Message-ID: <40aa078e0904271142u71d7ba97w9df80667c0d9b955@mail.gmail.com>
URL: https://gitlist.dev/e/40aa078e0904271142u71d7ba97w9df80667c0d9b955%40mail.gmail.com
In-Reply-To: <alpine.LFD.2.00.0904271059060.22156@localhost.localdomain>

```
On Mon, Apr 27, 2009 at 8:10 PM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
> Something like this should fix it.
>
>                Linus

(Sorry that you're getting this mail twice, Linus - I forgot to reply all)

This does indeed fix the crash, but I find the resulting operation
quite bizarre. I'm getting a "fatal: unmatched paranthesis", however
"git grep '(('" is happy to simply grep for the double parenthesis.
Now, if I had done "git grep '\('", I'd expect an unmatched
parenthesis-error... Am I misunderstanding something here?

$ git grep '('
fatal: unmatched parenthesis

$ git grep '(('
Documentation/CodingGuidelines: - We use Arithmetic Expansion $(( ... )).
[...]

$ git grep '\('
fatal: command line, '\(': Unmatched ( or \(

-- 
Erik "kusma" Faye-Lund
kusmabite@gmail.com
(+47) 986 59 656

```

## Linus Torvalds, 2009-04-27 18:50

Subject: Re: git grep '(' = segfault
Message-ID: <alpine.LFD.2.00.0904271149480.22156@localhost.localdomain>
URL: https://gitlist.dev/e/alpine.LFD.2.00.0904271149480.22156%40localhost.localdomain
In-Reply-To: <40aa078e0904271142u71d7ba97w9df80667c0d9b955@mail.gmail.com>

```


On Mon, 27 Apr 2009, Erik Faye-Lund wrote:
> On Mon, Apr 27, 2009 at 8:10 PM, Linus Torvalds
> <torvalds@linux-foundation.org> wrote:
> > Something like this should fix it.
> >
> >                Linus
> 
> (Sorry that you're getting this mail twice, Linus - I forgot to reply all)

Payback time. Now _you'll_ get it twice. Mmmwwhahahahaahaaa!

> $ git grep '('
> fatal: unmatched parenthesis

Try this:

        git grep -e '('

because 'git grep' actually allows multiple patterns, so you can do things 
like

        git grep '(' -e hello --or -e 'hi there' ')' --and -e world

Practical? Maybe.

                Linus

```

## Erik Faye-Lund, 2009-04-27 18:53

Subject: Re: git grep '(' = segfault
Message-ID: <40aa078e0904271153s48fccf1dj4b1bff62abbaf049@mail.gmail.com>
URL: https://gitlist.dev/e/40aa078e0904271153s48fccf1dj4b1bff62abbaf049%40mail.gmail.com
In-Reply-To: <alpine.LFD.2.00.0904271149480.22156@localhost.localdomain>

```
> Practical? Maybe.

Confusing? Yes. ;)

-- 
Erik "kusma" Faye-Lund
kusmabite@gmail.com
(+47) 986 59 656

```

## Matthieu Moy, 2009-04-27 18:54

Subject: Re: git grep '(' = segfault
Message-ID: <vpqfxfund0m.fsf@bauges.imag.fr>
URL: https://gitlist.dev/e/vpqfxfund0m.fsf%40bauges.imag.fr
In-Reply-To: <40aa078e0904271142u71d7ba97w9df80667c0d9b955@mail.gmail.com>

```
Erik Faye-Lund <kusmabite@googlemail.com> writes:

> $ git grep '('
> fatal: unmatched parenthesis

try this: git grep -e '('

The idea is that you can do things like

git grep -e foo --and '(' -e bar --or -e boz ')'

to build a boolean expression of expressions.

-- 
Matthieu

```

## Erik Faye-Lund, 2009-04-27 19:02

Subject: Re: git grep '(' = segfault
Message-ID: <40aa078e0904271202ye89ebf2wf417c623d8fe5689@mail.gmail.com>
URL: https://gitlist.dev/e/40aa078e0904271202ye89ebf2wf417c623d8fe5689%40mail.gmail.com
In-Reply-To: <vpqfxfund0m.fsf@bauges.imag.fr>

```
Yeah, thanks for explaining. But isn't this functionality kind of
redundant since we have the -E switch?
As far as I can see, "git grep -E "(bar|boz)" should do the same thing
as "git grep -e foo --and '(' -e bar --or -e boz ')'"...

On Mon, Apr 27, 2009 at 8:54 PM, Matthieu Moy <Matthieu.Moy@imag.fr> wrote:
> Erik Faye-Lund <kusmabite@googlemail.com> writes:
>
>> $ git grep '('
>> fatal: unmatched parenthesis
>
> try this: git grep -e '('
>
> The idea is that you can do things like
>
> git grep -e foo --and '(' -e bar --or -e boz ')'
>
> to build a boolean expression of expressions.
>
> --
> Matthieu
>



-- 
Erik "kusma" Faye-Lund
kusmabite@gmail.com
(+47) 986 59 656

```

## Junio C Hamano, 2009-04-27 23:18

Subject: Re: git grep '(' = segfault
Message-ID: <7vd4axwurv.fsf@gitster.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vd4axwurv.fsf%40gitster.siamese.dyndns.org
In-Reply-To: <40aa078e0904271202ye89ebf2wf417c623d8fe5689@mail.gmail.com>

```
Erik Faye-Lund <kusmabite@googlemail.com> writes:

> Yeah, thanks for explaining. But isn't this functionality kind of
> redundant since we have the -E switch?
> As far as I can see, "git grep -E "(bar|boz)" should do the same thing
> as "git grep -e foo --and '(' -e bar --or -e boz ')'"...

With -E, --or is not strictly necessary.

With only -E, however, it is cumbersome to express what --and can.  Once
you learn the handiness of --and, naturally you would start wanting to
be able to say --or (especially if you do not even know about -E).

```
