summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-11-06 00:01:29 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-11-06 00:01:29 +0000
commitdfa75017bea479c829db9f967509caa95411361e (patch)
treeec92ef61307c6e3ed12bd1ce8c6f47647843c8be
parent9a0802a3bf9ca9af35e22c5609760863b853ae7d (diff)
parse.y: fix segv after invalid keyword argument
* parse.y (kwd_append): fix segv after invalid keyword argument, preceding keyword list is NULL when syntax error is there. [ruby-core:71356] [Bug #11663] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52461 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog6
-rw-r--r--parse.y34
-rw-r--r--test/ruby/test_syntax.rb10
3 files changed, 36 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog
index b6ef3b1420..e55bc5951c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Fri Nov 6 09:01:26 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * parse.y (kwd_append): fix segv after invalid keyword argument,
+ preceding keyword list is NULL when syntax error is there.
+ [ruby-core:71356] [Bug #11663]
+
Fri Nov 6 06:59:37 2015 Eric Wong <e@80x24.org>
* test/ruby/test_autoload: hoist out ruby_impl_require
diff --git a/parse.y b/parse.y
index c205ac4854..e42526a3b8 100644
--- a/parse.y
+++ b/parse.y
@@ -466,6 +466,8 @@ static NODE *new_attr_op_assign_gen(struct parser_params *parser, NODE *lhs, ID
static NODE *new_const_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs);
#define new_const_op_assign(lhs, op, rhs) new_const_op_assign_gen(parser, (lhs), (op), (rhs))
+static NODE *kwd_append(NODE*, NODE*);
+
static NODE *new_hash_gen(struct parser_params *parser, NODE *hash);
#define new_hash(hash) new_hash_gen(parser, (hash))
@@ -4779,13 +4781,7 @@ f_block_kwarg : f_block_kw
| f_block_kwarg ',' f_block_kw
{
/*%%%*/
- NODE *kws = $1;
-
- while (kws->nd_next) {
- kws = kws->nd_next;
- }
- kws->nd_next = $3;
- $$ = $1;
+ $$ = kwd_append($1, $3);
/*%
$$ = rb_ary_push($1, $3);
%*/
@@ -4804,13 +4800,7 @@ f_kwarg : f_kw
| f_kwarg ',' f_kw
{
/*%%%*/
- NODE *kws = $1;
-
- while (kws->nd_next) {
- kws = kws->nd_next;
- }
- kws->nd_next = $3;
- $$ = $1;
+ $$ = kwd_append($1, $3);
/*%
$$ = rb_ary_push($1, $3);
%*/
@@ -6805,6 +6795,9 @@ formal_argument_gen(struct parser_params *parser, ID lhs)
case ID_CLASS:
yyerror("formal argument cannot be a class variable");
return 0;
+ default:
+ yyerror("formal argument must be local variable");
+ return 0;
#else
default:
lhs = dispatch1(param_error, lhs);
@@ -9018,6 +9011,19 @@ gettable_gen(struct parser_params *parser, ID id)
compile_error(PARSER_ARG "identifier %"PRIsVALUE" is not valid to get", rb_id2str(id));
return 0;
}
+
+static NODE *
+kwd_append(NODE *kwlist, NODE *kw)
+{
+ if (kwlist) {
+ NODE *kws = kwlist;
+ while (kws->nd_next) {
+ kws = kws->nd_next;
+ }
+ kws->nd_next = kw;
+ }
+ return kwlist;
+}
#else /* !RIPPER */
static int
id_is_var_gen(struct parser_params *parser, ID id)
diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb
index 552cf5cd00..1f76425cad 100644
--- a/test/ruby/test_syntax.rb
+++ b/test/ruby/test_syntax.rb
@@ -193,6 +193,16 @@ class TestSyntax < Test::Unit::TestCase
end
end
+ def test_keyword_invalid_name
+ bug11663 = '[ruby-core:71356] [Bug #11663]'
+
+ o = Object.new
+ assert_syntax_error('def o.foo(arg1?:) end', /arg1\?/, bug11663)
+ assert_syntax_error('def o.foo(arg1?:, arg2:) end', /arg1\?/, bug11663)
+ assert_syntax_error('proc {|arg1?:|}', /arg1\?/, bug11663)
+ assert_syntax_error('proc {|arg1?:, arg2:|}', /arg1\?/, bug11663)
+ end
+
def test_optional_self_reference
bug9593 = '[ruby-core:61299] [Bug #9593]'
o = Object.new