Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

from_str_radix incorrectly parses out-of-range repeating constants... #5770

Closed
huonw opened this issue Apr 7, 2013 · 2 comments
Closed

from_str_radix incorrectly parses out-of-range repeating constants... #5770

huonw opened this issue Apr 7, 2013 · 2 comments

Comments

@huonw
Copy link
Member

huonw commented Apr 7, 2013

...when the radix is a power of 2. e.g. 100 1's is an invalid u64/i64 in any base, but for powers of 2 it gives a "correct" parse:

static hundred_ones: &'static str  = "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111";

fn main() {
    for uint::range(2, 37) |i| {
        io::println(
            fmt!("%u %? %?", i,
                 u64::from_str_radix(hundred_ones, i),
                 i64::from_str_radix(hundred_ones, i)));
    }
}

outputs

2 Some(18446744073709551615) None
3 None None
4 Some(6148914691236517205) Some(6148914691236517205)
5 None None
6 None None
7 None None
8 Some(10540996613548315209) None
9 None None
10 None None
11 None None
12 None None
13 None None
14 None None
15 None None
16 Some(1229782938247303441) Some(1229782938247303441)
17 None None
18 None None
19 None None
20 None None
21 None None
22 None None
23 None None
24 None None
25 None None
26 None None
27 None None
28 None None
29 None None
30 None None
31 None None
32 Some(1190112520884487201) Some(1190112520884487201)
33 None None
34 None None
35 None None
36 None None
@Kimundi
Copy link
Member

Kimundi commented Apr 7, 2013

The problem here is, I think, that the code that attempts to detect overflows only does so by detecting if the accumulator grows in the wrong direction, which only covers overflow for signed values. For it to detect this condition here, it also needs to check if the accumulator does not change, even though it should, or more generally, if it changes by a smaller value than it is supposed to.

The reported behavior happens because, after the algorithm reads in the first 64 1s, this happens for the accumulator at each new digit:

        1111...1111
*= 2 -> 1111...1110
+= 1 -> 1111...1111

so it never sees that the value gets smaller

@huonw
Copy link
Member Author

huonw commented Apr 7, 2013

I agree that that is the issue, @Kimundi.

I have a fix, along with one for #5544.

huonw added a commit to huonw/rust that referenced this issue Apr 8, 2013
…2^n numbers.

A number like 0b1_1111_1111 == 511 would be parsed to Some(255u8) rather than None
by from_str_common, since 255 * 2 + 1 == 255 (mod 256) so the overflow wasn't detected.

Only applied to conversions where the radix was a power of 2, and where all digits
repeated.

Closes rust-lang#5770.
bors added a commit that referenced this issue Apr 8, 2013
…nger

Addresses #5544 and #5770, as well as a comment left in the documentation of `from_str_bytes_common`, so that there is now an option to ignore underscores.
@huonw huonw closed this as completed Apr 8, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants