-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Prevent String::retain from creating non-utf8 strings when abusing panic #78499
Conversation
r? @shepmaster (rust_highfive has picked a reviewer for you, use r? to override) |
Won't this result in an empty string if you do |
0890596
to
92049e5
Compare
Can you add a test that fails without this change, but passes with? |
A test for |
Done. I added it in the same function of the other tests for
There's already a test for that, which in fact initially failed in the CI. The reason I didn't catch it before opening the pull request is that I naively ran |
3860e50
to
1f6f917
Compare
Thanks! @bors r+ |
📌 Commit 1f6f917 has been approved by |
…as-schievink Rollup of 11 pull requests Successful merges: - rust-lang#75078 (Improve documentation for slice strip_* functions) - rust-lang#76138 (Explain fully qualified syntax for `Rc` and `Arc`) - rust-lang#78244 (Dogfood {exclusive,half-open} ranges in compiler (nfc)) - rust-lang#78422 (Do not ICE on invalid input) - rust-lang#78423 (rustc_span: improve bounds checks in byte_pos_to_line_and_col) - rust-lang#78431 (Prefer new associated numeric consts in float error messages) - rust-lang#78462 (Use unwrapDIPtr because the Scope may be null.) - rust-lang#78493 (Update cargo) - rust-lang#78499 (Prevent String::retain from creating non-utf8 strings when abusing panic) - rust-lang#78505 (Update Clippy - temporary_cstring_as_ptr deprecation) - rust-lang#78527 (Fix some more typos) Failed merges: r? `@ghost`
unsafe { | ||
self.vec.set_len(0); | ||
} | ||
|
||
while idx < len { | ||
let ch = unsafe { self.get_unchecked(idx..len).chars().next().unwrap() }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@RalfJung this was brought to my attention by @DJMcNab (the author of retain_more
), as somewhat suspicious - it's calling get_unchecked
on a &str
obtained via auto-deref which is zero-length now. So we more or less expect this needs to go through a raw pointer directly or something similar.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! I guess another fix would be using a DropGuard
for setting the length at the end of the loop. This way it's not necessary to set the length to 0 anymore because its drop
implementation would called even in case of panic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've opened #82554, let me know what you think about it
…ness, r=m-ou-se Fix invalid slice access in String::retain As noted in rust-lang#78499, the previous fix was technically still unsound because it accessed elements of a slice outside its bounds (even though they were still inside the same allocation). This PR addresses that concern by switching to a dropguard approach.
…ness, r=m-ou-se Fix invalid slice access in String::retain As noted in rust-lang#78499, the previous fix was technically still unsound because it accessed elements of a slice outside its bounds (even though they were still inside the same allocation). This PR addresses that concern by switching to a dropguard approach.
Fixes #78498
The idea is the same as
Vec::drain
, set the len to 0 so that nobody can observe the broken invariant if it escapes the function (in this case iff
panics)