From 2efa206862c05b3aaf9b2e017543bb320da883cf Mon Sep 17 00:00:00 2001 From: Emily Matheys Date: Tue, 24 Feb 2026 16:37:54 +0200 Subject: [PATCH 1/5] fix: alloc(0) call is UB --- src/lib.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 5a3051ac..f449fb42 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1051,6 +1051,15 @@ impl AlignedBuf { /// Creates a new buffer that is aligned with the simd register size #[must_use] pub fn with_capacity(capacity: usize) -> Self { + if capacity == 0 { + let layout = Layout::from_size_align(0, SIMDJSON_PADDING).unwrap(); + return Self { + layout, + capacity: 0, + len: 0, + inner: NonNull::dangling(), + }; + } let Ok(layout) = Layout::from_size_align(capacity, SIMDJSON_PADDING) else { Self::capacity_overflow() }; @@ -1092,8 +1101,10 @@ impl AlignedBuf { } impl Drop for AlignedBuf { fn drop(&mut self) { - unsafe { - dealloc(self.inner.as_ptr(), self.layout); + if self.capacity > 0 { + unsafe { + dealloc(self.inner.as_ptr(), self.layout); + } } } } From d67e7146bb967f1e6f560d63a5435b9ecfae4724 Mon Sep 17 00:00:00 2001 From: Emily Matheys Date: Tue, 24 Feb 2026 16:38:54 +0200 Subject: [PATCH 2/5] fix: No UTF-8 validation happening when `portable` is disabled --- src/lib.rs | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 5a3051ac..e6e76c0d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -605,6 +605,27 @@ impl<'de> Deserializer<'de> { /// architecture dependant `find_structural_bits` impl Deserializer<'_> { + #[cfg_attr(not(feature = "no-inline"), inline)] + /// Native fallback that pre-validates UTF-8 before finding structural bits, + /// since the native `ChunkedUtf8ValidatorImp` is a no-op. + #[cfg(all( + feature = "runtime-detection", + any(target_arch = "x86_64", target_arch = "x86"), + not(feature = "portable"), + ))] + pub(crate) unsafe fn find_structural_bits_native( + input: &[u8], + structural_indexes: &mut Vec, + ) -> std::result::Result<(), ErrorType> { + match core::str::from_utf8(input) { + Ok(_) => (), + Err(_) => return Err(ErrorType::InvalidUtf8), + }; + unsafe { + Self::_find_structural_bits::(input, structural_indexes) + } + } + #[cfg_attr(not(feature = "no-inline"), inline)] #[cfg(all( feature = "runtime-detection", @@ -629,7 +650,7 @@ impl Deserializer<'_> { #[cfg(feature = "portable")] let r = Deserializer::_find_structural_bits::; #[cfg(not(feature = "portable"))] - let r = Deserializer::_find_structural_bits::; + let r = Deserializer::find_structural_bits_native; r } } From e07f22ed9bf53e82c721f03a5708663ad4905d85 Mon Sep 17 00:00:00 2001 From: Emily Matheys Date: Thu, 30 Apr 2026 10:48:14 +0300 Subject: [PATCH 3/5] fix clippy warnings --- src/lib.rs | 4 ++-- src/macros.rs | 2 ++ src/numberparse/approx.rs | 1 - src/numberparse/correct.rs | 1 - src/stage2.rs | 1 - 5 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index f449fb42..f7248768 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -44,7 +44,6 @@ mod numberparse; mod safer_unchecked; mod stringparse; -use macros::static_cast_u64; use safer_unchecked::GetSaferUnchecked; use stage2::StackState; use tape::Value; @@ -1052,7 +1051,8 @@ impl AlignedBuf { #[must_use] pub fn with_capacity(capacity: usize) -> Self { if capacity == 0 { - let layout = Layout::from_size_align(0, SIMDJSON_PADDING).unwrap(); + let layout = Layout::from_size_align(0, SIMDJSON_PADDING) + .expect("Layout for size 0 should always be valid"); return Self { layout, capacity: 0, diff --git a/src/macros.rs b/src/macros.rs index 93bf572b..064e9349 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -1217,6 +1217,7 @@ macro_rules! unlikely { }}; } +#[allow(unused_imports)] pub(crate) use unlikely; /// static cast to an i32 @@ -1254,6 +1255,7 @@ macro_rules! static_cast_u64 { i64::cast_unsigned($v) }; } +#[allow(unused_imports)] pub(crate) use static_cast_u64; /// Custom `try!` macro that does no `From` conversions diff --git a/src/numberparse/approx.rs b/src/numberparse/approx.rs index be283407..137e0cf9 100644 --- a/src/numberparse/approx.rs +++ b/src/numberparse/approx.rs @@ -4,7 +4,6 @@ use super::{ }; use crate::StaticNode; use crate::charutils::is_structural_or_whitespace; -use crate::macros::{static_cast_i64, unlikely}; use crate::safer_unchecked::GetSaferUnchecked; use crate::{Deserializer, ErrorType, Result}; diff --git a/src/numberparse/correct.rs b/src/numberparse/correct.rs index 381ca6d0..f5f6ee2c 100644 --- a/src/numberparse/correct.rs +++ b/src/numberparse/correct.rs @@ -9,7 +9,6 @@ use super::{is_made_of_eight_digits_fast, parse_eight_digits_unrolled}; use crate::StaticNode; use crate::charutils::is_structural_or_whitespace; use crate::error::Error; -use crate::macros::{static_cast_i64, unlikely}; use crate::safer_unchecked::GetSaferUnchecked; use crate::{Deserializer, ErrorType, Result}; diff --git a/src/stage2.rs b/src/stage2.rs index 9f4d000f..87701f90 100644 --- a/src/stage2.rs +++ b/src/stage2.rs @@ -1,6 +1,5 @@ #![allow(dead_code)] use crate::charutils::is_not_structural_or_whitespace; -use crate::macros::unlikely; use crate::safer_unchecked::GetSaferUnchecked; use crate::value::tape::Node; use crate::{Deserializer, Error, ErrorType, InternalError, Result}; From ffa238dc8e638148e4524918e7e955822bdc0e74 Mon Sep 17 00:00:00 2001 From: Emily Matheys Date: Thu, 30 Apr 2026 10:50:45 +0300 Subject: [PATCH 4/5] allow unused macro import --- src/macros.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/macros.rs b/src/macros.rs index 064e9349..07db0644 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -1247,6 +1247,7 @@ macro_rules! static_cast_i64 { u64::cast_signed($v) }; } +#[allow(unused_imports)] pub(crate) use static_cast_i64; /// static cast to an u64 From 3084cb72b600967bacab69ea3e8a0ecd8301b668 Mon Sep 17 00:00:00 2001 From: Emily Matheys Date: Thu, 30 Apr 2026 10:57:06 +0300 Subject: [PATCH 5/5] install relevant wasmtime cli --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 11c013b0..e21d687c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -125,7 +125,7 @@ jobs: targets: wasm32-wasip1 - name: Install wasmtime - run: cargo install wasmtime-cli + run: cargo install wasmtime-cli --version 38.0.4 - name: Run tests run: |