Skip to content

Integer overflow false positive with (0u8..).take(256) #25708

Closed

Description

@Kimundi

Half open ranges like 0u8.. are defined as counting upwards without doing bound checks until their last value.

However, due to the way they are implemented they will panic in debug mode before yielding the last element:

fn main() {
    for i in (0u8..).take(256).skip(250) {
        println!("{}", i);
    }
}
250
251
252
253
254
thread '<main>' panicked at 'arithmetic operation overflowed', /home/rustbuild/src/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libcore/ops.rs:203
playpen: application terminated with error code 101

(https://play.rust-lang.org/?gist=db5b640e1a6c015c03f5&version=stable)

The issue here is that while the yielded values do not depend on a integer overflow occurring, it does so as part for preparing the state for the next, invalid iteration.

It is therefore not possible to use them for counting through the whole range of an integer value in debug mode.

A possible solution would be to use conditional compilation to add a overflow flag to the struct in debug mode, have it use wrapping operation and panic on the next next() call.

See also #20249

Activity

  1. bluss commented on May 22, 2015

    @bluss
    Contributor

    See also #25696.

  2. tbu- commented on May 6, 2016

    @tbu-
    Contributor

    There are three ways to go about this:

    1. Return the sequence 0, 1, 2, ..., 255, 255, 255, 255, 255, ...
      This would make the (0u8..).take(256) work, but gives weird behavior after the first 255.
    2. Return the sequence 0, 1, 2, ..., 255, 0, 1, 2, ...
    3. Make a breaking change to extend the struct, either only in debug mode or always.

    If (1) or (2) is wanted, I can implement it, but otherwise this issue can be closed with the label rust-2-breakage-wishlist, because the behavior of 0, 1, 2, ..., 255, panic is impossible to implement for the debug mode.

    (This behavior is impossible, because you have 256 states for the struct, but want to yield 257 different behaviors: 0, ..., 255, panic.)

  3. steveklabnik commented on Oct 31, 2018

    @steveklabnik
    Contributor

    Triage: still panics

  4. CAD97 commented on May 20, 2020

    @CAD97
    Contributor

    For anyone falling on this issue: the correct way to iterate over all values is to use an inclusive range, 0..=u8::MAX.

  5. added a commit that references this issue on May 29, 2020
    077383d
  6. added a commit that references this issue on May 30, 2020
    93d45a0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.T-libs-api[DEPRECATED; DO NOT USE]

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions