Unnamed repository; edit this file 'description' to name the repository.
Fix SmoLStrBuilder pushing null bytes on heap spill
| -rw-r--r-- | lib/smol_str/CHANGELOG.md | 5 | ||||
| -rw-r--r-- | lib/smol_str/src/lib.rs | 2 | ||||
| -rw-r--r-- | lib/smol_str/tests/test.rs | 9 |
3 files changed, 15 insertions, 1 deletions
diff --git a/lib/smol_str/CHANGELOG.md b/lib/smol_str/CHANGELOG.md index c1346a28a4..41f1377430 100644 --- a/lib/smol_str/CHANGELOG.md +++ b/lib/smol_str/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 0.3.2 - 2024-10-23 + +- Fix `SmolStrBuilder::push` incorrectly padding null bytes when spilling onto the heap on a + multibyte character push + ## 0.3.1 - 2024-09-04 - Fix `SmolStrBuilder` leaking implementation details diff --git a/lib/smol_str/src/lib.rs b/lib/smol_str/src/lib.rs index d00ec98915..bf88f57cf8 100644 --- a/lib/smol_str/src/lib.rs +++ b/lib/smol_str/src/lib.rs @@ -763,7 +763,7 @@ impl SmolStrBuilder { let mut heap = String::with_capacity(new_len); // copy existing inline bytes over to the heap // SAFETY: inline data is guaranteed to be valid utf8 for `old_len` bytes - unsafe { heap.as_mut_vec().extend_from_slice(buf) }; + unsafe { heap.as_mut_vec().extend_from_slice(&buf[..*len]) }; heap.push(c); self.0 = SmolStrBuilderRepr::Heap(heap); } diff --git a/lib/smol_str/tests/test.rs b/lib/smol_str/tests/test.rs index 81bccf106e..96b8b8f7f0 100644 --- a/lib/smol_str/tests/test.rs +++ b/lib/smol_str/tests/test.rs @@ -255,6 +255,7 @@ fn test_to_smolstr() { assert_eq!(a, smol_str::format_smolstr!("{}", a)); } } + #[test] fn test_builder_push_str() { //empty @@ -290,6 +291,14 @@ fn test_builder_push_str() { let s = builder.finish(); assert!(s.is_heap_allocated()); assert_eq!("a".repeat(46), s); + + // heap push on multibyte char + let mut builder = SmolStrBuilder::new(); + builder.push_str("ohnonononononononono!"); + builder.push('🤯'); + let s = builder.finish(); + assert!(s.is_heap_allocated()); + assert_eq!("ohnonononononononono!🤯", s); } #[test] |