Skip to content

Commit

Permalink
Fixed a memory problem in Array#to_h
Browse files Browse the repository at this point in the history
Reported from Alex Snaps via Mathieu Leduc-Hamel,
both from shopify.com.  Thank you!
  • Loading branch information
matz committed Nov 15, 2016
1 parent 4f6cce0 commit 739dad6
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 10 deletions.
9 changes: 9 additions & 0 deletions include/mruby/array.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
2 changes: 1 addition & 1 deletion mrbgems/mruby-array-ext/src/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
);
}
Expand Down
11 changes: 11 additions & 0 deletions mrbgems/mruby-array-ext/test/array.rb
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,17 @@
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 }
Expand Down
9 changes: 0 additions & 9 deletions src/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down

0 comments on commit 739dad6

Please sign in to comment.