aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-07-15 10:05:37 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-07-15 10:05:37 +0000
commitb64881077e272f421759149bff40e8d472621423 (patch)
tree1264d4f4a4e34c982959655d5f2064fd882141f8
parentdd523215af505c1f80997fd71d3afdc2e62aac92 (diff)
downloadruby-b64881077e272f421759149bff40e8d472621423.tar.gz
* bignum.c (rb_cstr_to_inum): check leading non-digits.
[ruby-core:11691] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12795 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog5
-rw-r--r--bignum.c31
-rw-r--r--test/ruby/test_integer.rb12
3 files changed, 33 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index 34dfdb2b89..a8a7cf1fc6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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]
diff --git a/bignum.c b/bignum.c
index 51a5a43d85..74659dd40d 100644
--- a/bignum.c
+++ b/bignum.c
@@ -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