Thread: [9.2] crash on regex

[9.2] crash on regex

From
Marko Kreen
Date:
Following query crashes backend on 9.2:
 select substring('asd TO foo' from ' TO (([a-z0-9._]+|"([^"]+|"")+")+)');

It is supposed to load potentially quoted table name from
CREATE RULE definition.  Works fine on 8.3 .. 9.1

Backtrace:
Program terminated with signal 11, Segmentation fault.
#0  ExecMakeFunctionResult (fcache=0xffffffff, econtext=0x953f3e8,
isNull=0xbffb8d1f "\b", isDone=0x0) at execQual.c:1833
1833                    *isNull = fcinfo->isnull;
(gdb) bt
#0  ExecMakeFunctionResult (fcache=0xffffffff, econtext=0x953f3e8,
isNull=0xbffb8d1f "\b", isDone=0x0) at execQual.c:1833
#1  0x08203104 in ExecEvalExprSwitchContext (expression=0x953ef60,
econtext=0x953f3e8, isNull=0xbffb8d1f "\b", isDone=0x0) at
execQual.c:4187
#2  0x082844d7 in evaluate_expr (expr=<value optimized out>,
result_type=25, result_typmod=<value optimized out>,
result_collation=100) at clauses.c:4408
...

-- 
marko


Re: [9.2] crash on regex

From
Robert Haas
Date:
On Thu, May 24, 2012 at 10:16 AM, Marko Kreen <markokr@gmail.com> wrote:
> Following query crashes backend on 9.2:
>
>  select substring('asd TO foo' from ' TO (([a-z0-9._]+|"([^"]+|"")+")+)');

I spent some time trying to reduce this to the simplest case that
still causes a crash, and came up with this:

select substring('a' from '((a))+');

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


Re: [9.2] crash on regex

From
Thom Brown
Date:
On 24 May 2012 16:08, Robert Haas <robertmhaas@gmail.com> wrote:
> On Thu, May 24, 2012 at 10:16 AM, Marko Kreen <markokr@gmail.com> wrote:
>> Following query crashes backend on 9.2:
>>
>>  select substring('asd TO foo' from ' TO (([a-z0-9._]+|"([^"]+|"")+")+)');
>
> I spent some time trying to reduce this to the simplest case that
> still causes a crash, and came up with this:
>
> select substring('a' from '((a))+');

It appears to occur with any quantifier attached to a group that is
more than 1 level deep with nothing between the groups, such as
((a))?, ((a))*, ((a)){1,4}, (((a)))+

Or if the quantifier is the only additional thing between the groups,
such as ((a)+)

But when breaking the groups up, it's fine, so this works: ((a)b)+

--
Thom


Re: [9.2] crash on regex

From
Thom Brown
Date:
On 24 May 2012 16:24, Thom Brown <thom@linux.com> wrote:
> On 24 May 2012 16:08, Robert Haas <robertmhaas@gmail.com> wrote:
>> On Thu, May 24, 2012 at 10:16 AM, Marko Kreen <markokr@gmail.com> wrote:
>>> Following query crashes backend on 9.2:
>>>
>>>  select substring('asd TO foo' from ' TO (([a-z0-9._]+|"([^"]+|"")+")+)');
>>
>> I spent some time trying to reduce this to the simplest case that
>> still causes a crash, and came up with this:
>>
>> select substring('a' from '((a))+');
>
> It appears to occur with any quantifier attached to a group that is
> more than 1 level deep with nothing between the groups, such as
> ((a))?, ((a))*, ((a)){1,4}, (((a)))+
>
> Or if the quantifier is the only additional thing between the groups,
> such as ((a)+)
>
> But when breaking the groups up, it's fine, so this works: ((a)b)+

Hmmm... curiously, lazy (non-greedy) quantifiers are stable, such as: ((a))*?

--
Thom


Re: [9.2] crash on regex

From
Tom Lane
Date:
Robert Haas <robertmhaas@gmail.com> writes:
> On Thu, May 24, 2012 at 10:16 AM, Marko Kreen <markokr@gmail.com> wrote:
>> Following query crashes backend on 9.2:
>> 
>> �select substring('asd TO foo' from ' TO (([a-z0-9._]+|"([^"]+|"")+")+)');

> I spent some time trying to reduce this to the simplest case that
> still causes a crash, and came up with this:

> select substring('a' from '((a))+');

Yeah, I'm looking at it.  Looks like I broke memory management somewhere
in the quantifier revisions --- it seems to be stomping the stack during
cleanup at the end of pg_regexec.  Possibly a multiple-free deal?
Haven't quite found it yet.
        regards, tom lane


Re: [9.2] crash on regex

From
Tom Lane
Date:
Thom Brown <thom@linux.com> writes:
> Hmmm... curiously, lazy (non-greedy) quantifiers are stable, such as: ((a))*?

I've found it.  The triggering conditions are (1) more than one set of
capturing parens in a substring() pattern, and (2) at least one trial
midpoint failing in ccondissect() or one of its siblings.  That results
in zaptreesubs() trying to clear an array entry that isn't there...
trivial to fix fortunately.  So it's not so much what the quantifiers
are as whether the first attempted match succeeds.
        regards, tom lane