summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Dalessio <mike.dalessio@gmail.com>2023-08-30 09:59:09 -0400
committergit <svn-admin@ruby-lang.org>2023-08-30 20:46:08 +0000
commitf80582cda8fb0d994db0c1cdf1c282f3a049485c (patch)
tree7a445134b7408a21e57b1f09a425b0ad1d07cb2e
parent209eda599a06682b0d32aa84870038e854fc49ef (diff)
[ruby/yarp] fix: StatementsNode with out-of-order body nodes
The presence of the heredocs in this snippet with invalid syntax: for <<A + <<B A B causes the MissingNode to have a location after other nodes in the list, resulting in a StatementsNode with inverted start and end locations: [ForNode(0...14)( MultiWriteNode(4...7)([InterpolatedStringNode(4...7)((4...7), [], (14...16))], nil, nil, nil, nil), MissingNode(16...16)(), > StatementsNode(16...14)( [MissingNode(16...16)(), InterpolatedStringNode(10...13)((10...13), [], (16...18)), MissingNode(13...14)()] ), (0...3), (16...16), nil, (14...14) )] which failed an assertion during serialization. With this fix, the node's locations are: [ForNode(0...14)( MultiWriteNode(4...7)([InterpolatedStringNode(4...7)((4...7), [], (14...16))], nil, nil, nil, nil), MissingNode(16...16)(), > StatementsNode(10...16)( [MissingNode(16...16)(), InterpolatedStringNode(10...13)((10...13), [], (16...18)), MissingNode(13...14)()] ), (0...3), (16...16), nil, (14...14) )] Found by the fuzzer. https://github.com/ruby/yarp/commit/09bcedc05e
-rw-r--r--test/yarp/fuzzer_test.rb6
-rw-r--r--yarp/yarp.c6
2 files changed, 10 insertions, 2 deletions
diff --git a/test/yarp/fuzzer_test.rb b/test/yarp/fuzzer_test.rb
index 384f3ff0d2..d75d1422f0 100644
--- a/test/yarp/fuzzer_test.rb
+++ b/test/yarp/fuzzer_test.rb
@@ -22,5 +22,11 @@ module YARP
snippet "incomplete escaped list", "%w[\\"
snippet "incomplete escaped regex", "/a\\"
snippet "unterminated heredoc with unterminated escape at end of file", "<<A\n\\"
+
+ snippet "statements node with multiple heredocs", <<~EOF
+ for <<A + <<B
+ A
+ B
+ EOF
end
end
diff --git a/yarp/yarp.c b/yarp/yarp.c
index 6fd16e16fc..40d8d3c972 100644
--- a/yarp/yarp.c
+++ b/yarp/yarp.c
@@ -3908,12 +3908,14 @@ yp_statements_node_location_set(yp_statements_node_t *node, const uint8_t *start
// Append a new node to the given StatementsNode node's body.
static void
yp_statements_node_body_append(yp_statements_node_t *node, yp_node_t *statement) {
- if (yp_statements_node_body_length(node) == 0) {
+ if (yp_statements_node_body_length(node) == 0 || statement->location.start < node->base.location.start) {
node->base.location.start = statement->location.start;
}
+ if (statement->location.end > node->base.location.end) {
+ node->base.location.end = statement->location.end;
+ }
yp_node_list_append(&node->body, statement);
- node->base.location.end = statement->location.end;
// Every statement gets marked as a place where a newline can occur.
statement->flags |= YP_NODE_FLAG_NEWLINE;