From 6bfb4921929e7f238df3ac165d598f73c5a82757 Mon Sep 17 00:00:00 2001 From: librelois <c@elo.tf> Date: Sun, 13 Jun 2021 17:32:37 +0200 Subject: [PATCH] fix(kv_typed): zerocopy slice deser not handle correctly empty slice --- tools/kv_typed/src/collection_ro.rs | 2 +- tools/kv_typed/src/from_bytes.rs | 28 +++++++++++++++-------- tools/kv_typed/src/iter.rs | 10 +++++--- tools/kv_typed/src/transactional_read.rs | 2 +- tools/kv_typed/src/transactional_write.rs | 2 +- 5 files changed, 28 insertions(+), 16 deletions(-) diff --git a/tools/kv_typed/src/collection_ro.rs b/tools/kv_typed/src/collection_ro.rs index 3a1aa0c..78e6f47 100644 --- a/tools/kv_typed/src/collection_ro.rs +++ b/tools/kv_typed/src/collection_ro.rs @@ -193,7 +193,7 @@ impl<V: ValueSliceZc, BC: BackendCol, E: EventTrait<V = V>> DbCollectionRoGetRef ) -> KvResult<Option<D>> { let r = self.inner.read(); r.backend_col.get_ref_slice::<E::K, V, D, _>(k, |bytes| { - if bytes.is_empty() { + if bytes.len() <= V::prefix_len() { f(&[]) } else if let Some(layout_verified) = zerocopy::LayoutVerified::<_, [V::Elem]>::new_slice(&bytes[V::prefix_len()..]) diff --git a/tools/kv_typed/src/from_bytes.rs b/tools/kv_typed/src/from_bytes.rs index 6cade2d..1646e7b 100644 --- a/tools/kv_typed/src/from_bytes.rs +++ b/tools/kv_typed/src/from_bytes.rs @@ -63,9 +63,13 @@ where type Err = LayoutVerifiedErr; fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Err> { - let layout_verified = zerocopy::LayoutVerified::<_, [T]>::new_slice(bytes) - .ok_or(LayoutVerifiedErr(stringify!(T)))?; - Ok(SmallVec::from_slice(layout_verified.into_slice())) + if bytes.is_empty() { + Ok(SmallVec::new()) + } else { + let layout_verified = zerocopy::LayoutVerified::<_, [T]>::new_slice(bytes) + .ok_or(LayoutVerifiedErr(stringify!(T)))?; + Ok(SmallVec::from_slice(layout_verified.into_slice())) + } } } @@ -76,13 +80,17 @@ where type Err = LayoutVerifiedErr; fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Err> { - let layout_verified = zerocopy::LayoutVerified::<_, [T]>::new_slice(bytes) - .ok_or(LayoutVerifiedErr(stringify!(Vec<T>)))?; - let slice = layout_verified.into_slice(); - let mut vec = Vec::with_capacity(slice.len()); - vec.resize_with(slice.len(), Default::default); - vec.copy_from_slice(slice); - Ok(vec) + if bytes.is_empty() { + Ok(Vec::with_capacity(0)) + } else { + let layout_verified = zerocopy::LayoutVerified::<_, [T]>::new_slice(bytes) + .ok_or(LayoutVerifiedErr(stringify!(Vec<T>)))?; + let slice = layout_verified.into_slice(); + let mut vec = Vec::with_capacity(slice.len()); + vec.resize_with(slice.len(), Default::default); + vec.copy_from_slice(slice); + Ok(vec) + } } } diff --git a/tools/kv_typed/src/iter.rs b/tools/kv_typed/src/iter.rs index 8671cb1..2625db8 100644 --- a/tools/kv_typed/src/iter.rs +++ b/tools/kv_typed/src/iter.rs @@ -175,9 +175,13 @@ where Some(Ok((k_bytes, v_bytes))) => { if let Some(k_layout) = zerocopy::LayoutVerified::<_, K::Ref>::new(k_bytes.as_ref()) { - if let Some(v_layout) = zerocopy::LayoutVerified::<_, [V::Elem]>::new_slice( - &v_bytes.as_ref()[V::prefix_len()..], - ) { + if v_bytes.as_ref().len() <= V::prefix_len() { + Some((self.f)(&k_layout, &[])) + } else if let Some(v_layout) = + zerocopy::LayoutVerified::<_, [V::Elem]>::new_slice( + &v_bytes.as_ref()[V::prefix_len()..], + ) + { Some((self.f)(&k_layout, &v_layout)) } else { Some(Err(KvError::DeserError( diff --git a/tools/kv_typed/src/transactional_read.rs b/tools/kv_typed/src/transactional_read.rs index 75df9be..5828a72 100644 --- a/tools/kv_typed/src/transactional_read.rs +++ b/tools/kv_typed/src/transactional_read.rs @@ -138,7 +138,7 @@ impl<'tx, V: ValueSliceZc, BC: BackendCol, E: EventTrait<V = V>> TxColRo<'tx, BC self.col_reader .backend_col .get_ref_slice::<E::K, V, D, _>(k, |bytes| { - if bytes.is_empty() { + if bytes.len() <= V::prefix_len() { f(&[]) } else if let Some(layout_verified) = zerocopy::LayoutVerified::<_, [V::Elem]>::new_slice(&bytes[V::prefix_len()..]) diff --git a/tools/kv_typed/src/transactional_write.rs b/tools/kv_typed/src/transactional_write.rs index 54d109d..5e500c1 100644 --- a/tools/kv_typed/src/transactional_write.rs +++ b/tools/kv_typed/src/transactional_write.rs @@ -62,7 +62,7 @@ impl<'tx, V: ValueSliceZc, BC: BackendCol, E: EventTrait<V = V>> TxColRw<'tx, BC self.col_reader .backend_col .get_ref_slice::<E::K, V, D, _>(k, |bytes| { - if bytes.is_empty() { + if bytes.len() <= V::prefix_len() { f(&[]) } else if let Some(layout_verified) = zerocopy::LayoutVerified::<_, [V::Elem]>::new_slice(&bytes[V::prefix_len()..]) -- GitLab