ruby-changes:17094
From: nobu <ko1@a...>
Date: Wed, 25 Aug 2010 18:31:52 +0900 (JST)
Subject: [ruby-changes:17094] Ruby:r29094 (trunk): * random.c (rb_random_real): check the range of result.
nobu 2010-08-25 18:31:46 +0900 (Wed, 25 Aug 2010) New Revision: 29094 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=29094 Log: * random.c (rb_random_real): check the range of result. Modified files: trunk/ChangeLog trunk/random.c trunk/test/ruby/test_array.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 29093) +++ ChangeLog (revision 29094) @@ -1,5 +1,7 @@ -Wed Aug 25 17:59:50 2010 Nobuyoshi Nakada <nobu@r...> +Wed Aug 25 18:31:17 2010 Nobuyoshi Nakada <nobu@r...> + * random.c (rb_random_real): check the range of result. + * array.c (rb_ary_{shuffle_bang,sample}): use Random class object. * random.c (try_get_rnd): use default_rand for Random as same as Index: test/ruby/test_array.rb =================================================================== --- test/ruby/test_array.rb (revision 29093) +++ test/ruby/test_array.rb (revision 29094) @@ -1899,6 +1899,19 @@ end end + def test_shuffle_random + cc = nil + gen = proc do + 10000000 + end + class << gen + alias rand call + end + assert_raise(RangeError) { + [*0..2].shuffle(random: gen) + } + end + def test_sample 100.times do assert([0, 1, 2].include?([2, 1, 0].sample)) Index: random.c =================================================================== --- random.c (revision 29093) +++ random.c (revision 29094) @@ -887,7 +887,13 @@ { rb_random_t *rnd = try_get_rnd(obj); if (!rnd) { - VALUE lim = ULONG2NUM(0xffffffff); +#if SIZEOF_LONG > 32 + VALUE lim = ULONG2NUM(0x100000000); +#elif defined HAVE_LONG_LONG + VALUE lim = ULL2NUM((LONG_LONG)0xffffffff+1); +#else + VALUE lim = rb_big_plus(ULONG2NUM(0xffffffff), INT2FIX(1)); +#endif return NUM2ULONG(rb_funcall2(obj, id_rand, 1, &lim)); } return genrand_int32(&rnd->mt); @@ -899,7 +905,11 @@ rb_random_t *rnd = try_get_rnd(obj); if (!rnd) { VALUE v = rb_funcall2(obj, id_rand, 0, 0); - return NUM2DBL(v); + double d = NUM2DBL(v); + if (d < 0.0 || d >= 1.0) { + rb_raise(rb_eRangeError, "random number too big %g", d); + } + return d; } return genrand_real(&rnd->mt); } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/