diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | bignum.c | 31 | ||||
-rw-r--r-- | test/ruby/test_integer.rb | 12 |
3 files changed, 33 insertions, 15 deletions
@@ -1,3 +1,8 @@ +Sun Jul 15 19:05:28 2007 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * bignum.c (rb_cstr_to_inum): check leading non-digits. + [ruby-core:11691] + Sun Jul 15 04:42:20 2007 Nobuyoshi Nakada <nobu@ruby-lang.org> * bignum.c (get2comp): do nothing for empty Bignum. [ruby-dev:31225] @@ -325,6 +325,13 @@ rb_cstr_to_inum(const char *str, int base, int badcheck) VALUE z; BDIGIT *zds; +#define conv_digit(c) \ + (!ISASCII(c) ? -1 : \ + isdigit(c) ? ((c) - '0') : \ + islower(c) ? ((c) - 'a' + 10) : \ + isupper(c) ? ((c) - 'A' + 10) : \ + -1) + if (!str) { if (badcheck) goto bad; return INT2FIX(0); @@ -412,7 +419,13 @@ rb_cstr_to_inum(const char *str, int base, int badcheck) } if (*str == '0') { /* squeeze preceeding 0s */ while (*++str == '0'); - --str; + if (!*str) --str; + } + c = *str; + c = conv_digit(c); + if (c < 0 || c >= base) { + if (badcheck) goto bad; + return INT2FIX(0); } len *= strlen(str)*sizeof(char); @@ -446,7 +459,7 @@ rb_cstr_to_inum(const char *str, int base, int badcheck) z = bignew(len, sign); zds = BDIGITS(z); for (i=len;i--;) zds[i]=0; - while (c = *str++) { + while ((c = *str++) != 0) { if (c == '_') { if (badcheck) { if (nondigit) goto bad; @@ -454,19 +467,7 @@ rb_cstr_to_inum(const char *str, int base, int badcheck) } continue; } - else if (!ISASCII(c)) { - break; - } - else if (isdigit(c)) { - c -= '0'; - } - else if (islower(c)) { - c -= 'a' - 10; - } - else if (isupper(c)) { - c -= 'A' - 10; - } - else { + else if ((c = conv_digit(c)) < 0) { break; } if (c >= base) break; diff --git a/test/ruby/test_integer.rb b/test/ruby/test_integer.rb index 87f7ec8a15..b813fbd878 100644 --- a/test/ruby/test_integer.rb +++ b/test/ruby/test_integer.rb @@ -375,4 +375,16 @@ class TestInteger < Test::Unit::TestCase assert(e ^ o) } end + + def test_Integer + assert_raise(ArgumentError) {Integer("0x-1")} + assert_raise(ArgumentError) {Integer("-0x-1")} + assert_raise(ArgumentError) {Integer("0x 123")} + assert_raise(ArgumentError) {Integer("0x 123")} + assert_raise(ArgumentError) {Integer("0x0x5")} + assert_raise(ArgumentError) {Integer("0x0x000000005")} + assert_nothing_raised(ArgumentError) { + assert_equal(1540841, "0x0x5".to_i(36)) + } + end end |