Skip to content

Fix UB in documentation example #93

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

Merged
merged 3 commits into from
Sep 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,13 @@ jobs:
with:
rust-version: nightly
- run: cargo test -Zminimal-versions --verbose --all-features

miri:
name: Run tests under `miri` to check for UB
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@nightly
with:
components: miri
- run: cargo miri test --all-features
17 changes: 9 additions & 8 deletions src/ascii_string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,14 @@ impl AsciiString {
/// This is highly unsafe, due to the number of invariants that aren't checked:
///
/// * The memory at `buf` need to have been previously allocated by the same allocator this
/// library uses.
/// library uses, with an alignment of 1.
/// * `length` needs to be less than or equal to `capacity`.
/// * `capacity` needs to be the correct value.
/// * `buf` must have `length` valid ascii elements and contain a total of `capacity` total,
/// possibly, uninitialized, elements.
/// * Nothing else must be using the memory `buf` points to.
///
/// Violating these may cause problems like corrupting the allocator's internal datastructures.
/// Violating these may cause problems like corrupting the allocator's internal data structures.
///
/// # Examples
///
Expand All @@ -81,14 +82,14 @@ impl AsciiString {
/// use std::mem;
///
/// unsafe {
/// let s = AsciiString::from_ascii("hello").unwrap();
/// let ptr = s.as_ptr();
/// let mut s = AsciiString::from_ascii("hello").unwrap();
/// let ptr = s.as_mut_ptr();
/// let len = s.len();
/// let capacity = s.capacity();
///
/// mem::forget(s);
///
/// let s = AsciiString::from_raw_parts(ptr as *mut _, len, capacity);
/// let s = AsciiString::from_raw_parts(ptr, len, capacity);
///
/// assert_eq!(AsciiString::from_ascii("hello").unwrap(), s);
/// }
Expand All @@ -97,9 +98,9 @@ impl AsciiString {
#[must_use]
pub unsafe fn from_raw_parts(buf: *mut AsciiChar, length: usize, capacity: usize) -> Self {
AsciiString {
// SAFETY: Caller guarantees `buf` was previously allocated by this library,
// that `buf` contains `length` valid ascii elements and has a total
// capacity of `capacity` elements.
// SAFETY: Caller guarantees that `buf` was previously allocated by this library,
// that `buf` contains `length` valid ascii elements and has a total capacity
// of `capacity` elements, and that nothing else is using the momory.
vec: unsafe { Vec::from_raw_parts(buf, length, capacity) },
}
}
Expand Down