summaryrefslogtreecommitdiffhomepage
path: root/src/vm.c
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2017-03-02 17:55:15 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2017-03-02 17:55:15 +0900
commit27ec2437fd240b10d0745256e813000b3d5d359a (patch)
tree2983652c770f4dafde24f1b7355e4245880a1fd2 /src/vm.c
parent0bcf9e28fc6b41f75e78557295decfdcdb947b7a (diff)
downloadmruby-27ec2437fd240b10d0745256e813000b3d5d359a.tar.gz
mruby-27ec2437fd240b10d0745256e813000b3d5d359a.zip
Fix possible stack overflow for `method_missing`; fix #3478
Instead of shifting mruby VM stack, we always use CALL_MAXARGS.
Diffstat (limited to 'src/vm.c')
-rw-r--r--src/vm.c16
1 files changed, 5 insertions, 11 deletions
diff --git a/src/vm.c b/src/vm.c
index c05afca9d..8c9a021aa 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -1188,19 +1188,13 @@ RETRY_TRY_BLOCK:
mrb_method_missing(mrb, mid, recv, args);
}
mid = missing;
- if (n == CALL_MAXARGS-1) {
+ if (n != CALL_MAXARGS) {
+ mrb_value blk = regs[bidx];
regs[a+1] = mrb_ary_new_from_values(mrb, n, regs+a+1);
- SET_NIL_VALUE(regs[bidx]);
- n++;
- }
- if (n == CALL_MAXARGS) {
- mrb_ary_unshift(mrb, regs[a+1], sym);
- }
- else {
- value_move(regs+a+2, regs+a+1, n+1);
- regs[a+1] = sym;
- n++;
+ regs[a+2] = blk;
+ n = CALL_MAXARGS;
}
+ mrb_ary_unshift(mrb, regs[a+1], sym);
}
/* push callinfo */