Skip to content

Compiled & source-generated Regex throw IndexOutOfRangeException on a nested optional containing a lazy capturing loop #129511

Description

@janipulkkinen

Description

A pattern combining an outer optional group wrapping an inner optional capturing group followed by a lazily-quantified capturing loop and a trailing literal throws System.IndexOutOfRangeException during matching under both RegexOptions.Compiled and the [GeneratedRegex] source generator. The interpreter matches the same input correctly (empty successful match).

Note: similar to #126556, but a different defect — it still reproduces on 11.0.0-preview.5.26302.115, which already contains the #126556 fix (PR #126561).

Reproduction Steps

using System.Text.RegularExpressions;

partial class Program
{
    private const string Pattern = @"((a+(:c*)?@)?([0-9]|A){1,4}?:)?";

    [GeneratedRegex(Pattern)]
    private static partial Regex Generated();

    static void Main()
    {
        const string input = "1234";
        Console.WriteLine(new Regex(Pattern).Match(input).Success); // OK: empty match
        new Regex(Pattern, RegexOptions.Compiled).Match(input);            // throws IndexOutOfRangeException
        Generated().Match(input);                                          // throws IndexOutOfRangeException
    }
}

Expected behavior

All three engines should agree (interpreter returns a successful empty match). Instead Compiled and [GeneratedRegex] throw IndexOutOfRangeException in TryMatchAtCurrentPosition.

Actual behavior

Compiled and [GeneratedRegex] throw IndexOutOfRangeException in TryMatchAtCurrentPosition.

Regression?

No response

Known Workarounds

No response

Configuration

.NET 8.0.26 / 9.0.15 / 10.0.7 / 11.0.0-preview.5.26302.115
Windows 11 x64

Other information

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions