summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2016-11-16 01:29:04 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2016-11-16 01:29:04 +0900
commit739dad6e87e91c74cda794ae3f33cd94a7c33eb1 (patch)
tree04efbd14bcc5463fc2a8f7975f2ef9623715f954
parent4f6cce059b317f7e6c1da801fe0edd487985df6e (diff)
downloadmruby-739dad6e87e91c74cda794ae3f33cd94a7c33eb1.tar.gz
mruby-739dad6e87e91c74cda794ae3f33cd94a7c33eb1.zip
Fixed a memory problem in Array#to_h
Reported from Alex Snaps via Mathieu Leduc-Hamel, both from shopify.com. Thank you!
-rw-r--r--include/mruby/array.h9
-rw-r--r--mrbgems/mruby-array-ext/src/array.c2
-rw-r--r--mrbgems/mruby-array-ext/test/array.rb11
-rw-r--r--src/array.c9
4 files changed, 21 insertions, 10 deletions
diff --git a/include/mruby/array.h b/include/mruby/array.h
index bd78db066..8f9d5d502 100644
--- a/include/mruby/array.h
+++ b/include/mruby/array.h
@@ -134,6 +134,15 @@ mrb_ary_len(mrb_state *mrb, mrb_value ary)
return RARRAY_LEN(ary);
}
+static inline mrb_value
+ary_elt(mrb_value ary, mrb_int offset)
+{
+ if (offset < 0 || RARRAY_LEN(ary) <= offset) {
+ return mrb_nil_value();
+ }
+ return RARRAY_PTR(ary)[offset];
+}
+
MRB_END_DECL
#endif /* MRUBY_ARRAY_H */
diff --git a/mrbgems/mruby-array-ext/src/array.c b/mrbgems/mruby-array-ext/src/array.c
index d5c96e2cc..af947303b 100644
--- a/mrbgems/mruby-array-ext/src/array.c
+++ b/mrbgems/mruby-array-ext/src/array.c
@@ -131,7 +131,7 @@ mrb_ary_to_h(mrb_state *mrb, mrb_value ary)
if (mrb_nil_p(v)) {
mrb_raisef(mrb, E_TYPE_ERROR, "wrong element type %S at %S (expected array)",
- mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, RARRAY_PTR(ary)[i])),
+ mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, ary_elt(ary, i))),
mrb_fixnum_value(i)
);
}
diff --git a/mrbgems/mruby-array-ext/test/array.rb b/mrbgems/mruby-array-ext/test/array.rb
index ec1528fc3..09ec8d9e7 100644
--- a/mrbgems/mruby-array-ext/test/array.rb
+++ b/mrbgems/mruby-array-ext/test/array.rb
@@ -301,6 +301,17 @@ assert('Array#to_h') do
assert_raise(ArgumentError) { [[1]].to_h }
end
+assert('Array#to_h (Modified)') do
+ class A
+ def to_ary
+ $a.clear
+ nil
+ end
+ end
+ $a = [A.new]
+ assert_raise(TypeError) { $a.to_h }
+end
+
assert("Array#index (block)") do
assert_nil (1..10).to_a.index { |i| i % 5 == 0 and i % 7 == 0 }
assert_equal 34, (1..100).to_a.index { |i| i % 5 == 0 and i % 7 == 0 }
diff --git a/src/array.c b/src/array.c
index df953832b..e8882b7a3 100644
--- a/src/array.c
+++ b/src/array.c
@@ -16,15 +16,6 @@
#define ARY_C_MAX_SIZE (SIZE_MAX / sizeof(mrb_value))
#define ARY_MAX_SIZE ((ARY_C_MAX_SIZE < (size_t)MRB_INT_MAX) ? (mrb_int)ARY_C_MAX_SIZE : MRB_INT_MAX-1)
-static inline mrb_value
-ary_elt(mrb_value ary, mrb_int offset)
-{
- if (offset < 0 || RARRAY_LEN(ary) <= offset) {
- return mrb_nil_value();
- }
- return RARRAY_PTR(ary)[offset];
-}
-
static struct RArray*
ary_new_capa(mrb_state *mrb, mrb_int capa)
{