Fix segfault when using Generator.map with PonyCheck shrinking#5006
Open
SeanTAllen wants to merge 1 commit intomainfrom
Open
Fix segfault when using Generator.map with PonyCheck shrinking#5006SeanTAllen wants to merge 1 commit intomainfrom
SeanTAllen wants to merge 1 commit intomainfrom
Conversation
When a lambda is nested inside an object literal inside a generic method, collect_type_params copies type parameters twice, producing an ast_data chain of length > 1 (copy'' → copy' → original). reify_typeparamref followed this chain only one level, so the doubly-copied type params never matched. This caused the lambda's apply method to not be marked as reachable during codegen, leaving a hole in the vtable and segfaulting at runtime. The fix follows the ast_data chain to the root (the self-referential node set during the scope pass) for both sides of the comparison, handling any depth of nesting. The same single-level ast_data pattern existed in reify_reference. While investigation showed that code path is not currently reachable in the nested lambda scenario (TK_REFERENCE nodes are resolved by the refer pass before any reify call encounters them), the pattern is structurally vulnerable. Applied the same chain-following fix defensively, guarded by a TK_TYPEPARAM check on ref_def since scope lookup can return other node types. Closes #4838 Closes #5005
2007d9b to
5c4a9aa
Compare
Member
Author
|
Hit this in ponylang/corral while writing property-based tests for a DEFLATE BitReader. The test used Original property test that segfaults on ponyc 0.62.0: use "pony_check"
use "pony_test"
class _PropertyBitReaderSplit is Property1[Array[U8] val]
fun name(): String => "inflate/property/bit-reader-split"
fun gen(): Generator[Array[U8] val] =>
Generators.map2[U8, U8, Array[U8] val](
Generators.u8(),
Generators.u8(),
{(a, b) => recover val
let arr = Array[U8](4)
arr.push(a)
arr.push(b)
arr.push(a xor b)
arr.push(a + b)
arr
end })
fun property(sample: Array[U8] val, h: PropertyHelper) =>
if sample.size() < 4 then return end
// ... reads bits from sample, no assertions that would fail ...Worked around by converting to a manual |
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.
When a lambda is nested inside an object literal inside a generic method,
collect_type_paramscopies type parameters twice, producing anast_datachain of length > 1.reify_typeparamreffollowed this chain only one level, so the doubly-copied type params never matched. This caused the lambda'sapplymethod to not be marked as reachable during codegen, leaving a hole in the vtable and segfaulting at runtime.The fix follows the
ast_datachain to the root (the self-referential node set during the scope pass) for both sides of the comparison, handling any depth of nesting.The same single-level pattern in
reify_referenceis fixed defensively — investigation showed that code path is not currently reachable in the nested lambda scenario, but the pattern is structurally vulnerable.Closes #4838
Closes #5005