diff --git a/src/lib/char.rs b/src/lib/char.rs index e91e8697dd86e..28345fb19fe9e 100644 --- a/src/lib/char.rs +++ b/src/lib/char.rs @@ -93,3 +93,12 @@ pure fn is_whitespace(c: char) -> bool { true } else if c == ch_no_break_space { true } else { false } } + +pure fn to_digit(c: char) -> u8 { + alt c { + '0' to '9' { c as u8 - ('0' as u8) } + 'a' to 'z' { c as u8 + 10u8 - ('a' as u8) } + 'A' to 'Z' { c as u8 + 10u8 - ('A' as u8) } + _ { fail; } + } +} diff --git a/src/lib/int.rs b/src/lib/int.rs index 41d166fe3fc14..62fb0a7cb63ae 100644 --- a/src/lib/int.rs +++ b/src/lib/int.rs @@ -112,7 +112,11 @@ fn parse_buf(buf: [u8], radix: uint) -> int { } let n = 0; while true { - n += (buf[i] - ('0' as u8) as int) * power; + let digit = char::to_digit(buf[i] as char); + if (digit as uint) >= radix { + fail; + } + n += (digit as int) * power; power *= radix as int; if i <= start { ret n; } i -= 1u; diff --git a/src/lib/uint.rs b/src/lib/uint.rs index cf50b70e1cd8c..5de9bd974e43a 100644 --- a/src/lib/uint.rs +++ b/src/lib/uint.rs @@ -100,7 +100,11 @@ fn parse_buf(buf: [u8], radix: uint) -> uint { let power = 1u; let n = 0u; while true { - n += (buf[i] - ('0' as u8) as uint) * power; + let digit = char::to_digit(buf[i] as char); + if (digit as uint) >= radix { + fail; + } + n += (digit as uint) * power; power *= radix; if i == 0u { ret n; } i -= 1u; diff --git a/src/test/stdtest/char.rs b/src/test/stdtest/char.rs new file mode 100644 index 0000000000000..b2724ca325d61 --- /dev/null +++ b/src/test/stdtest/char.rs @@ -0,0 +1,28 @@ +use std; +import std::char; + +#[test] +fn test_is_whitespace() { + assert char::is_whitespace(' '); + assert char::is_whitespace('\u2007'); + assert char::is_whitespace('\t'); + assert char::is_whitespace('\n'); + + assert !char::is_whitespace('a'); + assert !char::is_whitespace('_'); + assert !char::is_whitespace('\u0000'); +} + +#[test] +fn test_to_digit() { + assert (char::to_digit('0') == 0u8); + assert (char::to_digit('1') == 1u8); + assert (char::to_digit('2') == 2u8); + assert (char::to_digit('9') == 9u8); + assert (char::to_digit('a') == 10u8); + assert (char::to_digit('A') == 10u8); + assert (char::to_digit('b') == 11u8); + assert (char::to_digit('B') == 11u8); + assert (char::to_digit('z') == 35u8); + assert (char::to_digit('Z') == 35u8); +} diff --git a/src/test/stdtest/int.rs b/src/test/stdtest/int.rs index 282e16daf08a0..1bd67d5c45ecf 100644 --- a/src/test/stdtest/int.rs +++ b/src/test/stdtest/int.rs @@ -2,6 +2,7 @@ use std; import std::int; import std::str::eq; +import std::str::bytes; #[test] fn test_from_str() { @@ -18,6 +19,27 @@ fn test_from_str() { assert(int::from_str("-00100") == -100); } +#[test] +fn test_parse_buf() { + assert (int::parse_buf(bytes("123"), 10u) == 123); + assert (int::parse_buf(bytes("1001"), 2u) == 9); + assert (int::parse_buf(bytes("123"), 8u) == 83); + assert (int::parse_buf(bytes("123"), 16u) == 291); + assert (int::parse_buf(bytes("ffff"), 16u) == 65535); + assert (int::parse_buf(bytes("FFFF"), 16u) == 65535); + assert (int::parse_buf(bytes("z"), 36u) == 35); + assert (int::parse_buf(bytes("Z"), 36u) == 35); + + assert (int::parse_buf(bytes("-123"), 10u) == -123); + assert (int::parse_buf(bytes("-1001"), 2u) == -9); + assert (int::parse_buf(bytes("-123"), 8u) == -83); + assert (int::parse_buf(bytes("-123"), 16u) == -291); + assert (int::parse_buf(bytes("-ffff"), 16u) == -65535); + assert (int::parse_buf(bytes("-FFFF"), 16u) == -65535); + assert (int::parse_buf(bytes("-z"), 36u) == -35); + assert (int::parse_buf(bytes("-Z"), 36u) == -35); +} + #[test] fn test_to_str() { assert (eq(int::to_str(0, 10u), "0")); diff --git a/src/test/stdtest/stdtest.rc b/src/test/stdtest/stdtest.rc index c47b85c65f8a6..501879c540f8a 100644 --- a/src/test/stdtest/stdtest.rc +++ b/src/test/stdtest/stdtest.rc @@ -2,6 +2,7 @@ use std; mod bitv; mod box; +mod char; mod comm; mod deque; mod either; diff --git a/src/test/stdtest/uint.rs b/src/test/stdtest/uint.rs index 141b59ace82a8..35bd65c0c057f 100644 --- a/src/test/stdtest/uint.rs +++ b/src/test/stdtest/uint.rs @@ -3,6 +3,26 @@ // -*- rust -*- use std; import std::uint; +import std::str::bytes; + +#[test] +fn test_from_str() { + assert (uint::from_str("0") == 0u); + assert (uint::from_str("3") == 3u); + assert (uint::from_str("10") == 10u); + assert (uint::from_str("123456789") == 123456789u); + assert (uint::from_str("00100") == 100u); +} + +#[test] +fn test_parse_buf() { + assert (uint::parse_buf(bytes("123"), 10u) == 123u); + assert (uint::parse_buf(bytes("1001"), 2u) == 9u); + assert (uint::parse_buf(bytes("123"), 8u) == 83u); + assert (uint::parse_buf(bytes("123"), 16u) == 291u); + assert (uint::parse_buf(bytes("ffff"), 16u) == 65535u); + assert (uint::parse_buf(bytes("z"), 36u) == 35u); +} #[test] fn test_next_power_of_two() { @@ -53,4 +73,4 @@ fn test_overflows() { assert (uint::max_value() > 0u); assert (uint::min_value() <= 0u); assert (uint::min_value() + uint::max_value() + 1u == 0u); -} \ No newline at end of file +}