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

Overflow in Ranges with unsigned end value #13648

Open
HertzDevil opened this issue Jul 10, 2023 · 3 comments
Open

Overflow in Ranges with unsigned end value #13648

HertzDevil opened this issue Jul 10, 2023 · 3 comments
Labels
kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:stdlib:collection

Comments

@HertzDevil
Copy link
Contributor

HertzDevil commented Jul 10, 2023

A few methods of Range calculate end - 1 or end - begin + 1. These can raise OverflowError for specific unsigned values of end:

(0_u32...0_u32).size          # raises OverflowError
(5_u32...5_u32).map(&.itself) # raises OverflowError
(1_u32..0_u32).sum            # raises OverflowError
(-3..0_u32).step.sum          # raises OverflowError
@HertzDevil HertzDevil added kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:stdlib:collection labels Jul 10, 2023
@HertzDevil HertzDevil changed the title Overflow in exclusive Ranges of unsigned integers Overflow in empty Ranges of unsigned integers Jul 10, 2023
@HertzDevil HertzDevil changed the title Overflow in empty Ranges of unsigned integers Overflow in empty Ranges with unsigned end value Jul 10, 2023
@HertzDevil HertzDevil changed the title Overflow in empty Ranges with unsigned end value Overflow in Ranges with unsigned end value Jul 11, 2023
@baseballlover723
Copy link
Contributor

What should be the correct value for (0_u8..255_u8).size? It's 256, which is out of range of a UInt8. I suppose you could bump it up to like an UInt16, but it seems awkward performance and typing wise, since it's only relevant for unsigned int ranges that go across the whole range.

You also get the same type of issue with signed integers when it spans more then half of the range ((-128_i8...0_i8).size). Though for the signed ints, maybe it makes more sense to convert it to an unsigned int somewhere, since the unsigned int version should be able to hold every range except from the min to the max value.

@straight-shoota
Copy link
Member

The thing is the type of Range#size should actually be Int32 like all size types. That's also the type of the super definition Enumerable#size which is used whenever the range type is not numeric.
So Range#size should also be fixed to honor the return type Int32. And that should make the calculations pretty straightforward. (There will still be overflow errors for huge values, but we just have to accept that.

@straight-shoota
Copy link
Member

straight-shoota commented Sep 4, 2024

Range#size returns Int32 with #14588. That should allow fixing this bug as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:stdlib:collection
Projects
None yet
Development

No branches or pull requests

3 participants