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: | diff --git a/src/lib.rs b/src/lib.rs index 5a3051ac..b2a59d8d 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; @@ -605,6 +604,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 +649,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 } } @@ -1051,6 +1071,16 @@ 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) + .expect("Layout for size 0 should always be valid"); + 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 +1122,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); + } } } } diff --git a/src/macros.rs b/src/macros.rs index 93bf572b..07db0644 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 @@ -1246,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 @@ -1254,6 +1256,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};