ripper: fix bad label parameter handling [Bug #17425]
This commit is contained in:
parent
cd63f0358f
commit
733ed1e184
Notes:
git
2020-12-23 09:57:00 +09:00
17
parse.y
17
parse.y
@ -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_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 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);
|
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);
|
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 ID shadowing_lvar(struct parser_params*,ID);
|
||||||
static void new_bv(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
|
f_norm_arg : f_bad_arg
|
||||||
| tIDENTIFIER
|
| tIDENTIFIER
|
||||||
{
|
{
|
||||||
formal_argument(p, get_id($1));
|
formal_argument(p, $1);
|
||||||
p->max_numparam = ORDINAL_PARAM;
|
p->max_numparam = ORDINAL_PARAM;
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
@ -5248,9 +5252,8 @@ f_arg : f_arg_item
|
|||||||
|
|
||||||
f_label : tLABEL
|
f_label : tLABEL
|
||||||
{
|
{
|
||||||
ID id = get_id($1);
|
arg_var(p, formal_argument(p, $1));
|
||||||
arg_var(p, formal_argument(p, id));
|
p->cur_arg = get_id($1);
|
||||||
p->cur_arg = id;
|
|
||||||
p->max_numparam = ORDINAL_PARAM;
|
p->max_numparam = ORDINAL_PARAM;
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
@ -7855,9 +7858,13 @@ arg_ambiguous(struct parser_params *p, char c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static ID
|
static ID
|
||||||
|
#ifndef RIPPER
|
||||||
formal_argument(struct parser_params *p, ID lhs)
|
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:
|
case ID_LOCAL:
|
||||||
break;
|
break;
|
||||||
#ifndef RIPPER
|
#ifndef RIPPER
|
||||||
|
@ -146,18 +146,19 @@ class TestRipper::Lexer < Test::Unit::TestCase
|
|||||||
assert_equal [[1, 17], :on_embexpr_end, "}", state(:EXPR_ARG)], token
|
assert_equal [[1, 17], :on_embexpr_end, "}", state(:EXPR_ARG)], token
|
||||||
end
|
end
|
||||||
|
|
||||||
BAD_CODE = {
|
BAD_CODE = [
|
||||||
parse_error: ['def req(true) end', %r[unexpected `true'], 'true'],
|
[:parse_error, 'def req(true) end', %r[unexpected `true'], 'true'],
|
||||||
assign_error: ['begin; nil = 1; end', %r[assign to nil], 'nil'],
|
[:assign_error, 'begin; nil = 1; end', %r[assign to nil], 'nil'],
|
||||||
alias_error: ['begin; alias $x $1; end', %r[number variables], '$1'],
|
[:alias_error, 'begin; alias $x $1; end', %r[number variables], '$1'],
|
||||||
class_name_error: ['class bad; end', %r[class/module name], 'bad'],
|
[: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.*instance], '@a'],
|
||||||
}
|
[:param_error, 'def req(a?:) end', %r[formal argument must.*local], 'a?'],
|
||||||
|
]
|
||||||
|
|
||||||
def test_raise_errors_keyword
|
def test_raise_errors_keyword
|
||||||
all_assertions do |all|
|
all_assertions do |all|
|
||||||
BAD_CODE.each do |err, (code, message)|
|
BAD_CODE.each do |(err, code, message)|
|
||||||
all.for(err) do
|
all.for([err, code]) do
|
||||||
assert_raise_with_message(SyntaxError, message) { Ripper.tokenize(code, raise_errors: true) }
|
assert_raise_with_message(SyntaxError, message) { Ripper.tokenize(code, raise_errors: true) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -166,8 +167,8 @@ class TestRipper::Lexer < Test::Unit::TestCase
|
|||||||
|
|
||||||
def test_tokenize_with_syntax_error
|
def test_tokenize_with_syntax_error
|
||||||
all_assertions do |all|
|
all_assertions do |all|
|
||||||
BAD_CODE.each do |err, (code)|
|
BAD_CODE.each do |(err, code)|
|
||||||
all.for(err) do
|
all.for([err, code]) do
|
||||||
assert_equal "end", Ripper.tokenize(code).last
|
assert_equal "end", Ripper.tokenize(code).last
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -176,8 +177,8 @@ class TestRipper::Lexer < Test::Unit::TestCase
|
|||||||
|
|
||||||
def test_lex_with_syntax_error
|
def test_lex_with_syntax_error
|
||||||
all_assertions do |all|
|
all_assertions do |all|
|
||||||
BAD_CODE.each do |err, (code)|
|
BAD_CODE.each do |(err, code)|
|
||||||
all.for(err) do
|
all.for([err, code]) do
|
||||||
assert_equal [[1, code.size-3], :on_kw, "end", state(:EXPR_END)], Ripper.lex(code).last
|
assert_equal [[1, code.size-3], :on_kw, "end", state(:EXPR_END)], Ripper.lex(code).last
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -186,8 +187,8 @@ class TestRipper::Lexer < Test::Unit::TestCase
|
|||||||
|
|
||||||
def test_lexer_scan_with_syntax_error
|
def test_lexer_scan_with_syntax_error
|
||||||
all_assertions do |all|
|
all_assertions do |all|
|
||||||
BAD_CODE.each do |err, (code, message, token)|
|
BAD_CODE.each do |(err, code, message, token)|
|
||||||
all.for(err) do
|
all.for([err, code]) do
|
||||||
lexer = Ripper::Lexer.new(code)
|
lexer = Ripper::Lexer.new(code)
|
||||||
elems = lexer.scan
|
elems = lexer.scan
|
||||||
assert_predicate lexer, :error?
|
assert_predicate lexer, :error?
|
||||||
|
Loading…
x
Reference in New Issue
Block a user