fix(builtin): limit recursion depth #870
Merged
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.
Motivation
The builtin functions
flatten,min,max,mean, andmedianrecursively traverse nested arrays. If the environment provides a deeply nested structure or one containing a cycle (e.g., a slice containing itself), these functions would recurse indefinitely until the Go runtime panics due to stack overflow. This panic is unrecoverable and crashes the host application, presenting a DoS risk.Changes
The
builtinpackage now has aMaxDepthinteger (defaults to 10k).These recursive helper functions now accept a
depthargument. This is incremented on recursive calls, and errors propagate up the stack if limit is exceeded. Initial function definitions call the helpers with an initial depth of 0 and handle returned errors.Tests
Added various tests for the affected builtin functions using self-referencing slices. Also a test about customising the MaxDepth for users who rely on expr-lang as a library, and need more or less depth.