Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 9, 2025

Deferred and Recursive parsers crash with stack overflow when configured with infinite recursion (e.g., loop.Parser = loop or Recursive(c => c)).

var loop = Deferred<string>();
loop.Parser = loop;  // Direct self-reference
var result = loop.Parse("test");  // Stack overflow

var recursive = Recursive<string>(c => c);  // Self-reference via constructor
var result2 = recursive.Parse("test");  // Stack overflow

Changes

  • ParseContext: Added position-aware cycle detection via _activeParserPositions HashSet tracking parser-position pairs using an optimized private ParserPosition record struct

    • IsParserActiveAtPosition(): Check if parser already active at current input offset
    • PushParserAtPosition() / PopParserAtPosition(): Manage active parser stack
    • DisableLoopDetection: New property to disable loop detection when needed (e.g., when ParseContext is mutated during loops)
  • Deferred.Parse(): Check for cycles before recursing; return false (parse failure) when same parser invoked at same position. Respects the DisableLoopDetection flag.

  • Tests: Added coverage for direct self-reference, recursive constructor, valid recursion scenarios, and DisableLoopDetection flag

Valid recursive parsers that consume input between invocations remain unaffected. Loop detection can be disabled by setting ParseContext.DisableLoopDetection = true when needed.

Original prompt

This section details on the original issue you should resolve

<issue_title>Access Violation exception</issue_title>
<issue_description>@sebastienros is there any cycle detection mechanism in parlot?

example code which will break your app:

var loop = Deferred<string>();

loop.Parser = loop;

var test = loop.Parse("hello parlot");

or

var loop = Recursive<string>(c => c);

var test = loop.Parse("hello parlot");

I would expect this will detect infinite loop and return null instead of crashing.

image
</issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 2 commits November 9, 2025 17:04
Co-authored-by: sebastienros <1165805+sebastienros@users.noreply.github.com>
Co-authored-by: sebastienros <1165805+sebastienros@users.noreply.github.com>
Copilot AI changed the title [WIP] Add cycle detection mechanism to prevent access violation Fix stack overflow in Deferred parsers with infinite recursion Nov 9, 2025
Copilot AI requested a review from sebastienros November 9, 2025 17:12
Copilot finished work on behalf of sebastienros November 9, 2025 17:12
@sebastienros sebastienros marked this pull request as ready for review November 10, 2025 09:36
@sebastienros
Copy link
Owner

@copilot add an option in ParseContext to disable this feature. For instance bool DisableLoopDetection { get; set; } = false; since the ParseContext itself could be mutated during loops and change the end result of parsing at the same location.

Co-authored-by: sebastienros <1165805+sebastienros@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 10, 2025

@copilot add an option in ParseContext to disable this feature. For instance bool DisableLoopDetection { get; set; } = false; since the ParseContext itself could be mutated during loops and chan...

Added the DisableLoopDetection property to ParseContext in commit 8069841.

The property defaults to false (loop detection enabled), and when set to true, the cycle detection is bypassed. The implementation checks the flag in Deferred.Parse() before performing position tracking and cycle detection.

Co-authored-by: sebastienros <1165805+sebastienros@users.noreply.github.com>
Copilot finished work on behalf of sebastienros November 10, 2025 10:00
@sebastienros sebastienros enabled auto-merge (squash) November 10, 2025 10:01
@sebastienros sebastienros merged commit ebec683 into main Nov 10, 2025
2 checks passed
@sebastienros sebastienros deleted the copilot/add-cycle-detection-mechanism branch November 10, 2025 10:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Access Violation exception

2 participants