ReviewOS

zig-utils/zig-regex

Parser: roll back named capture and built-in class allocations on OOM

#20
Closed chris opened this 10 days ago ·
10 days ago

Problem

Exhaustive allocation-failure testing of a named-capture expression exposes two parser ownership leaks:

  • the normalized name returned by parseGroupName is orphaned when parsing or allocating the group body later fails;
  • non-Unicode \\d, \\D, \\w, and \\W nodes duplicate static character-class ranges before allocating the AST node, but do not free that duplicate if node allocation fails.

This was found while making zig-js parse-time RegExp validation use bounded scratch storage in zig-utils/zig-js#560.

Required behavior

  • every fallible construction edge rolls back allocations it has not transferred;
  • successful AST nodes retain ownership exactly once;
  • behavior and accepted RegExp syntax remain unchanged;
  • exhaustive checkAllAllocationFailures coverage includes a named capture, a lookahead, built-in classes, and ordinary character classes.

Validation

  • focused exhaustive allocation-failure test;
  • complete zig-regex test suite with zero leaks.

Related: zig-utils/zig-js#560

10 days ago

Fixed on main by e9ea8b5: named-capture names and duplicated built-in class ranges now roll back on every later allocation failure. Added exhaustive allocation-failure coverage for the combined construction path. zig build test-core and the complete 609-test suite pass with zero leaks.

10 days ago

Reopened after zig-js#560 exhaustive validation reached a second constructor family: Unicode/code-point class sets could transfer nested items through a fallible slice/node allocation without a complete rollback. The follow-up consolidates class-set ownership transfer, covers nested/string items, and adds a dedicated exhaustive class-set compilation test. Full-suite validation is running before the follow-up lands.

10 days ago

Follow-up fixed on main by cfb24da: all class-set constructors now use failure-atomic item/set/node ownership transfer, including nested and owned-string items. The zig-js#560 allocation sweep passes all 101 injected points; the complete zig-regex suite passes 610/610 with zero leaks.

Sign in to comment on this issue.