ruby-changes:17475
From: naruse <ko1@a...>
Date: Wed, 13 Oct 2010 12:56:41 +0900 (JST)
Subject: [ruby-changes:17475] Ruby:r29480 (trunk): * numeric.c (rb_num_to_uint): added to check the range of arguments.
naruse 2010-10-13 12:56:31 +0900 (Wed, 13 Oct 2010) New Revision: 29480 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=29480 Log: * numeric.c (rb_num_to_uint): added to check the range of arguments. Mainly for negative value with NUM2UINT on 32bit environment. * string.c (rb_str_concat): use rb_num_to_uint. Modified files: trunk/ChangeLog trunk/numeric.c trunk/string.c Index: ChangeLog =================================================================== --- ChangeLog (revision 29479) +++ ChangeLog (revision 29480) @@ -1,3 +1,10 @@ +Wed Oct 13 12:53:43 2010 NARUSE, Yui <naruse@r...> + + * numeric.c (rb_num_to_uint): added to check the range of arguments. + Mainly for negative value with NUM2UINT on 32bit environment. + + * string.c (rb_str_concat): use rb_num_to_uint. + Wed Oct 13 12:10:02 2010 NAKAMURA Usaku <usa@r...> * thread_win32.c (w32_error): get English message first, instead Index: string.c =================================================================== --- string.c (revision 29479) +++ string.c (revision 29480) @@ -2001,6 +2001,7 @@ return rb_str_buf_append(str, str2); } +int rb_num_to_uint(VALUE val, unsigned int *ret); /* * call-seq: @@ -2023,12 +2024,16 @@ { unsigned int lc; - if (FIXNUM_P(str2)) { - lc = FIX2UINT(str2); + if (FIXNUM_P(str2) || TYPE(str2) == T_BIGNUM) { + if (rb_num_to_uint(str2, &lc) == 0) { + } + else if (FIXNUM_P(str2)) { + rb_raise(rb_eRangeError, "%ld out of char range", FIX2LONG(str2)); + } + else { + rb_raise(rb_eRangeError, "bignum out of char range"); + } } - else if (TYPE(str2) == T_BIGNUM) { - lc = NUM2UINT(str2); - } else { return rb_str_append(str1, str2); } Index: numeric.c =================================================================== --- numeric.c (revision 29479) +++ numeric.c (revision 29480) @@ -113,7 +113,37 @@ rb_raise(rb_eZeroDivError, "divided by 0"); } +/* experimental API */ +int +rb_num_to_uint(VALUE val, unsigned int *ret) +{ +#define NUMERR_TYPE 1 +#define NUMERR_NEGATIVE 2 +#define NUMERR_TOOLARGE 3 + if (FIXNUM_P(val)) { + long v = FIX2LONG(val); + if (v > UINT_MAX) return NUMERR_TOOLARGE; + if (v < 0) return NUMERR_NEGATIVE; + *ret = (unsigned int)v; + return 0; + } + switch (TYPE(val)) { + case T_BIGNUM: + if (RBIGNUM_NEGATIVE_P(val)) return NUMERR_NEGATIVE; +#if SIZEOF_INT < SIZEOF_LONG + /* long is 64bit */ + return NUMERR_TOOLARGE; +#else + /* long is 32bit */ + if (RBIGNUM_LEN(x) > DIGSPERLONG) return NUMERR_TOOLARGE; + *ret = (unsigned int)rb_big2ulong((VALUE)val); + return 0; +#endif + } + return NUMERR_TYPE; +} + /* * call-seq: * num.coerce(numeric) -> array -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/