diff options
| author | Mike Dalessio <mike.dalessio@gmail.com> | 2023-08-30 13:09:02 -0400 |
|---|---|---|
| committer | git <svn-admin@ruby-lang.org> | 2023-08-30 20:46:09 +0000 |
| commit | 6beaf010a447ce9fb35c85f9fb2f41685e2114ba (patch) | |
| tree | 30fa9a385c566e2c4bfc8c6db59a74670501eac5 | |
| parent | f80582cda8fb0d994db0c1cdf1c282f3a049485c (diff) | |
[ruby/yarp] fix: binary CallNode with out-of-order arg and receiver
The snippet added in this commit previously resulted in a CallNode
with inverted start and end locations:
> AssocNode(15...13)(
> CallNode(15...13)(
StringNode(15...17)((15...16), (16...16), (16...17), ""),
nil,
(12...13),
nil,
ArgumentsNode(12...13)([MissingNode(12...13)()]),
nil,
nil,
0,
"/"
),
MissingNode(13...13)(),
(13...13)
),
which failed an assertion during serialization.
After this change, it looks better:
> AssocNode(12...13)(
> CallNode(12...17)(
StringNode(15...17)((15...16), (16...16), (16...17), ""),
nil,
(12...13),
nil,
ArgumentsNode(12...13)([MissingNode(12...13)()]),
nil,
nil,
0,
"/"
),
MissingNode(13...13)(),
(13...13)
),
Found by the fuzzer.
https://github.com/ruby/yarp/commit/040aa63ad6
| -rw-r--r-- | test/yarp/fuzzer_test.rb | 5 | ||||
| -rw-r--r-- | yarp/yarp.c | 8 |
2 files changed, 11 insertions, 2 deletions
diff --git a/test/yarp/fuzzer_test.rb b/test/yarp/fuzzer_test.rb index d75d1422f0..4d7a0af8e7 100644 --- a/test/yarp/fuzzer_test.rb +++ b/test/yarp/fuzzer_test.rb @@ -28,5 +28,10 @@ module YARP A B EOF + snippet "create a binary call node with arg before receiver", <<~EOF + <<-A.g/{/ + A + /, ""\\ + EOF end end diff --git a/yarp/yarp.c b/yarp/yarp.c index 40d8d3c972..5b8fba9f62 100644 --- a/yarp/yarp.c +++ b/yarp/yarp.c @@ -161,6 +161,10 @@ debug_token(yp_token_t * token) { #endif +/* Macros for min/max. */ +#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MAX(a,b) (((a)>(b))?(a):(b)) + /******************************************************************************/ /* Lex mode manipulations */ /******************************************************************************/ @@ -1240,8 +1244,8 @@ static yp_call_node_t * yp_call_node_binary_create(yp_parser_t *parser, yp_node_t *receiver, yp_token_t *operator, yp_node_t *argument) { yp_call_node_t *node = yp_call_node_create(parser); - node->base.location.start = receiver->location.start; - node->base.location.end = argument->location.end; + node->base.location.start = MIN(receiver->location.start, argument->location.start); + node->base.location.end = MAX(receiver->location.end, argument->location.end); node->receiver = receiver; node->message_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(operator); |
