From e9b1d9dc2f1de290da4aadfd39f1957502d67e18 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 17 Sep 2018 23:52:14 +0900 Subject: Array size may be changed in `mrb_get_args()` reentry. fix #4116; fix #4117; fix #4118; fix #4119; fix #4120 --- mrbgems/mruby-array-ext/src/array.c | 5 +++-- src/array.c | 22 ++++++++++++++-------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/mrbgems/mruby-array-ext/src/array.c b/mrbgems/mruby-array-ext/src/array.c index 169f968f9..792eb26de 100644 --- a/mrbgems/mruby-array-ext/src/array.c +++ b/mrbgems/mruby-array-ext/src/array.c @@ -175,7 +175,7 @@ static mrb_value mrb_ary_slice_bang(mrb_state *mrb, mrb_value self) { struct RArray *a = mrb_ary_ptr(self); - mrb_int i, j, k, len, alen = ARY_LEN(a); + mrb_int i, j, k, len, alen; mrb_value val; mrb_value *ptr; mrb_value ary; @@ -188,7 +188,7 @@ mrb_ary_slice_bang(mrb_state *mrb, mrb_value self) mrb_get_args(mrb, "o|i", &index, &len); switch (mrb_type(index)) { case MRB_TT_RANGE: - if (mrb_range_beg_len(mrb, index, &i, &len, alen, TRUE) == 1) { + if (mrb_range_beg_len(mrb, index, &i, &len, ARY_LEN(a), TRUE) == 1) { goto delete_pos_len; } else { @@ -205,6 +205,7 @@ mrb_ary_slice_bang(mrb_state *mrb, mrb_value self) mrb_get_args(mrb, "ii", &i, &len); delete_pos_len: + alen = ARY_LEN(a); if (i < 0) i += alen; if (i < 0 || alen < i) return mrb_nil_value(); if (len < 0) return mrb_nil_value(); diff --git a/src/array.c b/src/array.c index f0c32bc7f..0b039a6ec 100644 --- a/src/array.c +++ b/src/array.c @@ -853,14 +853,14 @@ static mrb_value mrb_ary_aget(mrb_state *mrb, mrb_value self) { struct RArray *a = mrb_ary_ptr(self); - mrb_int i, len, alen = ARY_LEN(a); + mrb_int i, len, alen; mrb_value index; if (mrb_get_args(mrb, "o|i", &index, &len) == 1) { switch (mrb_type(index)) { /* a[n..m] */ case MRB_TT_RANGE: - if (mrb_range_beg_len(mrb, index, &i, &len, alen, TRUE) == 1) { + if (mrb_range_beg_len(mrb, index, &i, &len, ARY_LEN(a), TRUE) == 1) { return ary_subseq(mrb, a, i, len); } else { @@ -874,6 +874,7 @@ mrb_ary_aget(mrb_state *mrb, mrb_value self) } i = aget_index(mrb, index); + alen = ARY_LEN(a); if (i < 0) i += alen; if (i < 0 || alen < i) return mrb_nil_value(); if (len < 0) return mrb_nil_value(); @@ -953,9 +954,10 @@ mrb_ary_delete_at(mrb_state *mrb, mrb_value self) mrb_int index; mrb_value val; mrb_value *ptr; - mrb_int len, alen = ARY_LEN(a); + mrb_int len, alen; mrb_get_args(mrb, "i", &index); + alen = ARY_LEN(a); if (index < 0) index += alen; if (index < 0 || alen <= index) return mrb_nil_value(); @@ -980,16 +982,17 @@ static mrb_value mrb_ary_first(mrb_state *mrb, mrb_value self) { struct RArray *a = mrb_ary_ptr(self); - mrb_int size, alen = ARY_LEN(a); + mrb_int size, alen; if (mrb_get_argc(mrb) == 0) { - return (alen > 0)? ARY_PTR(a)[0]: mrb_nil_value(); + return (ARY_LEN(a) > 0)? ARY_PTR(a)[0]: mrb_nil_value(); } mrb_get_args(mrb, "|i", &size); if (size < 0) { mrb_raise(mrb, E_ARGUMENT_ERROR, "negative array size"); } + alen = ARY_LEN(a); if (size > alen) size = alen; if (ARY_SHARED_P(a)) { return ary_subseq(mrb, a, 0, size); @@ -1001,10 +1004,13 @@ static mrb_value mrb_ary_last(mrb_state *mrb, mrb_value self) { struct RArray *a = mrb_ary_ptr(self); - mrb_int size, alen = ARY_LEN(a); + mrb_int n, size, alen; - if (mrb_get_args(mrb, "|i", &size) == 0) - return (alen > 0)? ARY_PTR(a)[alen - 1]: mrb_nil_value(); + n = mrb_get_args(mrb, "|i", &size); + alen = ARY_LEN(a); + if (n == 0) { + return (alen > 0) ? ARY_PTR(a)[alen - 1]: mrb_nil_value(); + } if (size < 0) { mrb_raise(mrb, E_ARGUMENT_ERROR, "negative array size"); -- cgit v1.2.3