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

extend_from_within leaks elements on panic #82533

Closed
cmazakas opened this issue Feb 25, 2021 · 5 comments · Fixed by #82760
Closed

extend_from_within leaks elements on panic #82533

cmazakas opened this issue Feb 25, 2021 · 5 comments · Fixed by #82760
Assignees
Labels
C-bug Category: This is a bug. P-medium Medium priority T-libs Relevant to the library team, which will review and decide on the PR/issue.

Comments

@cmazakas
Copy link

cmazakas commented Feb 25, 2021

impl<T: Clone, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
default unsafe fn spec_extend_from_within(&mut self, src: Range<usize>) {
let initialized = {
let (this, spare) = self.split_at_spare_mut();
// Safety:
// - caller guaratees that src is a valid index
let to_clone = unsafe { this.get_unchecked(src) };
to_clone.iter().cloned().zip(spare.iter_mut()).map(|(e, s)| s.write(e)).count()
};
// Safety:
// - elements were just initialized
unsafe {
let new_len = self.len() + initialized;
self.set_len(new_len);
}
}
}

Looking here, the internal length of the vector is only adjusted at the end of the loop

This has the caveat that if cloning panics, the Vec will start to unwind and only drop the first len elements which doesn't include the most recently appended ones.

Something more in line with how the stdlib does things might look like this:
https://github.com/LeonineKing1199/minivec/blob/424354dfababae7101aacf70fa9332a87e9cdb15/src/lib.rs#L1612-L1700

@cmazakas cmazakas added the C-bug Category: This is a bug. label Feb 25, 2021
@camelid camelid added I-prioritize Issue: Indicates that prioritization has been requested for this issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Feb 26, 2021
@jyn514
Copy link
Member

jyn514 commented Feb 26, 2021

This has the caveat that if cloning panics, the Vec will start to unwind and only drop the first len elements which doesn't include the most recently appended ones.

This is not unsafe, leaking items is safe: #24456.

@jyn514 jyn514 changed the title No Panic Safety in extend_from_within extend_from_within leaks items on panic Feb 26, 2021
@jyn514 jyn514 changed the title extend_from_within leaks items on panic extend_from_within leaks elements on panic Feb 26, 2021
@cmazakas
Copy link
Author

This is not unsafe, leaking items is safe: #24456.

Sure; never said it was unsafe.

This is more about making sure programs who gracefully handle panics don't wind up eventually exhausting resources.

@hameerabbasi hameerabbasi added P-medium Medium priority and removed I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Feb 26, 2021
@hameerabbasi
Copy link
Contributor

Assigning P-medium as part of the WG-prioritization discussion.

@WaffleLapkin
Copy link
Member

I would like to fix this

@rustbot claim

@cmazakas
Copy link
Author

cmazakas commented Mar 3, 2021

The fix seems pretty straight-forward.

The Clone specialization just needs a RAII type that handles adjusting the Vec's new len in its Drop implementation, as I've linked in my MiniVec.

Copy can't fail so there's no need to adjust that specialization. The only thing that could theoretically panic in that case would be reallocating and in that case, there's no need to worry about the len.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. P-medium Medium priority T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants