diff --git a/std/regex/internal/parser.d b/std/regex/internal/parser.d index d8ebe59f0a6..480b7e555c4 100644 --- a/std/regex/internal/parser.d +++ b/std/regex/internal/parser.d @@ -968,17 +968,13 @@ if (isForwardRange!R && is(ElementType!R : dchar)) case '1': .. case '9': uint nref = cast(uint) front - '0'; immutable maxBackref = sum(g.groupStack.data); - enforce(nref < maxBackref, "Backref to unseen group"); - //perl's disambiguation rule i.e. - //get next digit only if there is such group number popFront(); - while (nref < maxBackref && !empty && std.ascii.isDigit(front)) + while (!empty && std.ascii.isDigit(front)) { nref = nref * 10 + front - '0'; popFront(); } - if (nref >= maxBackref) - nref /= 10; + enforce(nref < maxBackref, "Backref to unseen group"); enforce(!g.isOpenGroup(nref), "Backref to open group"); uint localLimit = maxBackref - g.groupStack.top; if (nref >= localLimit) diff --git a/std/regex/internal/tests2.d b/std/regex/internal/tests2.d index 0c9f23d7941..c942374f478 100644 --- a/std/regex/internal/tests2.d +++ b/std/regex/internal/tests2.d @@ -711,3 +711,12 @@ version (none) // TODO: revist once we have proper benchmark framework ma = ma2; assert(ma[1] == ""); } + +// https://github.com/dlang/phobos/issues/11035 +@safe unittest +{ + assertThrown(regex(`(a)\12`)); + assertThrown(regex(`(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\123`)); + // a valid multi-digit backref still works + assertNotThrown(regex(`(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\12`)); +}