Skip to content

Limit parser collection nesting and wrap resolver stack overflow - #874

Open
kastoestoramadus wants to merge 4 commits into
lightbend:mainfrom
kastoestoramadus:fix/port-o06-stack-overflow
Open

kastoestoramadus wants to merge 4 commits into
lightbend:mainfrom
kastoestoramadus:fix/port-o06-stack-overflow

Conversation

@kastoestoramadus

@kastoestoramadus kastoestoramadus commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

TLDR: Deeply nested collections and very long += chains fail with ConfigException.Parse instead of escaping as StackOverflowError.

Behaviour change: both parsers reject more than 100 nested objects/arrays (the root counts). The limit is fixed and not configurable. During resolution a StackOverflowError is caught at the outermost resolve and rethrown as Parse; the maximum += chain still depends on the JVM stack.

Tests in their own commit before the fix; 8 of 11 fail without it. Ported from ekrich/sconfig#636 (still a draft there).

Generated with gpt-6.1-sol/m through Codex
Reviewed by sonnet-5.5/m

kastoestoramadus and others added 2 commits October 2, 2026 15:14
Nesting beyond what the JVM stack allows escapes the parsers as
StackOverflowError, and a long chain of += does the same in resolve().

Ported from ekrich/sconfig#636 (5251a70e7b18883b0bab4faafc78683f9f538175).

Co-Authored-By: gpt-6.1-sol/m through Codex <noreply@openai.com>
Co-Authored-By: sonnet-5.5/m through Claude Code <noreply@anthropic.com>
Reject more than 100 nested objects/arrays in both parsers with
ConfigException.Parse; the root collection counts. Convert a
StackOverflowError at the outermost resolve into ConfigException.Parse,
keeping the error as the cause.

Ported from ekrich/sconfig#636 (5251a70e7b18883b0bab4faafc78683f9f538175).

Co-Authored-By: gpt-6.1-sol/m through Codex <noreply@openai.com>
Co-Authored-By: sonnet-5.5/m through Claude Code <noreply@anthropic.com>
@kastoestoramadus
kastoestoramadus force-pushed the fix/port-o06-stack-overflow branch from 7d3021a to 84b6a12 Compare October 2, 2026 13:17
kastoestoramadus and others added 2 commits October 7, 2026 14:05
2000 += lines took 4 s on a developer machine and would exceed the 30 s join
on a slow runner (resolving += lines is quadratic). A 256 KiB stack
overflows from about 100 lines on JDK 8, 17, 24 and 25, so 300 keeps a
margin and runs in 0.2 s. It still fails without the fix: "expected
ConfigException.Parse, got StackOverflowError".

Co-Authored-By: sonnet-5.5/m through Claude Code <noreply@anthropic.com>
A 256 KiB stack overflowed from about 100 lines in a cold JVM but needed over
1000 once the JIT had compiled the resolver (full suite on CI: "expected
ConfigException.Parse, got null" at 300 lines, 18 s at 2000). The JVM raises a
64 KiB request to its minimum stack, which overflows from 40 to 100 lines on
JDK 8, 17 and 25, cold or warmed up, so 500 lines keep a margin and run in
0.1 s. Still fails without the fix: "expected ConfigException.Parse, got
StackOverflowError".

Co-Authored-By: sonnet-5.5/m through Claude Code <noreply@anthropic.com>
@kastoestoramadus
kastoestoramadus marked this pull request as ready for review October 10, 2026 16:14

This branch has not been deployed

No deployments
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.

1 participant