diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c14eac8..e8cabbe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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 diff --git a/src/ascii_string.rs b/src/ascii_string.rs index e85a512..32592e8 100644 --- a/src/ascii_string.rs +++ b/src/ascii_string.rs @@ -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 /// @@ -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); /// } @@ -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) }, } }