Skip to content

Commit 2723b10

Browse files
committed
Merge pull request mruby#3090 from kou/fix-segv-by-stack-extension-in-mrb-get-args
Fix SEGV by stack extension in mrb_get_args()
2 parents 8a74e68 + c77123d commit 2723b10

1 file changed

Lines changed: 45 additions & 35 deletions

File tree

src/class.c

Lines changed: 45 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -466,9 +466,10 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
466466
{
467467
char c;
468468
int i = 0;
469-
mrb_value *sp = mrb->c->stack + 1;
470469
va_list ap;
471470
int argc = mrb->c->ci->argc;
471+
int arg_i = 0;
472+
mrb_bool array_argv;
472473
mrb_bool opt = FALSE;
473474
mrb_bool given = TRUE;
474475

@@ -477,8 +478,14 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
477478
struct RArray *a = mrb_ary_ptr(mrb->c->stack[1]);
478479

479480
argc = a->len;
480-
sp = a->ptr;
481+
array_argv = TRUE;
482+
} else {
483+
array_argv = FALSE;
481484
}
485+
486+
#define ARGV \
487+
(array_argv ? mrb_ary_ptr(mrb->c->stack[1])->ptr : (mrb->c->stack + 1))
488+
482489
while ((c = *format++)) {
483490
switch (c) {
484491
case '|': case '*': case '&': case '?':
@@ -502,7 +509,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
502509

503510
p = va_arg(ap, mrb_value*);
504511
if (i < argc) {
505-
*p = *sp++;
512+
*p = ARGV[arg_i++];
506513
i++;
507514
}
508515
}
@@ -515,7 +522,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
515522
if (i < argc) {
516523
mrb_value ss;
517524

518-
ss = *sp++;
525+
ss = ARGV[arg_i++];
519526
switch (mrb_type(ss)) {
520527
case MRB_TT_CLASS:
521528
case MRB_TT_MODULE:
@@ -537,14 +544,14 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
537544
p = va_arg(ap, mrb_value*);
538545
if (*format == '!') {
539546
format++;
540-
if (i < argc && mrb_nil_p(*sp)) {
541-
*p = *sp++;
547+
if (i < argc && mrb_nil_p(ARGV[arg_i])) {
548+
*p = ARGV[arg_i++];
542549
i++;
543550
break;
544551
}
545552
}
546553
if (i < argc) {
547-
*p = to_str(mrb, *sp++);
554+
*p = to_str(mrb, ARGV[arg_i++]);
548555
i++;
549556
}
550557
}
@@ -556,14 +563,14 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
556563
p = va_arg(ap, mrb_value*);
557564
if (*format == '!') {
558565
format++;
559-
if (i < argc && mrb_nil_p(*sp)) {
560-
*p = *sp++;
566+
if (i < argc && mrb_nil_p(ARGV[arg_i])) {
567+
*p = ARGV[arg_i++];
561568
i++;
562569
break;
563570
}
564571
}
565572
if (i < argc) {
566-
*p = to_ary(mrb, *sp++);
573+
*p = to_ary(mrb, ARGV[arg_i++]);
567574
i++;
568575
}
569576
}
@@ -575,14 +582,14 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
575582
p = va_arg(ap, mrb_value*);
576583
if (*format == '!') {
577584
format++;
578-
if (i < argc && mrb_nil_p(*sp)) {
579-
*p = *sp++;
585+
if (i < argc && mrb_nil_p(ARGV[arg_i])) {
586+
*p = ARGV[arg_i++];
580587
i++;
581588
break;
582589
}
583590
}
584591
if (i < argc) {
585-
*p = to_hash(mrb, *sp++);
592+
*p = to_hash(mrb, ARGV[arg_i++]);
586593
i++;
587594
}
588595
}
@@ -597,15 +604,15 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
597604
pl = va_arg(ap, mrb_int*);
598605
if (*format == '!') {
599606
format++;
600-
if (i < argc && mrb_nil_p(*sp)) {
607+
if (i < argc && mrb_nil_p(ARGV[arg_i])) {
601608
*ps = NULL;
602609
*pl = 0;
603610
i++;
604611
break;
605612
}
606613
}
607614
if (i < argc) {
608-
ss = to_str(mrb, *sp++);
615+
ss = to_str(mrb, ARGV[arg_i++]);
609616
*ps = RSTRING_PTR(ss);
610617
*pl = RSTRING_LEN(ss);
611618
i++;
@@ -620,14 +627,14 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
620627
ps = va_arg(ap, const char**);
621628
if (*format == '!') {
622629
format++;
623-
if (i < argc && mrb_nil_p(*sp)) {
630+
if (i < argc && mrb_nil_p(ARGV[arg_i])) {
624631
*ps = NULL;
625-
i++; sp++;
632+
i++; arg_i++;
626633
break;
627634
}
628635
}
629636
if (i < argc) {
630-
ss = to_str(mrb, *sp++);
637+
ss = to_str(mrb, ARGV[arg_i++]);
631638
*ps = mrb_string_value_cstr(mrb, &ss);
632639
i++;
633640
}
@@ -644,15 +651,15 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
644651
pl = va_arg(ap, mrb_int*);
645652
if (*format == '!') {
646653
format++;
647-
if (i < argc && mrb_nil_p(*sp)) {
654+
if (i < argc && mrb_nil_p(ARGV[arg_i])) {
648655
*pb = 0;
649656
*pl = 0;
650-
i++; sp++;
657+
i++; arg_i++;
651658
break;
652659
}
653660
}
654661
if (i < argc) {
655-
aa = to_ary(mrb, *sp++);
662+
aa = to_ary(mrb, ARGV[arg_i++]);
656663
a = mrb_ary_ptr(aa);
657664
*pb = a->ptr;
658665
*pl = a->len;
@@ -666,8 +673,8 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
666673

667674
p = va_arg(ap, mrb_float*);
668675
if (i < argc) {
669-
*p = mrb_to_flo(mrb, *sp);
670-
sp++;
676+
*p = mrb_to_flo(mrb, ARGV[arg_i]);
677+
arg_i++;
671678
i++;
672679
}
673680
}
@@ -678,13 +685,13 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
678685

679686
p = va_arg(ap, mrb_int*);
680687
if (i < argc) {
681-
switch (mrb_type(*sp)) {
688+
switch (mrb_type(ARGV[arg_i])) {
682689
case MRB_TT_FIXNUM:
683-
*p = mrb_fixnum(*sp);
690+
*p = mrb_fixnum(ARGV[arg_i]);
684691
break;
685692
case MRB_TT_FLOAT:
686693
{
687-
mrb_float f = mrb_float(*sp);
694+
mrb_float f = mrb_float(ARGV[arg_i]);
688695

689696
if (!FIXABLE(f)) {
690697
mrb_raise(mrb, E_RANGE_ERROR, "float too big for int");
@@ -696,10 +703,10 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
696703
mrb_raise(mrb, E_TYPE_ERROR, "no implicit conversion of String into Integer");
697704
break;
698705
default:
699-
*p = mrb_fixnum(mrb_Integer(mrb, *sp));
706+
*p = mrb_fixnum(mrb_Integer(mrb, ARGV[arg_i]));
700707
break;
701708
}
702-
sp++;
709+
arg_i++;
703710
i++;
704711
}
705712
}
@@ -709,7 +716,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
709716
mrb_bool *boolp = va_arg(ap, mrb_bool*);
710717

711718
if (i < argc) {
712-
mrb_value b = *sp++;
719+
mrb_value b = ARGV[arg_i++];
713720
*boolp = mrb_test(b);
714721
i++;
715722
}
@@ -723,7 +730,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
723730
if (i < argc) {
724731
mrb_value ss;
725732

726-
ss = *sp++;
733+
ss = ARGV[arg_i++];
727734
*symp = to_sym(mrb, ss);
728735
i++;
729736
}
@@ -738,14 +745,14 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
738745
type = va_arg(ap, struct mrb_data_type const*);
739746
if (*format == '!') {
740747
format++;
741-
if (i < argc && mrb_nil_p(*sp)) {
748+
if (i < argc && mrb_nil_p(ARGV[arg_i])) {
742749
*datap = 0;
743-
i++; sp++;
750+
i++; arg_i++;
744751
break;
745752
}
746753
}
747754
if (i < argc) {
748-
*datap = mrb_data_get_ptr(mrb, *sp++, type);
755+
*datap = mrb_data_get_ptr(mrb, ARGV[arg_i++], type);
749756
++i;
750757
}
751758
}
@@ -787,10 +794,10 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
787794
if (argc > i) {
788795
*pl = argc-i;
789796
if (*pl > 0) {
790-
*var = sp;
797+
*var = ARGV + arg_i;
791798
}
792799
i = argc;
793-
sp += *pl;
800+
arg_i += *pl;
794801
}
795802
else {
796803
*pl = 0;
@@ -803,6 +810,9 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
803810
break;
804811
}
805812
}
813+
814+
#undef ARGV
815+
806816
if (!c && argc > i) {
807817
mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
808818
}

0 commit comments

Comments
 (0)