diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | array.c | 4 | ||||
-rw-r--r-- | test/ruby/test_array.rb | 7 |
3 files changed, 16 insertions, 0 deletions
@@ -1,3 +1,8 @@ +Sat Apr 16 01:16:02 2016 Tanaka Akira <akr@fsij.org> + + * array.c (rb_ary_sum): Don't yield same element twice. + Found by nagachika. + Sat Apr 16 01:03:32 2016 Tanaka Akira <akr@fsij.org> * array.c (rb_ary_sum): Fix SEGV by [1/2r, 1].sum. @@ -5736,12 +5736,14 @@ rb_ary_sum(int argc, VALUE *argv, VALUE ary) f = NUM2DBL(v); c = 0.0; + goto has_float_value; for (; i < RARRAY_LEN(ary); i++) { double x, y, t; e = RARRAY_AREF(ary, i); if (block_given) e = rb_yield(e); if (RB_FLOAT_TYPE_P(e)) + has_float_value: x = RFLOAT_VALUE(e); else if (FIXNUM_P(e)) x = FIX2LONG(e); @@ -5763,10 +5765,12 @@ rb_ary_sum(int argc, VALUE *argv, VALUE ary) v = DBL2NUM(f); } + goto has_some_value; for (; i < RARRAY_LEN(ary); i++) { e = RARRAY_AREF(ary, i); if (block_given) e = rb_yield(e); + has_some_value: v = rb_funcall(v, idPLUS, 1, e); } return v; diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb index fb6b2a42ad..4ae5f9f820 100644 --- a/test/ruby/test_array.rb +++ b/test/ruby/test_array.rb @@ -1,6 +1,7 @@ # coding: US-ASCII # frozen_string_literal: false require 'test/unit' +require "delegate" require "rbconfig/sizeof" class TestArray < Test::Unit::TestCase @@ -2769,6 +2770,12 @@ class TestArray < Test::Unit::TestCase assert_int_equal(13, [1, 2].sum(10)) assert_int_equal(16, [1, 2].sum(10) {|v| v * 2 }) + yielded = [] + three = SimpleDelegator.new(3) + ary = [1, 2.0, three] + assert_float_equal(12.0, ary.sum {|x| yielded << x; x * 2 }) + assert_equal(ary, yielded) + assert_raise(TypeError) { [Object.new].sum } large_number = 100000000 |