From 73e4f069becaf69707b990d658b34155f8973508 Mon Sep 17 00:00:00 2001 From: Bouke van der Bijl Date: Fri, 18 Nov 2016 16:17:40 -0500 Subject: Fix nested empty heredoc causing segfault As reported by https://hackerone.com/jpenalbae --- test/t/codegen.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 test/t/codegen.rb (limited to 'test/t/codegen.rb') diff --git a/test/t/codegen.rb b/test/t/codegen.rb new file mode 100644 index 000000000..2f44ca247 --- /dev/null +++ b/test/t/codegen.rb @@ -0,0 +1,10 @@ +## +# Codegen tests + +assert('nested empty heredoc') do + _, a = nil, < Date: Thu, 17 Nov 2016 11:12:35 -0500 Subject: Fix segfault on method call with exactly 127 arguments Reported by https://hackerone.com/dkasak --- mrbgems/mruby-compiler/core/codegen.c | 8 +++++--- test/t/codegen.rb | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 test/t/codegen.rb (limited to 'test/t/codegen.rb') diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 0c84dd558..a36984dea 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -772,6 +772,8 @@ attrsym(codegen_scope *s, mrb_sym a) return mrb_intern(s->mrb, name2, len+1); } +#define CALL_MAXARGS 127 + static int gen_values(codegen_scope *s, node *t, int val) { @@ -780,7 +782,9 @@ gen_values(codegen_scope *s, node *t, int val) while (t) { is_splat = (intptr_t)t->car->car == NODE_SPLAT; /* splat mode */ - if (n >= 127 || is_splat) { + if ( + n >= CALL_MAXARGS - 1 /* need to subtract one because vm.c expects an array if n == CALL_MAXARGS */ + || is_splat) { if (val) { if (is_splat && n == 0 && (intptr_t)t->car->cdr->car == NODE_ARRAY) { codegen(s, t->car->cdr, VAL); @@ -831,8 +835,6 @@ gen_values(codegen_scope *s, node *t, int val) return n; } -#define CALL_MAXARGS 127 - static void gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) { diff --git a/test/t/codegen.rb b/test/t/codegen.rb new file mode 100644 index 000000000..0690cef06 --- /dev/null +++ b/test/t/codegen.rb @@ -0,0 +1,17 @@ +## +# Codegen tests + +assert('method call with exactly 127 arguments') do + def args_to_ary(*args) + args + end + + assert_equal [0]*127, args_to_ary( + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ) +end -- cgit v1.2.3 From 12539825773ddb13fac38091d13341b816ac23fa Mon Sep 17 00:00:00 2001 From: Bouke van der Bijl Date: Mon, 14 Nov 2016 15:07:07 -0500 Subject: Fix codegen issue causing misaligned register Reported by https://hackerone.com/haquaman --- mrbgems/mruby-compiler/core/codegen.c | 2 ++ test/t/codegen.rb | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 test/t/codegen.rb (limited to 'test/t/codegen.rb') diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 0c84dd558..75adbefdd 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -2024,6 +2024,7 @@ codegen(codegen_scope *s, node *tree, int val) } genop(s, MKOP_sBx(OP_JMP, s->loop->pc2 - s->pc)); } + if (val) push(); break; case NODE_RETRY: @@ -2058,6 +2059,7 @@ codegen(codegen_scope *s, node *tree, int val) genop(s, MKOP_sBx(OP_JMP, lp->pc1 - s->pc)); } } + if (val) push(); } break; diff --git a/test/t/codegen.rb b/test/t/codegen.rb new file mode 100644 index 000000000..89ad94bae --- /dev/null +++ b/test/t/codegen.rb @@ -0,0 +1,20 @@ +## +# Codegen tests + +assert('codegen absorbs arguments to redo and retry if they are the argument of a call') do + assert_nothing_raised do + a=*"1", case nil + when 1 + redo | + 1 + end + end + + assert_nothing_raised do + a=*"1", case nil + when 1 + retry | + 1 + end + end +end -- cgit v1.2.3 From 71641bbf732ab8cbadf8a07e20b2a939b0e3b82b Mon Sep 17 00:00:00 2001 From: Bouke van der Bijl Date: Mon, 14 Nov 2016 17:28:18 -0500 Subject: Fix segfault caused by empty condition in ternary Reported by https://hackerone.com/jpenalbae --- mrbgems/mruby-compiler/core/codegen.c | 4 ++++ test/t/codegen.rb | 6 ++++++ 2 files changed, 10 insertions(+) create mode 100644 test/t/codegen.rb (limited to 'test/t/codegen.rb') diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 0c84dd558..71b1dcc6f 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -1362,6 +1362,10 @@ codegen(codegen_scope *s, node *tree, int val) int pos1, pos2; node *e = tree->cdr->cdr->car; + if (!tree->car) { + codegen(s, e, val); + return; + } switch ((intptr_t)tree->car->car) { case NODE_TRUE: case NODE_INT: diff --git a/test/t/codegen.rb b/test/t/codegen.rb new file mode 100644 index 000000000..99d6dbe66 --- /dev/null +++ b/test/t/codegen.rb @@ -0,0 +1,6 @@ +## +# Codegen tests + +assert('empty condition in ternary expression parses correctly') do + assert_equal () ? 1 : 2, 2 +end -- cgit v1.2.3 From 964427f82c5a8556daf4448b47cc65fb6d2a94b8 Mon Sep 17 00:00:00 2001 From: Francis Bogsanyi Date: Thu, 17 Nov 2016 12:59:27 -0500 Subject: Fix unsafe peephole optimization Reported by https://hackerone.com/dkasak --- mrbgems/mruby-compiler/core/codegen.c | 6 ++++-- test/t/codegen.rb | 11 +++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 test/t/codegen.rb (limited to 'test/t/codegen.rb') diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 0c84dd558..39d62348a 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -1798,8 +1798,10 @@ codegen(codegen_scope *s, node *tree, int val) int pos; pop(); - if (val && vsp >= 0) { - genop(s, MKOP_AB(OP_MOVE, vsp, cursp())); + if (val) { + if (vsp >= 0) { + genop(s, MKOP_AB(OP_MOVE, vsp, cursp())); + } pos = genop(s, MKOP_AsBx(name[0]=='|'?OP_JMPIF:OP_JMPNOT, cursp(), 0)); } else { diff --git a/test/t/codegen.rb b/test/t/codegen.rb new file mode 100644 index 000000000..f910d37fb --- /dev/null +++ b/test/t/codegen.rb @@ -0,0 +1,11 @@ +## +# Codegen tests + +assert('peephole optimization does not eliminate move whose result is reused') do + assert_raise LocalJumpError do + def method + yield + end + method(&a &&= 0) + end +end -- cgit v1.2.3 From fe362c1f2649c9c502d9a5998ef8c4c94893f3ea Mon Sep 17 00:00:00 2001 From: Bouke van der Bijl Date: Thu, 24 Nov 2016 13:31:47 -0500 Subject: Fix segfault when using result of rest assignment Reported by https://hackerone.com/haquaman --- mrbgems/mruby-compiler/core/codegen.c | 4 +++- test/t/codegen.rb | 9 +++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'test/t/codegen.rb') diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 553baa116..2c75c8aed 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -1061,7 +1061,9 @@ gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val) n++; } } - push(); + if (!val) { + push(); + } } } diff --git a/test/t/codegen.rb b/test/t/codegen.rb index 1ac689a82..bb0f5c306 100644 --- a/test/t/codegen.rb +++ b/test/t/codegen.rb @@ -54,3 +54,12 @@ A B assert_equal "\n", a end + +assert('splat in case splat') do + a = *case + when 0 + * = 1 + end + + assert_equal [1], a +end -- cgit v1.2.3 From d56a19cbf526190de036130fe3a5bf14a0705ee2 Mon Sep 17 00:00:00 2001 From: Bouke van der Bijl Date: Fri, 2 Dec 2016 09:48:28 -0500 Subject: Don't generate code for NODE_NEGATE if the result isn't used Reported by https://hackerone.com/haquaman --- mrbgems/mruby-compiler/core/codegen.c | 4 ++++ test/t/codegen.rb | 10 ++++++++++ 2 files changed, 14 insertions(+) (limited to 'test/t/codegen.rb') diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index b2cd12225..891c4f62b 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -2223,6 +2223,10 @@ codegen(codegen_scope *s, node *tree, int val) { nt = (intptr_t)tree->car; tree = tree->cdr; + if (!val) { + codegen(s, tree, NOVAL); + break; + } switch (nt) { case NODE_FLOAT: { diff --git a/test/t/codegen.rb b/test/t/codegen.rb index bb0f5c306..bd360dbcb 100644 --- a/test/t/codegen.rb +++ b/test/t/codegen.rb @@ -63,3 +63,13 @@ assert('splat in case splat') do assert_equal [1], a end + +assert('negate literal register alignment') do + a = *case + when 0 + -0.0 + 2 + end + + assert_equal [2], a +end -- cgit v1.2.3 From c8da3c4df4f8cb6f6d00c70e75606c59f9888509 Mon Sep 17 00:00:00 2001 From: Bouke van der Bijl Date: Wed, 7 Dec 2016 11:22:30 -0500 Subject: Fix segfault when undef is called with exactly 127 arguments The issue is that when there are more than 126 arguments an array needs to be created to pass the arguments on with. Reported by https://hackerone.com/revskills --- mrbgems/mruby-compiler/core/codegen.c | 22 ++++++++++++++++++++-- test/t/codegen.rb | 10 ++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) (limited to 'test/t/codegen.rb') diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index b2cd12225..3cfd99d41 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -2560,13 +2560,31 @@ codegen(codegen_scope *s, node *tree, int val) genop(s, MKOP_A(OP_TCLASS, cursp())); push(); while (t) { - int symbol = new_msym(s, sym(t->car)); + int symbol; + if (num >= CALL_MAXARGS - 1) { + pop_n(num); + genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), num)); + while (t) { + symbol = new_msym(s, sym(t->car)); + push(); + genop(s, MKOP_ABx(OP_LOADSYM, cursp(), symbol)); + pop(); + genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1)); + t = t->cdr; + } + num = CALL_MAXARGS; + break; + } + symbol = new_msym(s, sym(t->car)); genop(s, MKOP_ABx(OP_LOADSYM, cursp(), symbol)); push(); t = t->cdr; num++; } - pop_n(num + 1); + pop(); + if (num < CALL_MAXARGS) { + pop_n(num); + } genop(s, MKOP_ABC(OP_SEND, cursp(), undef, num)); if (val) { push(); diff --git a/test/t/codegen.rb b/test/t/codegen.rb index bb0f5c306..3058a7fbc 100644 --- a/test/t/codegen.rb +++ b/test/t/codegen.rb @@ -63,3 +63,13 @@ assert('splat in case splat') do assert_equal [1], a end + +assert('undef with 127 or more arguments') do + assert_raise NameError do + undef + a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, + a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, + a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, + a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a + end +end -- cgit v1.2.3 From 1264219832aeff2630f47d4abb9bee6d013c3e75 Mon Sep 17 00:00:00 2001 From: Bouke van der Bijl Date: Tue, 15 Nov 2016 11:13:38 -0500 Subject: Fix segfault in gen_values with NOVAL and more than 127 args --- mrbgems/mruby-compiler/core/codegen.c | 2 -- test/t/codegen.rb | 8 ++++++++ 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'test/t/codegen.rb') diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 3cfd99d41..99ab4dd97 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -818,8 +818,6 @@ gen_values(codegen_scope *s, node *t, int val) } } else { - codegen(s, t->car->cdr, NOVAL); - t = t->cdr; while (t) { codegen(s, t->car, NOVAL); t = t->cdr; diff --git a/test/t/codegen.rb b/test/t/codegen.rb index 3058a7fbc..528f58d9e 100644 --- a/test/t/codegen.rb +++ b/test/t/codegen.rb @@ -73,3 +73,11 @@ assert('undef with 127 or more arguments') do a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a end end + +assert('next in normal loop with 127 arguments') do + assert_raise NameError do + while true + next A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A + end + end +end -- cgit v1.2.3