1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

ripper: fix bad label parameter handling [Bug #17425]

This commit is contained in:
Nobuyoshi Nakada 2020-12-22 22:41:54 +09:00
parent cd63f0358f
commit 733ed1e184
Notes: git 2020-12-23 09:57:00 +09:00
2 changed files with 28 additions and 20 deletions

17
parse.y
View file

@ -654,7 +654,11 @@ RUBY_SYMBOL_EXPORT_END
static void error_duplicate_pattern_variable(struct parser_params *p, ID id, const YYLTYPE *loc);
static void error_duplicate_pattern_key(struct parser_params *p, ID id, const YYLTYPE *loc);
static void parser_token_value_print(struct parser_params *p, enum yytokentype type, const YYSTYPE *valp);
#ifndef RIPPER
static ID formal_argument(struct parser_params*, ID);
#else
static ID formal_argument(struct parser_params*, VALUE);
#endif
static ID shadowing_lvar(struct parser_params*,ID);
static void new_bv(struct parser_params*,ID);
@ -5187,7 +5191,7 @@ f_bad_arg : tCONSTANT
f_norm_arg : f_bad_arg
| tIDENTIFIER
{
formal_argument(p, get_id($1));
formal_argument(p, $1);
p->max_numparam = ORDINAL_PARAM;
$$ = $1;
}
@ -5248,9 +5252,8 @@ f_arg : f_arg_item
f_label : tLABEL
{
ID id = get_id($1);
arg_var(p, formal_argument(p, id));
p->cur_arg = id;
arg_var(p, formal_argument(p, $1));
p->cur_arg = get_id($1);
p->max_numparam = ORDINAL_PARAM;
$$ = $1;
}
@ -7855,9 +7858,13 @@ arg_ambiguous(struct parser_params *p, char c)
}
static ID
#ifndef RIPPER
formal_argument(struct parser_params *p, ID lhs)
#else
formal_argument(struct parser_params *p, VALUE lhs)
#endif
{
switch (id_type(lhs)) {
switch (id_type(get_id(lhs))) {
case ID_LOCAL:
break;
#ifndef RIPPER

View file

@ -146,18 +146,19 @@ class TestRipper::Lexer < Test::Unit::TestCase
assert_equal [[1, 17], :on_embexpr_end, "}", state(:EXPR_ARG)], token
end
BAD_CODE = {
parse_error: ['def req(true) end', %r[unexpected `true'], 'true'],
assign_error: ['begin; nil = 1; end', %r[assign to nil], 'nil'],
alias_error: ['begin; alias $x $1; end', %r[number variables], '$1'],
class_name_error: ['class bad; end', %r[class/module name], 'bad'],
param_error: ['def req(@a) end', %r[formal argument.*instance], '@a'],
}
BAD_CODE = [
[:parse_error, 'def req(true) end', %r[unexpected `true'], 'true'],
[:assign_error, 'begin; nil = 1; end', %r[assign to nil], 'nil'],
[:alias_error, 'begin; alias $x $1; end', %r[number variables], '$1'],
[:class_name_error, 'class bad; end', %r[class/module name], 'bad'],
[:param_error, 'def req(@a) end', %r[formal argument.*instance], '@a'],
[:param_error, 'def req(a?:) end', %r[formal argument must.*local], 'a?'],
]
def test_raise_errors_keyword
all_assertions do |all|
BAD_CODE.each do |err, (code, message)|
all.for(err) do
BAD_CODE.each do |(err, code, message)|
all.for([err, code]) do
assert_raise_with_message(SyntaxError, message) { Ripper.tokenize(code, raise_errors: true) }
end
end
@ -166,8 +167,8 @@ class TestRipper::Lexer < Test::Unit::TestCase
def test_tokenize_with_syntax_error
all_assertions do |all|
BAD_CODE.each do |err, (code)|
all.for(err) do
BAD_CODE.each do |(err, code)|
all.for([err, code]) do
assert_equal "end", Ripper.tokenize(code).last
end
end
@ -176,8 +177,8 @@ class TestRipper::Lexer < Test::Unit::TestCase
def test_lex_with_syntax_error
all_assertions do |all|
BAD_CODE.each do |err, (code)|
all.for(err) do
BAD_CODE.each do |(err, code)|
all.for([err, code]) do
assert_equal [[1, code.size-3], :on_kw, "end", state(:EXPR_END)], Ripper.lex(code).last
end
end
@ -186,8 +187,8 @@ class TestRipper::Lexer < Test::Unit::TestCase
def test_lexer_scan_with_syntax_error
all_assertions do |all|
BAD_CODE.each do |err, (code, message, token)|
all.for(err) do
BAD_CODE.each do |(err, code, message, token)|
all.for([err, code]) do
lexer = Ripper::Lexer.new(code)
elems = lexer.scan
assert_predicate lexer, :error?