fix(#1028): LenientJsonParser infinite-loop / OOM on non-JSON content#40
Merged
Skobeltsyn merged 1 commit intomainfrom May 5, 2026
Merged
fix(#1028): LenientJsonParser infinite-loop / OOM on non-JSON content#40Skobeltsyn merged 1 commit intomainfrom
Skobeltsyn merged 1 commit intomainfrom
Conversation
Two-layer fix for the parser bug that turned LLM-emitted brackets around
non-JSON content (e.g. `[abc]`, `{"k": foo}`, `[<html>]`) into infinite
loops and OOM during agent invocation.
Layer 1: parseValue() now strict on the else branch — throws on chars
that aren't a valid JSON-value prefix instead of falling through to
parseNumber(). The throw is caught by parse(input)'s try/catch and the
function returns null, preserving the lenient contract.
Layer 2: parseArray() and parseObject() carry zero-progress guards as
defense-in-depth. Each loop iteration captures pos before parseValue()
and throws if pos didn't advance afterward — catches any future
regression where some other path also fails to advance.
Root cause: the old `else -> parseNumber()` fallthrough returned 0
without advancing pos when the input had no digits (the digit-while-loop
ran zero times, substring start..pos was empty, the `if (n.isEmpty())
return 0` branch fired). Back in parseArray, the loop condition was
unchanged, list.add(0) repeated forever.
Bumps version 0.2.2 → 0.2.3 (patch). Same fix will roll into 0.3.0.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two-layer fix for the parser bug that turned LLM-emitted brackets around non-JSON content (e.g.
[abc],{"k": foo},[<html>]) into infinite loops and OOM during agent invocation.Layer 1: parseValue() now strict on the else branch — throws on chars that aren't a valid JSON-value prefix instead of falling through to parseNumber(). The throw is caught by parse(input)'s try/catch and the function returns null, preserving the lenient contract.
Layer 2: parseArray() and parseObject() carry zero-progress guards as defense-in-depth. Each loop iteration captures pos before parseValue() and throws if pos didn't advance afterward — catches any future regression where some other path also fails to advance.
Root cause: the old
else -> parseNumber()fallthrough returned 0 without advancing pos when the input had no digits (the digit-while-loop ran zero times, substring start..pos was empty, theif (n.isEmpty()) return 0branch fired). Back in parseArray, the loop condition was unchanged, list.add(0) repeated forever.Bumps version 0.2.2 → 0.2.3 (patch). Same fix will roll into 0.3.0.