[9.2] crash on regex

Started by Marko Kreenover 13 years ago6 messages
#1Marko Kreen
markokr@gmail.com

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

#2Robert Haas
robertmhaas@gmail.com
In reply to: Marko Kreen (#1)
Re: [9.2] crash on regex

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

#3Thom Brown
thom@linux.com
In reply to: Robert Haas (#2)
Re: [9.2] crash on regex

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

#4Thom Brown
thom@linux.com
In reply to: Thom Brown (#3)
Re: [9.2] crash on regex

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

#5Tom Lane
tgl@sss.pgh.pa.us
In reply to: Robert Haas (#2)
Re: [9.2] crash on regex

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

#6Tom Lane
tgl@sss.pgh.pa.us
In reply to: Thom Brown (#4)
Re: [9.2] crash on regex

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