Sitelet https://github.com/jmespath/jmespath.py/pull/377
Skip to content

limit expression nesting depth to avoid bare RecursionError - #377

Open
choudhryfrompak wants to merge 1 commit into
jmespath:developfrom
choudhryfrompak:limit-parser-nesting-depth
Open

choudhryfrompak wants to merge 1 commit into
jmespath:developfrom
choudhryfrompak:limit-parser-nesting-depth

Conversation

@choudhryfrompak

Copy link
Copy Markdown

_expression() recurses once per nesting level of the parsed expression with no bound. A deeply nested expression (e.g. 50,000 levels of [) drives the interpreter's call stack to its limit and raises a bare RecursionError, not jmespath.exceptions.ParseError or any other member of this library's own exception hierarchy — so a caller following the documented error-handling pattern (catching only JMESPathError around compile()/search()) does not catch it.

Fix: add _MAX_EXPRESSION_DEPTH (100, well above any realistic expression), track depth through the single shared recursive entry point, raise a regular ParseError past that depth instead of recursing further.

4 new regression tests, full existing suite (995 tests, including the upstream JMESPath compliance suite) passes unchanged.

_expression() recurses once per nesting level of the parsed
expression with no bound. A deeply nested expression string
(e.g. 50,000 levels of '[') drives the interpreter's call stack to
its limit and raises a bare RecursionError, not
jmespath.exceptions.ParseError or any other member of this
library's own exception hierarchy - so a caller following the
documented error-handling pattern (catching only JMESPathError
around compile()/search()) does not catch it.

Add _MAX_EXPRESSION_DEPTH (100, well above any realistic
hand-written or generated expression) to Parser, track the current
depth across the single shared recursive entry point (_expression),
and raise a regular ParseError past that depth instead of recursing
further.

Adds 4 regression tests: a too-deep expression raises ParseError and
never leaks a RecursionError, a reasonably nested expression still
parses, and depth correctly resets between separate parse() calls on
the same (possibly cache-reused) Parser instance. Full existing test
suite (995 tests, including the upstream JMESPath compliance suite)
passes unchanged.
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