From b59a158a1870000ef1db5acd52afa1b40e2c4fe6 Mon Sep 17 00:00:00 2001 From: akr Date: Fri, 15 Apr 2016 16:26:38 +0000 Subject: [PATCH] * array.c (rb_ary_sum): Don't yield same element twice. Found by nagachika. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54609 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 5 +++++ array.c | 4 ++++ test/ruby/test_array.rb | 7 +++++++ 3 files changed, 16 insertions(+) diff --git a/ChangeLog b/ChangeLog index cd6fdcd76e..5ac0e5db09 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Sat Apr 16 01:16:02 2016 Tanaka Akira + + * array.c (rb_ary_sum): Don't yield same element twice. + Found by nagachika. + Sat Apr 16 01:03:32 2016 Tanaka Akira * array.c (rb_ary_sum): Fix SEGV by [1/2r, 1].sum. diff --git a/array.c b/array.c index 5fe5800954..f0a212de08 100644 --- a/array.c +++ b/array.c @@ -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