Skip to content

error: don't try to 1-index the usize::MAXth position in a string - #263

Open
apoelstra wants to merge 2 commits into
rust-bitcoin:masterfrom
apoelstra:2026-09/error-overflow
Open

apoelstra wants to merge 2 commits into
rust-bitcoin:masterfrom
apoelstra:2026-09/error-overflow

Conversation

@apoelstra

Copy link
Copy Markdown
Member

There are a lot of ways we can go about fixing this. Project Loupe advocates always casting to u128. If we want to do that I guess we can do it specifically for usize::MAX.

Alternately we can use a saturating increment, which would result in wrong output.

I choose to just write [usize overflow]. Even though this is supposed to be a use-facing error, the only way to hit this case is if the programmer is doing something crazy, so it seems worthwhile to handle this specific case in a programmer-centric way.

I don't feel strongly about this. Happy to take any other approach.

Fixes https://github.com/project-loupe/audit-hex-conservative/issues/4

@apoelstra
apoelstra force-pushed the 2026-09/error-overflow branch from 99e4b33 to a1d869b Compare September 30, 2026 01:14
@apoelstra

Copy link
Copy Markdown
Member Author

On a1d869b successfully ran local tests

Comment thread src/error.rs Outdated
0 => &"1st",
1 => &"2nd",
2 => &"3rd",
usize::MAX => &"[usize overflow]",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can realistically only happen in the offset method, so I suggest adding an assert there to prevent it reaching usize::MAX.

@Kixunil Kixunil Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or maybe just write out 18446744073709551616th for this case. There's no point programatically adding 1 if you already know the value.

(I guess I prefer not dealing with invariant if we can avoid it.)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And change the docs of DecodeFixedLengthBytesError::offset to say that it'll panic if you pass it usize::MAX?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My preferred solution is to special case usize::MAX by printing the statically-known number and update the docs of offset to say warn that the operation may overflow if you pass in crazy numbers. That way we won't have to make sure the error type maintains a funny invariant. But if we're going to maintain an invariant then we really should document it of course.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately we don't know the value because the size of usize is system dependent :). We could special-case 32 and 64 and add a fallback for others of course.

But whatever our solution, I'd prefer to avoid the funny invariant.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LOL, forgetting about that was quite a brain fart.

Since a cfg for usize doesn't exist, we need this:

const USIZE_MAX_PLUS_ONE: &str = {
    match core::mem::size_of::<usize>() {
        8 => "18446744073709551616th"
        4 => "4294967296th",
        2 => "65536th",
        _ => panic!("unsupported architecture"),
    }
};

(Weird, I jut noticed all the numbers end with 6. 🤯 )

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just gonna go with this. Though I'll replace the panic with some dummy text because why not.

There are a lot of ways we can go about fixing this. Project Loupe
advocates always casting to u128. If we want to do that I guess we
can do it specifically for usize::MAX.

Alternately we can use a saturating increment, which would result in
wrong output.

After talking with Kix, I chose to just write the number explicitly.

I don't feel strongly about this. Happy to take any other approach.
@apoelstra
apoelstra force-pushed the 2026-09/error-overflow branch from a1d869b to d817255 Compare October 3, 2026 14:22

@Kixunil Kixunil left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK d817255

@apoelstra

Copy link
Copy Markdown
Member Author

On d817255 successfully ran local tests

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

Successfully merging this pull request may close these issues.

2 participants