Re: BUG #18708: regex problem: (?:[^\d\D]){0} asserts with "lp->nouts == 0 && rp->nins == 0"

Aleksander Alekseev <aleksander@timescale.com>

From: Aleksander Alekseev <aleksander@timescale.com>
To: dhyan@nataraj.su
Cc: pgsql-bugs@lists.postgresql.org
Date: 2024-11-14T14:50:23Z
Lists: pgsql-bugs
Hi Nikolay,

> If you run
>
> SELECT '' ~ '(?:[^\d\D]){0}';
>
> it will assert with  "lp->nouts == 0 && rp->nins == 0"
>
> This behavior have been introduced in 2a0af7fe460 commit.
>
> This bug have been found while fuzzing jsonpath_in function, and then
> narrowed down to regex problem. Thanks to Andrey Bille for help with
> narrowing sample down and finding commit that caused the problem.

Thanks for the report. I can reproduce it with 18devel too:

```
#6  0x00005906af1a1e5b in delsub (nfa=0x5906b179f8b0,
lp=0x5906b179fd88, rp=0x5906b179fdc0) at
../src/backend/regex/regc_nfa.c:1292
1292        assert(lp->nouts == 0 && rp->nins == 0);    /* did the job */

(gdb) p *lp
$1 = {no = 4, flag = 0 '\000', nins = 1, nouts = 0, ins =
0x5906b17a3418, outs = 0x0, tmp = 0x0, next = 0x5906b179fdc0, prev =
0x5906b179fd50}

(gdb) p *rp
$2 = {no = 5, flag = 0 '\000', nins = 1, nouts = 1, ins =
0x5906b17a34f0, outs = 0x5906b17a3460, tmp = 0x5906b179fdc0, next =
0x5906b179fe30,
  prev = 0x5906b179fd88}
```

I wonder if the Assert is just wrong or if it's more complicated than that.

For the record:

([^\d\D]){0} - OK
(?:[^\d\D]){1} - OK
(?:[^\D]){0} - OK
(?:[^\d]){0} - OK
'(?:[^\d\D]){0}' - FAIL

The value of the left argument of the `~` operator is not important.

Thoughts?

-- 
Best regards,
Aleksander Alekseev



Commits

  1. Fix recently-exposed portability issue in regex optimization.

  2. Avoid assertion due to disconnected NFA sub-graphs in regex parsing.

  3. Fix recovery conflict SIGUSR1 handling.

  4. Redesign interrupt/cancel API for regex engine.

  5. Use MemoryContext API for regex memory management.

  6. Invent "rainbow" arcs within the regex engine.