Skip to content

Commit 9683f51

Browse files
committed
All serialization/deserialization methods are now unsafe
1 parent 0cf57f4 commit 9683f51

File tree

14 files changed

+180
-157
lines changed

14 files changed

+180
-157
lines changed

epserde-derive/src/lib.rs

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ pub fn epserde_derive(input: TokenStream) -> TokenStream {
443443
const ZERO_COPY_MISMATCH: bool = false;
444444

445445
#[inline(always)]
446-
fn _serialize_inner(&self, backend: &mut impl epserde::ser::WriteWithNames) -> epserde::ser::Result<()> {
446+
unsafe fn _serialize_inner(&self, backend: &mut impl epserde::ser::WriteWithNames) -> epserde::ser::Result<()> {
447447
// No-op code that however checks that all fields are zero-copy.
448448
fn test<T: epserde::traits::ZeroCopy>() {}
449449
#(
@@ -456,20 +456,20 @@ pub fn epserde_derive(input: TokenStream) -> TokenStream {
456456
#[automatically_derived]
457457
impl<#generics_deserialize> epserde::deser::DeserializeInner for #name<#concat_generics> #where_clause_des
458458
{
459-
fn _deserialize_full_inner(
459+
unsafe fn _deserialize_full_inner(
460460
backend: &mut impl epserde::deser::ReadWithPos,
461461
) -> core::result::Result<Self, epserde::deser::Error> {
462462
use epserde::deser::DeserializeInner;
463-
unsafe { epserde::deser::helpers::deserialize_full_zero::<Self>(backend) }
463+
epserde::deser::helpers::deserialize_full_zero::<Self>(backend)
464464
}
465465

466466
type DeserType<'epserde_desertype> = &'epserde_desertype #name<#concat_generics>;
467467

468-
fn _deserialize_eps_inner<'deserialize_eps_inner_lifetime>(
468+
unsafe fn _deserialize_eps_inner<'deserialize_eps_inner_lifetime>(
469469
backend: &mut epserde::deser::SliceWithPos<'deserialize_eps_inner_lifetime>,
470470
) -> core::result::Result<Self::DeserType<'deserialize_eps_inner_lifetime>, epserde::deser::Error>
471471
{
472-
unsafe { epserde::deser::helpers::deserialize_eps_zero::<Self>(backend) }
472+
epserde::deser::helpers::deserialize_eps_zero::<Self>(backend)
473473
}
474474
}
475475
}
@@ -493,7 +493,7 @@ pub fn epserde_derive(input: TokenStream) -> TokenStream {
493493
const ZERO_COPY_MISMATCH: bool = ! #is_deep_copy #(&& <#fields_types>::IS_ZERO_COPY)*;
494494

495495
#[inline(always)]
496-
fn _serialize_inner(&self, backend: &mut impl epserde::ser::WriteWithNames) -> epserde::ser::Result<()> {
496+
unsafe fn _serialize_inner(&self, backend: &mut impl epserde::ser::WriteWithNames) -> epserde::ser::Result<()> {
497497
epserde::ser::helpers::check_mismatch::<Self>();
498498
#(
499499
backend.write(stringify!(#fields_names), &self.#fields_names)?;
@@ -504,20 +504,20 @@ pub fn epserde_derive(input: TokenStream) -> TokenStream {
504504

505505
#[automatically_derived]
506506
impl<#generics_deserialize> epserde::deser::DeserializeInner for #name<#concat_generics> #where_clause_des {
507-
fn _deserialize_full_inner(
507+
unsafe fn _deserialize_full_inner(
508508
backend: &mut impl epserde::deser::ReadWithPos,
509509
) -> core::result::Result<Self, epserde::deser::Error> {
510510
use epserde::deser::DeserializeInner;
511511
Ok(#name{
512512
#(
513-
#fields_names: <#fields_types>::_deserialize_full_inner(backend)?,
513+
#fields_names: unsafe { <#fields_types>::_deserialize_full_inner(backend)? },
514514
)*
515515
})
516516
}
517517

518518
type DeserType<'epserde_desertype> = #name<#(#deser_type_generics,)*>;
519519

520-
fn _deserialize_eps_inner<'deserialize_eps_inner_lifetime>(
520+
unsafe fn _deserialize_eps_inner<'deserialize_eps_inner_lifetime>(
521521
backend: &mut epserde::deser::SliceWithPos<'deserialize_eps_inner_lifetime>,
522522
) -> core::result::Result<Self::DeserType<'deserialize_eps_inner_lifetime>, epserde::deser::Error>
523523
{
@@ -627,12 +627,12 @@ pub fn epserde_derive(input: TokenStream) -> TokenStream {
627627
});
628628
variant_full_des.push(quote! {
629629
#(
630-
#var_fields_names: <#var_fields_types>::_deserialize_full_inner(backend)?,
630+
#var_fields_names: unsafe { <#var_fields_types>::_deserialize_full_inner(backend)? },
631631
)*
632632
});
633633
variant_eps_des.push(quote! {
634634
#(
635-
#var_fields_names: <#var_fields_types>::#methods(backend)?,
635+
#var_fields_names: unsafe { <#var_fields_types>::#methods(backend)? },
636636
)*
637637
});
638638
}
@@ -711,12 +711,12 @@ pub fn epserde_derive(input: TokenStream) -> TokenStream {
711711
});
712712
variant_full_des.push(quote! {
713713
#(
714-
#var_fields_vars : <#var_fields_types>::_deserialize_full_inner(backend)?,
714+
#var_fields_vars : unsafe { <#var_fields_types>::_deserialize_full_inner(backend)? },
715715
)*
716716
});
717717
variant_eps_des.push(quote! {
718718
#(
719-
#var_fields_vars : <#var_fields_types>::#methods(backend)?,
719+
#var_fields_vars : unsafe { <#var_fields_types>::#methods(backend)? },
720720
)*
721721
});
722722
}
@@ -770,7 +770,7 @@ pub fn epserde_derive(input: TokenStream) -> TokenStream {
770770
// The type is declared as zero copy, so a fortiori there is no mismatch.
771771
const ZERO_COPY_MISMATCH: bool = false;
772772
#[inline(always)]
773-
fn _serialize_inner(&self, backend: &mut impl epserde::ser::WriteWithNames) -> epserde::ser::Result<()> {
773+
unsafe fn _serialize_inner(&self, backend: &mut impl epserde::ser::WriteWithNames) -> epserde::ser::Result<()> {
774774
// No-op code that however checks that all fields are zero-copy.
775775
fn test<T: epserde::traits::ZeroCopy>() {}
776776
#(
@@ -782,19 +782,19 @@ pub fn epserde_derive(input: TokenStream) -> TokenStream {
782782

783783
#[automatically_derived]
784784
impl<#generics_deserialize> epserde::deser::DeserializeInner for #name<#concat_generics> #where_clause_des {
785-
fn _deserialize_full_inner(
785+
unsafe fn _deserialize_full_inner(
786786
backend: &mut impl epserde::deser::ReadWithPos,
787787
) -> core::result::Result<Self, epserde::deser::Error> {
788-
unsafe { epserde::deser::helpers::deserialize_full_zero::<Self>(backend) }
788+
epserde::deser::helpers::deserialize_full_zero::<Self>(backend)
789789
}
790790

791791
type DeserType<'epserde_desertype> = &'epserde_desertype #name<#concat_generics>;
792792

793-
fn _deserialize_eps_inner<'deserialize_eps_inner_lifetime>(
793+
unsafe fn _deserialize_eps_inner<'deserialize_eps_inner_lifetime>(
794794
backend: &mut epserde::deser::SliceWithPos<'deserialize_eps_inner_lifetime>,
795795
) -> core::result::Result<Self::DeserType<'deserialize_eps_inner_lifetime>, epserde::deser::Error>
796796
{
797-
unsafe { epserde::deser::helpers::deserialize_eps_zero::<Self>(backend) }
797+
epserde::deser::helpers::deserialize_eps_zero::<Self>(backend)
798798
}
799799
}
800800
}
@@ -817,7 +817,7 @@ pub fn epserde_derive(input: TokenStream) -> TokenStream {
817817
// and the attribute `deep_copy` is missing.
818818
const ZERO_COPY_MISMATCH: bool = ! #is_deep_copy #(&& <#fields_types>::IS_ZERO_COPY)*;
819819
#[inline(always)]
820-
fn _serialize_inner(&self, backend: &mut impl epserde::ser::WriteWithNames) -> epserde::ser::Result<()> {
820+
unsafe fn _serialize_inner(&self, backend: &mut impl epserde::ser::WriteWithNames) -> epserde::ser::Result<()> {
821821
epserde::ser::helpers::check_mismatch::<Self>();
822822
match self {
823823
#(
@@ -829,11 +829,11 @@ pub fn epserde_derive(input: TokenStream) -> TokenStream {
829829
}
830830
#[automatically_derived]
831831
impl<#generics_deserialize> epserde::deser::DeserializeInner for #name<#concat_generics> #where_clause_des {
832-
fn _deserialize_full_inner(
832+
unsafe fn _deserialize_full_inner(
833833
backend: &mut impl epserde::deser::ReadWithPos,
834834
) -> core::result::Result<Self, epserde::deser::Error> {
835835
use epserde::deser::DeserializeInner;
836-
match usize::_deserialize_full_inner(backend)? {
836+
match unsafe { usize::_deserialize_full_inner(backend)? } {
837837
#(
838838
#tag => Ok(Self::#variants_names{ #variant_full_des }),
839839
)*
@@ -843,12 +843,12 @@ pub fn epserde_derive(input: TokenStream) -> TokenStream {
843843

844844
type DeserType<'epserde_desertype> = #name<#(#deser_type_generics,)*>;
845845

846-
fn _deserialize_eps_inner<'deserialize_eps_inner_lifetime>(
846+
unsafe fn _deserialize_eps_inner<'deserialize_eps_inner_lifetime>(
847847
backend: &mut epserde::deser::SliceWithPos<'deserialize_eps_inner_lifetime>,
848848
) -> core::result::Result<Self::DeserType<'deserialize_eps_inner_lifetime>, epserde::deser::Error>
849849
{
850850
use epserde::deser::DeserializeInner;
851-
match usize::_deserialize_full_inner(backend)? {
851+
match unsafe { usize::_deserialize_full_inner(backend)? } {
852852
#(
853853
#tag => Ok(Self::DeserType::<'_>::#variants_names{ #variant_eps_des }),
854854
)*

epserde/src/deser/helpers.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@ pub unsafe fn deserialize_full_vec_zero<T: DeserializeInner + ZeroCopy>(
6666
pub fn deserialize_full_vec_deep<T: DeserializeInner + DeepCopy>(
6767
backend: &mut impl ReadWithPos,
6868
) -> deser::Result<Vec<T>> {
69-
let len = usize::_deserialize_full_inner(backend)?;
69+
let len = unsafe { usize::_deserialize_full_inner(backend)? };
7070
let mut res = Vec::with_capacity(len);
7171
for _ in 0..len {
72-
res.push(T::_deserialize_full_inner(backend)?);
72+
res.push(unsafe { T::_deserialize_full_inner(backend)? });
7373
}
7474
Ok(res)
7575
}
@@ -128,10 +128,10 @@ pub unsafe fn deserialize_eps_slice_zero<'a, T: ZeroCopy>(
128128
pub fn deserialize_eps_vec_deep<'a, T: DeepCopy + DeserializeInner>(
129129
backend: &mut SliceWithPos<'a>,
130130
) -> deser::Result<Vec<<T as DeserializeInner>::DeserType<'a>>> {
131-
let len = usize::_deserialize_full_inner(backend)?;
131+
let len = unsafe { usize::_deserialize_full_inner(backend)? };
132132
let mut res = Vec::with_capacity(len);
133133
for _ in 0..len {
134-
res.push(T::_deserialize_eps_inner(backend)?);
134+
res.push(unsafe { T::_deserialize_eps_inner(backend)? });
135135
}
136136
Ok(res)
137137
}

epserde/src/deser/mod.rs

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ pub trait Deserialize: DeserializeInner {
9898
///
9999
/// # Safety
100100
///
101-
/// See the [trait documentation](DeserializeInner).
101+
/// See the [trait documentation](Deserialize).
102102
unsafe fn load_mem<'a>(
103103
path: impl AsRef<Path>,
104104
) -> anyhow::Result<MemCase<<Self as DeserializeInner>::DeserType<'a>>> {
@@ -265,9 +265,18 @@ pub trait DeserializeInner: Sized {
265265
/// The deserialization type associated with this type. It can be
266266
/// retrieved conveniently with the alias [`DeserType`].
267267
type DeserType<'a>;
268-
fn _deserialize_full_inner(backend: &mut impl ReadWithPos) -> Result<Self>;
269268

270-
fn _deserialize_eps_inner<'a>(backend: &mut SliceWithPos<'a>) -> Result<Self::DeserType<'a>>;
269+
/// # Safety
270+
///
271+
/// See the documentation of [`Deserialize`].
272+
unsafe fn _deserialize_full_inner(backend: &mut impl ReadWithPos) -> Result<Self>;
273+
274+
/// # Safety
275+
///
276+
/// See the documentation of [`Deserialize`].
277+
unsafe fn _deserialize_eps_inner<'a>(
278+
backend: &mut SliceWithPos<'a>,
279+
) -> Result<Self::DeserType<'a>>;
271280
}
272281

273282
/// Blanket implementation that prevents the user from overwriting the
@@ -278,12 +287,18 @@ pub trait DeserializeInner: Sized {
278287
/// [`DeserializeInner::_deserialize_full_inner`] or
279288
/// [`DeserializeInner::_deserialize_eps_inner`].
280289
impl<T: TypeHash + AlignHash + DeserializeInner> Deserialize for T {
290+
/// # Safety
291+
///
292+
/// See the documentation of [`Deserialize`].
281293
unsafe fn deserialize_full(backend: &mut impl ReadNoStd) -> Result<Self> {
282294
let mut backend = ReaderWithPos::new(backend);
283295
check_header::<Self>(&mut backend)?;
284296
Self::_deserialize_full_inner(&mut backend)
285297
}
286298

299+
/// # Safety
300+
///
301+
/// See the documentation of [`Deserialize`].
287302
unsafe fn deserialize_eps(backend: &'_ [u8]) -> Result<Self::DeserType<'_>> {
288303
let mut backend = SliceWithPos::new(backend);
289304
check_header::<Self>(&mut backend)?;
@@ -307,32 +322,32 @@ pub fn check_header<T: Deserialize + TypeHash + AlignHash>(
307322
T::align_hash(&mut align_hasher, &mut offset_of);
308323
let self_align_hash = align_hasher.finish();
309324

310-
let magic = u64::_deserialize_full_inner(backend)?;
325+
let magic = unsafe { u64::_deserialize_full_inner(backend)? };
311326
match magic {
312327
MAGIC => Ok(()),
313328
MAGIC_REV => Err(Error::EndiannessError),
314329
magic => Err(Error::MagicCookieError(magic)),
315330
}?;
316331

317-
let major = u16::_deserialize_full_inner(backend)?;
332+
let major = unsafe { u16::_deserialize_full_inner(backend)? };
318333
if major != VERSION.0 {
319334
return Err(Error::MajorVersionMismatch(major));
320335
}
321-
let minor = u16::_deserialize_full_inner(backend)?;
336+
let minor = unsafe { u16::_deserialize_full_inner(backend)? };
322337
if minor > VERSION.1 {
323338
return Err(Error::MinorVersionMismatch(minor));
324339
};
325340

326-
let usize_size = u8::_deserialize_full_inner(backend)?;
341+
let usize_size = unsafe { u8::_deserialize_full_inner(backend)? };
327342
let usize_size = usize_size as usize;
328343
let native_usize_size = core::mem::size_of::<usize>();
329344
if usize_size != native_usize_size {
330345
return Err(Error::UsizeSizeMismatch(usize_size));
331346
};
332347

333-
let ser_type_hash = u64::_deserialize_full_inner(backend)?;
334-
let ser_align_hash = u64::_deserialize_full_inner(backend)?;
335-
let ser_type_name = String::_deserialize_full_inner(backend)?;
348+
let ser_type_hash = unsafe { u64::_deserialize_full_inner(backend)? };
349+
let ser_align_hash = unsafe { u64::_deserialize_full_inner(backend)? };
350+
let ser_type_name = unsafe { String::_deserialize_full_inner(backend)? };
336351

337352
if ser_type_hash != self_type_hash {
338353
return Err(Error::WrongTypeHash {
@@ -361,9 +376,17 @@ pub trait DeserializeHelper<T: CopySelector> {
361376
type FullType;
362377
type DeserType<'a>;
363378

364-
fn _deserialize_full_inner_impl(backend: &mut impl ReadWithPos) -> Result<Self::FullType>;
379+
/// # Safety
380+
///
381+
/// See the documentation of [`Deserialize`].
382+
unsafe fn _deserialize_full_inner_impl(
383+
backend: &mut impl ReadWithPos,
384+
) -> Result<Self::FullType>;
365385

366-
fn _deserialize_eps_inner_impl<'a>(
386+
/// # Safety
387+
///
388+
/// See the documentation of [`Deserialize`].
389+
unsafe fn _deserialize_eps_inner_impl<'a>(
367390
backend: &mut SliceWithPos<'a>,
368391
) -> Result<Self::DeserType<'a>>;
369392
}

0 commit comments

Comments
 (0)