diff options
author | nagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-08-18 03:37:56 +0000 |
---|---|---|
committer | nagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-08-18 03:37:56 +0000 |
commit | f5a90a2d97bf5b4e79fd0a534bf6941bdaf53ccb (patch) | |
tree | 393880f9f5a1649362683b57ce2720bd30339c18 | |
parent | 36045438973153db6ddb483fbf4413da9cda90d5 (diff) |
merge revision(s) 63549,63551,63554: [Backport #14805]
memo->u3.cnt is long not int [Bug #14805]
enum.c: mitigate overflows
* enum.c (enum_count): convert counters to Integer as unsigned
long, instead of long, to mitigate overflows.
[ruby-core:87348] [Bug #14805]
* enum.c (ary_inject_op): ditto.
* enum.c (each_with_index_i): ditto, instead of int.
* enum.c (find_index_i, find_index_iter_i): ditto, instead of
unsigned int.
enum.c: bignum counter
* enum.c (imemo_count_up, imemo_count_value): promote the counter
value to a bignum on overflow. [Bug #14805]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_5@64432 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | enum.c | 52 | ||||
-rw-r--r-- | version.h | 2 |
2 files changed, 42 insertions, 12 deletions
@@ -141,6 +141,34 @@ enum_grep_v(VALUE obj, VALUE pat) return ary; } +#define COUNT_BIGNUM IMEMO_FL_USER0 +#define MEMO_V3_SET(m, v) RB_OBJ_WRITE((m), &(m)->u3.value, (v)) + +static void +imemo_count_up(struct MEMO *memo) +{ + if (memo->flags & COUNT_BIGNUM) { + MEMO_V3_SET(memo, rb_int_succ(memo->u3.value)); + } + else if (++memo->u3.cnt == 0) { + /* overflow */ + unsigned long buf[2] = {0, 1}; + MEMO_V3_SET(memo, rb_big_unpack(buf, 2)); + memo->flags |= COUNT_BIGNUM; + } +} + +static VALUE +imemo_count_value(struct MEMO *memo) +{ + if (memo->flags & COUNT_BIGNUM) { + return memo->u3.value; + } + else { + return ULONG2NUM(memo->u3.cnt); + } +} + static VALUE count_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, memop)) { @@ -149,7 +177,7 @@ count_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, memop)) ENUM_WANT_SVALUE(); if (rb_equal(i, memo->v1)) { - memo->u3.cnt++; + imemo_count_up(memo); } return Qnil; } @@ -160,7 +188,7 @@ count_iter_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, memop)) struct MEMO *memo = MEMO_CAST(memop); if (RTEST(rb_yield_values2(argc, argv))) { - memo->u3.cnt++; + imemo_count_up(memo); } return Qnil; } @@ -170,7 +198,7 @@ count_all_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, memop)) { struct MEMO *memo = MEMO_CAST(memop); - memo->u3.cnt++; + imemo_count_up(memo); return Qnil; } @@ -217,7 +245,7 @@ enum_count(int argc, VALUE *argv, VALUE obj) memo = MEMO_NEW(item, 0, 0); rb_block_call(obj, id_each, 0, 0, func, (VALUE)memo); - return INT2NUM(memo->u3.cnt); + return imemo_count_value(memo); } static VALUE @@ -285,10 +313,10 @@ find_index_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, memop)) ENUM_WANT_SVALUE(); if (rb_equal(i, memo->v2)) { - MEMO_V1_SET(memo, UINT2NUM(memo->u3.cnt)); + MEMO_V1_SET(memo, imemo_count_value(memo)); rb_iter_break(); } - memo->u3.cnt++; + imemo_count_up(memo); return Qnil; } @@ -298,10 +326,10 @@ find_index_iter_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, memop)) struct MEMO *memo = MEMO_CAST(memop); if (RTEST(rb_yield_values2(argc, argv))) { - MEMO_V1_SET(memo, UINT2NUM(memo->u3.cnt)); + MEMO_V1_SET(memo, imemo_count_value(memo)); rb_iter_break(); } - memo->u3.cnt++; + imemo_count_up(memo); return Qnil; } @@ -688,7 +716,7 @@ ary_inject_op(VALUE ary, VALUE init, VALUE op) if (FIXNUM_P(e)) { n += FIX2LONG(e); /* should not overflow long type */ if (!FIXABLE(n)) { - v = rb_big_plus(LONG2NUM(n), v); + v = rb_big_plus(ULONG2NUM(n), v); n = 0; } } @@ -2227,9 +2255,11 @@ enum_member(VALUE obj, VALUE val) static VALUE each_with_index_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, memo)) { - long n = MEMO_CAST(memo)->u3.cnt++; + struct MEMO *m = MEMO_CAST(memo); + VALUE n = imemo_count_value(m); - return rb_yield_values(2, rb_enum_values_pack(argc, argv), INT2NUM(n)); + imemo_count_up(m); + return rb_yield_values(2, rb_enum_values_pack(argc, argv), n); } /* @@ -1,6 +1,6 @@ #define RUBY_VERSION "2.5.2" #define RUBY_RELEASE_DATE "2018-08-18" -#define RUBY_PATCHLEVEL 75 +#define RUBY_PATCHLEVEL 76 #define RUBY_RELEASE_YEAR 2018 #define RUBY_RELEASE_MONTH 8 |