Skip to content

Convert str indices without casting the char length to i32 - #255

Closed
Dilshad-Tanvi wants to merge 1 commit into
facebook:mainfrom
Dilshad-Tanvi:str-indices-len-beyond-i32
Closed

Dilshad-Tanvi wants to merge 1 commit into
facebook:mainfrom
Dilshad-Tanvi:str-indices-len-beyond-i32

Conversation

@Dilshad-Tanvi

Copy link
Copy Markdown
Contributor

convert_str_indices_slow, the negative-index path behind str slicing and find/rfind/index/rindex/count/startswith/endswith, casts the char length to i32 before calling convert_indices. A string can hold up to u32::MAX bytes, so at 2^31 chars or more the length wraps negative, bound returns limit as usize (about 2^64) for a positive index, and the ASCII fast path passes that to get_unchecked(start..end). In a release build s = ("a" * (1 << 30)) * 2; s.find("b", -2147483648, 5) builds a &str running far past the 2 GiB buffer and segfaults reading it. s[:-1] builds the same out-of-bounds slice and only stops at the len overflow assert in alloc_str.

Convert the indices in usize against the real char length, and make the end <= len precondition of the unchecked slice an assert! instead of a debug_assert!. With the fix the script above returns -1. Both the bytes and the list/tuple slicing paths use apply_slice with checked indexing, so this is the only unchecked slice fed by the wrapped length. The new unit test drives the index conversion with a 1 << 31 length directly so it doesn't need a 2 GiB allocation.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 23, 2026
@meta-codesync

meta-codesync Bot commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

This pull request has been imported. If you are a Meta employee, you can view this in D127104746. (Because this pull request was imported automatically, there will not be any future comments.)

@JakobDegen JakobDegen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Review automatically exported from Phabricator review in Meta.

meta-codesync Bot pushed a commit to facebook/buck2 that referenced this pull request Oct 23, 2026
Summary:
`convert_str_indices_slow`, the negative-index path behind str slicing and `find`/`rfind`/`index`/`rindex`/`count`/`startswith`/`endswith`, casts the char length to `i32` before calling `convert_indices`. A string can hold up to `u32::MAX` bytes, so at 2^31 chars or more the length wraps negative, `bound` returns `limit as usize` (about 2^64) for a positive index, and the ASCII fast path passes that to `get_unchecked(start..end)`. In a release build `s = ("a" * (1 << 30)) * 2; s.find("b", -2147483648, 5)` builds a `&str` running far past the 2 GiB buffer and segfaults reading it. `s[:-1]` builds the same out-of-bounds slice and only stops at the `len overflow` assert in `alloc_str`.

Convert the indices in `usize` against the real char length, and make the `end <= len` precondition of the unchecked slice an `assert!` instead of a `debug_assert!`. With the fix the script above returns `-1`. Both the bytes and the list/tuple slicing paths use `apply_slice` with checked indexing, so this is the only unchecked slice fed by the wrapped length. The new unit test drives the index conversion with a `1 << 31` length directly so it doesn't need a 2 GiB allocation.

X-link: facebook/starlark-rust#255

Reviewed By: JakobDegen

Differential Revision: D127104746

fbshipit-source-id: f41e47335a0719274872e02761f283b64c335477
@meta-codesync meta-codesync Bot closed this in c6e2f40 Oct 23, 2026
@meta-codesync meta-codesync Bot added the Merged label Oct 23, 2026
@meta-codesync

meta-codesync Bot commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

This pull request has been merged in c6e2f40.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Merged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants