Commit bc1af084 authored by thiolliere's avatar thiolliere Committed by Bastian Köcher
Browse files

Revert min_encoded_len stuff due to #131 (#132)

* fix io reader

* Revert "Implement min_encoded_len and required_len (#119)"

This reverts commit 2b66d2ce.
parent bb6cb646
Pipeline #43917 passed with stages
in 10 minutes and 41 seconds
......@@ -41,7 +41,6 @@ The `Decode` trait is used for deserialization/decoding of encoded data into the
* `fn decode<I: Input>(value: &mut I) -> Result<Self, Error>`: Tries to decode the value from SCALE format to the type it is called on.
Returns an `Err` if the decoding fails.
* `fn min_encoded_len() -> usize`: The minimum length a valid encoded value can have.
### CompactAs
......
......@@ -12,122 +12,82 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use proc_macro2::{TokenStream, Ident};
use proc_macro2::{Span, TokenStream, Ident};
use syn::{Data, Fields, Field, spanned::Spanned, Error};
use crate::utils;
use std::iter::FromIterator;
// Encode macro use one byte to encode the index of the variant when encoding an enum.
const ENUM_VARIANT_INDEX_ENCODED_LEN: usize = 1;
pub struct Impl {
pub decode: TokenStream,
pub min_encoded_len: TokenStream,
}
pub fn quote(data: &Data, type_name: &Ident, input: &TokenStream) -> Result<Impl, Error> {
pub fn quote(data: &Data, type_name: &Ident, input: &TokenStream) -> TokenStream {
match *data {
Data::Struct(ref data) => match data.fields {
Fields::Named(_) | Fields::Unnamed(_) => fields_impl(
Fields::Named(_) | Fields::Unnamed(_) => create_instance(
quote! { #type_name },
input,
&data.fields,
),
Fields::Unit => {
let decode = quote_spanned! { data.fields.span() =>
quote_spanned! { data.fields.span() =>
drop(#input);
Ok(#type_name)
};
let min_encoded_len = quote_spanned! { data.fields.span() =>
0
};
Ok(Impl { decode, min_encoded_len })
}
},
},
Data::Enum(ref data) => {
let data_variants = || data.variants.iter().filter(|variant| crate::utils::get_skip(&variant.attrs).is_none());
if data_variants().count() > 256 {
return Err(Error::new(
return Error::new(
data.variants.span(),
"Currently only enums with at most 256 variants are encodable."
));
).to_compile_error();
}
let recurse = data_variants().enumerate().map(|(i, v)| {
let name = &v.ident;
let index = utils::index(v, i);
let impl_ = fields_impl(
let create = create_instance(
quote! { #type_name :: #name },
input,
&v.fields,
)?;
let impl_decode = impl_.decode;
let impl_min_encoded_len = impl_.min_encoded_len;
);
let decode = quote_spanned! { v.span() =>
quote_spanned! { v.span() =>
x if x == #index as u8 => {
#impl_decode
#create
},
};
let min_encoded_len = quote_spanned! { v.span() =>
#ENUM_VARIANT_INDEX_ENCODED_LEN + #impl_min_encoded_len
};
Ok(Impl { decode, min_encoded_len })
}
});
let recurse: Vec<_> = Result::<_, Error>::from_iter(recurse)?;
let recurse_decode = recurse.iter().map(|i| &i.decode);
let recurse_min_encoded_len = recurse.iter().map(|i| &i.min_encoded_len);
let err_msg = format!("No such variant in enum {}", type_name);
let decode = quote! {
quote! {
match #input.read_byte()? {
#( #recurse_decode )*
#( #recurse )*
x => Err(#err_msg.into()),
}
};
let min_encoded_len = quote! {
let mut res = usize::max_value();
#( res = res.min( #recurse_min_encoded_len); )*
res
};
}
Ok(Impl { decode, min_encoded_len })
},
Data::Union(ref data) => Err(Error::new(
data.union_token.span(),
"Union types are not supported."
)),
Data::Union(_) => Error::new(Span::call_site(), "Union types are not supported.").to_compile_error(),
}
}
fn field_impl(field: &Field, name: &String, input: &TokenStream) -> Result<Impl, Error> {
fn create_decode_expr(field: &Field, name: &String, input: &TokenStream) -> TokenStream {
let encoded_as = utils::get_encoded_as_type(field);
let compact = utils::get_enable_compact(field);
let skip = utils::get_skip(&field.attrs).is_some();
if encoded_as.is_some() as u8 + compact as u8 + skip as u8 > 1 {
return Err(Error::new(
return Error::new(
field.span(),
"`encoded_as`, `compact` and `skip` can only be used one at a time!"
));
).to_compile_error();
}
let err_msg = format!("Error decoding field {}", name);
if compact {
let field_type = &field.ty;
let decode = quote_spanned! { field.span() =>
quote_spanned! { field.span() =>
{
let res = <
<#field_type as _parity_scale_codec::HasCompact>::Type as _parity_scale_codec::Decode
......@@ -137,17 +97,9 @@ fn field_impl(field: &Field, name: &String, input: &TokenStream) -> Result<Impl,
Ok(a) => a.into(),
}
}
};
let min_encoded_len = quote_spanned! { field.span() =>
<
<#field_type as _parity_scale_codec::HasCompact>::Type as _parity_scale_codec::Decode
>::min_encoded_len()
};
Ok(Impl { decode, min_encoded_len })
}
} else if let Some(encoded_as) = encoded_as {
let decode = quote_spanned! { field.span() =>
quote_spanned! { field.span() =>
{
let res = <#encoded_as as _parity_scale_codec::Decode>::decode(#input);
match res {
......@@ -155,22 +107,11 @@ fn field_impl(field: &Field, name: &String, input: &TokenStream) -> Result<Impl,
Ok(a) => a.into(),
}
}
};
let min_encoded_len = quote_spanned! { field.span() =>
<#encoded_as as _parity_scale_codec::Decode>::min_encoded_len()
};
Ok(Impl { decode, min_encoded_len })
}
} else if skip {
let decode = quote_spanned! { field.span() => Default::default() };
let min_encoded_len = quote_spanned! { field.span() => 0 };
Ok(Impl { decode, min_encoded_len })
quote_spanned! { field.span() => Default::default() }
} else {
let field_type = &field.ty;
let decode = quote_spanned! { field.span() =>
quote_spanned! { field.span() =>
{
let res = _parity_scale_codec::Decode::decode(#input);
match res {
......@@ -178,21 +119,15 @@ fn field_impl(field: &Field, name: &String, input: &TokenStream) -> Result<Impl,
Ok(a) => a,
}
}
};
let min_encoded_len = quote_spanned! { field.span() =>
<#field_type as _parity_scale_codec::Decode>::min_encoded_len()
};
Ok(Impl { decode, min_encoded_len })
}
}
}
fn fields_impl(
fn create_instance(
name: TokenStream,
input: &TokenStream,
fields: &Fields
) -> Result<Impl, Error> {
) -> TokenStream {
match *fields {
Fields::Named(ref fields) => {
let recurse = fields.named.iter().map(|f| {
......@@ -201,73 +136,36 @@ fn fields_impl(
Some(a) => format!("{}.{}", name, a),
None => format!("{}", name),
};
let impl_ = field_impl(f, &field, input)?;
let impl_decode = impl_.decode;
let decode = quote_spanned! { f.span() =>
#name_ident: #impl_decode
};
let impl_min_encoded_len = impl_.min_encoded_len;
let min_encoded_len = quote_spanned! { f.span() =>
#impl_min_encoded_len
};
let decode = create_decode_expr(f, &field, input);
Ok(Impl { decode, min_encoded_len })
quote_spanned! { f.span() =>
#name_ident: #decode
}
});
let recurse: Vec<_> = Result::<_, Error>::from_iter(recurse)?;
let recurse_decode = recurse.iter().map(|i| &i.decode);
let recurse_min_encoded_len = recurse.iter().map(|i| &i.min_encoded_len);
let decode = quote_spanned! { fields.span() =>
quote_spanned! { fields.span() =>
Ok(#name {
#( #recurse_decode, )*
#( #recurse, )*
})
};
let min_encoded_len = quote_spanned! { fields.span() =>
0 #( + #recurse_min_encoded_len )*
};
Ok(Impl { decode, min_encoded_len })
}
},
Fields::Unnamed(ref fields) => {
let recurse = fields.unnamed.iter().enumerate().map(|(i, f) | {
let name = format!("{}.{}", name, i);
field_impl(f, &name, input)
create_decode_expr(f, &name, input)
});
let recurse: Vec<_> = Result::from_iter(recurse)?;
let recurse_decode = recurse.iter().map(|i| &i.decode);
let recurse_min_encoded_len = recurse.iter().map(|i| &i.min_encoded_len);
let decode = quote_spanned! { fields.span() =>
quote_spanned! { fields.span() =>
Ok(#name (
#( #recurse_decode, )*
#( #recurse, )*
))
};
let min_encoded_len = quote_spanned! { fields.span() =>
0 #( + #recurse_min_encoded_len )*
};
Ok(Impl { decode, min_encoded_len })
}
},
Fields::Unit => {
let decode = quote_spanned! { fields.span() =>
quote_spanned! { fields.span() =>
Ok(#name)
};
let min_encoded_len = quote_spanned! { fields.span() =>
0
};
Ok(Impl { decode, min_encoded_len })
}
},
}
}
......@@ -132,24 +132,14 @@ pub fn decode_derive(input: TokenStream) -> TokenStream {
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
let input_ = quote!(input);
let impl_ = match decode::quote(&input.data, name, &input_) {
Ok(impl_) => impl_,
Err(e) => return e.to_compile_error().into(),
};
let decode = impl_.decode;
let min_encoded_len = impl_.min_encoded_len;
let decoding = decode::quote(&input.data, name, &input_);
let impl_block = quote! {
impl #impl_generics _parity_scale_codec::Decode for #name #ty_generics #where_clause {
fn min_encoded_len() -> usize {
#min_encoded_len
}
fn decode<DecIn: _parity_scale_codec::Input>(
#input_: &mut DecIn
) -> core::result::Result<Self, _parity_scale_codec::Error> {
#decode
#decoding
}
}
};
......@@ -197,7 +187,7 @@ pub fn compact_as_derive(input: TokenStream) -> TokenStream {
});
let field = utils::filter_skip_named(fields).next().expect("Exactly one field");
let field_name = &field.ident;
let constructor = quote!( #name { #( #recurse, )* } );
let constructor = quote!( #name { #( #recurse, )* });
(&field.ty, quote!(&self.#field_name), constructor)
},
Fields::Unnamed(ref fields) if utils::filter_skip_unnamed(fields).count() == 1 => {
......@@ -207,7 +197,7 @@ pub fn compact_as_derive(input: TokenStream) -> TokenStream {
});
let (id, field) = utils::filter_skip_unnamed(fields).next().expect("Exactly one field");
let id = syn::Index::from(id);
let constructor = quote!( #name(#( #recurse, )*) );
let constructor = quote!( #name(#( #recurse, )*));
(&field.ty, quote!(&self.#id), constructor)
},
_ => {
......
......@@ -59,18 +59,8 @@ macro_rules! fuzz_types {
let num = $counter;
$(
if $data[0] % num == $index {
let mut input = &$data[1..];
let input_start_len = input.len();
// Check that decode doesn't panic.
let result = <$parsed>::decode(&mut input);
// Check that min_encoded_len is valid.
if result.is_ok() {
let encoded_len = input_start_len - input.len();
assert!(<$parsed>::min_encoded_len() <= encoded_len);
}
let _ = <$parsed>::decode(&mut &$data[1..]);
return
}
)*
......
......@@ -47,10 +47,6 @@ impl<C: Cursor, T: BitStore + ToByteSlice> Encode for BitVec<C, T> {
}
impl<C: Cursor, T: BitStore + FromByteSlice> Decode for BitVec<C, T> {
fn min_encoded_len() -> usize {
<Compact<u32>>::min_encoded_len()
}
fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
<Compact<u32>>::decode(input).and_then(move |Compact(bits)| {
let bits = bits as usize;
......@@ -73,10 +69,6 @@ impl<C: Cursor, T: BitStore + ToByteSlice> Encode for BitBox<C, T> {
}
impl<C: Cursor, T: BitStore + FromByteSlice> Decode for BitBox<C, T> {
fn min_encoded_len() -> usize {
<BitVec<C, T>>::min_encoded_len()
}
fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
Ok(Self::from_bitslice(BitVec::<C, T>::decode(input)?.as_bitslice()))
}
......@@ -92,7 +84,6 @@ fn required_bytes<T>(bits: usize) -> usize {
mod tests {
use super::*;
use bitvec::{bitvec, cursor::BigEndian};
use crate::codec::DecodeM;
macro_rules! test_data {
($inner_type: ty) => (
......@@ -155,7 +146,7 @@ mod tests {
fn bitvec_u8() {
for v in &test_data!(u8) {
let encoded = v.encode();
assert_eq!(*v, BitVec::<BigEndian, u8>::decode_m(&mut &encoded[..]).unwrap());
assert_eq!(*v, BitVec::<BigEndian, u8>::decode(&mut &encoded[..]).unwrap());
}
}
......@@ -163,7 +154,7 @@ mod tests {
fn bitvec_u16() {
for v in &test_data!(u16) {
let encoded = v.encode();
assert_eq!(*v, BitVec::<BigEndian, u16>::decode_m(&mut &encoded[..]).unwrap());
assert_eq!(*v, BitVec::<BigEndian, u16>::decode(&mut &encoded[..]).unwrap());
}
}
......@@ -171,7 +162,7 @@ mod tests {
fn bitvec_u32() {
for v in &test_data!(u32) {
let encoded = v.encode();
assert_eq!(*v, BitVec::<BigEndian, u32>::decode_m(&mut &encoded[..]).unwrap());
assert_eq!(*v, BitVec::<BigEndian, u32>::decode(&mut &encoded[..]).unwrap());
}
}
......@@ -179,7 +170,7 @@ mod tests {
fn bitvec_u64() {
for v in &test_data!(u64) {
let encoded = v.encode();
assert_eq!(*v, BitVec::<BigEndian, u64>::decode_m(&mut &encoded[..]).unwrap());
assert_eq!(*v, BitVec::<BigEndian, u64>::decode(&mut &encoded[..]).unwrap());
}
}
......@@ -188,7 +179,7 @@ mod tests {
let data: &[u8] = &[0x69];
let slice: &BitSlice = data.into();
let encoded = slice.encode();
let decoded = BitVec::<BigEndian, u8>::decode_m(&mut &encoded[..]).unwrap();
let decoded = BitVec::<BigEndian, u8>::decode(&mut &encoded[..]).unwrap();
assert_eq!(slice, decoded.as_bitslice());
}
......@@ -197,7 +188,7 @@ mod tests {
let data: &[u8] = &[5, 10];
let bb: BitBox = data.into();
let encoded = bb.encode();
let decoded = BitBox::<BigEndian, u8>::decode_m(&mut &encoded[..]).unwrap();
let decoded = BitBox::<BigEndian, u8>::decode(&mut &encoded[..]).unwrap();
assert_eq!(bb, decoded);
}
}
......@@ -95,10 +95,6 @@ impl From<&'static str> for Error {
/// Trait that allows reading of data into a slice.
pub trait Input {
/// Require the input to be at least the len specified. This allow to ensure a valid value can
/// be constructed with the given input, thus allowing allocating memory upfront.
fn require_min_len(&mut self, len: usize) -> Result<(), Error>;
/// Read the exact number of bytes required to fill the given buffer.
///
/// Note that this function is similar to `std::io::Read::read_exact` and not
......@@ -113,15 +109,8 @@ pub trait Input {
}
}
#[cfg(not(feature = "std"))]
impl<'a> Input for &'a [u8] {
fn require_min_len(&mut self, len: usize) -> Result<(), Error> {
if self.len() < len {
return Err("Not enough data for required minimum length".into());
}
Ok(())
}
fn read(&mut self, into: &mut [u8]) -> Result<(), Error> {
if into.len() > self.len() {
return Err("Not enough data to fill buffer".into());
......@@ -135,54 +124,40 @@ impl<'a> Input for &'a [u8] {
#[cfg(feature = "std")]
impl From<std::io::Error> for Error {
fn from(_err: std::io::Error) -> Self {
"io error".into()
fn from(err: std::io::Error) -> Self {
use std::io::ErrorKind::*;
match err.kind() {
NotFound => "io error: NotFound".into(),
PermissionDenied => "io error: PermissionDenied".into(),
ConnectionRefused => "io error: ConnectionRefused".into(),
ConnectionReset => "io error: ConnectionReset".into(),
ConnectionAborted => "io error: ConnectionAborted".into(),
NotConnected => "io error: NotConnected".into(),
AddrInUse => "io error: AddrInUse".into(),
AddrNotAvailable => "io error: AddrNotAvailable".into(),
BrokenPipe => "io error: BrokenPipe".into(),
AlreadyExists => "io error: AlreadyExists".into(),
WouldBlock => "io error: WouldBlock".into(),
InvalidInput => "io error: InvalidInput".into(),
InvalidData => "io error: InvalidData".into(),
TimedOut => "io error: TimedOut".into(),
WriteZero => "io error: WriteZero".into(),
Interrupted => "io error: Interrupted".into(),
Other => "io error: Other".into(),
UnexpectedEof => "io error: UnexpectedEof".into(),
_ => "io error: Unkown".into(),
}
}
}
#[cfg(feature = "std")]
pub struct IoReader<R: std::io::Read> {
buffer: Vec<u8>,
reader: R,
}
#[cfg(feature = "std")]
impl<R: std::io::Read> Input for IoReader<R> {
fn require_min_len(&mut self, len: usize) -> Result<(), Error> {
if self.buffer.len() >= len {
return Ok(())
}
let filled_len = self.buffer.len();
self.buffer.resize(len, 0);
self.reader.read_exact(&mut self.buffer[filled_len..])?;
Ok(())
}
impl<R: std::io::Read> Input for R {
fn read(&mut self, into: &mut [u8]) -> Result<(), Error> {
let into_len = into.len();
let buffer_len = self.buffer.len();
into.copy_from_slice(&self.buffer[..into_len.min(buffer_len)]);
self.buffer.resize(buffer_len - into_len.min(buffer_len), 0);
if into_len > buffer_len {
self.reader.read_exact(&mut into[buffer_len..])?;
}
(self as &mut dyn std::io::Read).read_exact(into)?;
Ok(())
}
}
#[cfg(feature = "std")]
impl<R: std::io::Read> From<R> for IoReader<R> {
fn from(reader: R) -> Self {
IoReader {
buffer: vec![],
reader,
}
}
}
/// Trait that allows writing of data.
pub trait Output: Sized {
/// Write to the output.
......@@ -278,10 +253,6 @@ pub trait Decode: Sized {
#[doc(hidden)]
const IS_U8: IsU8 = IsU8::No;
/// The minimum length of an encoded value. This is used to prevent allocating memory on
/// crafted wrong input.
fn min_encoded_len() -> usize;
/// Attempt to deserialise the value from input.
fn decode<I: Input>(value: &mut I) -> Result<Self, Error>;
}
......@@ -355,10 +326,6 @@ impl<T, X> Decode for X where
T: Decode + Into<X>,
X: WrapperTypeDecode<Wrapped=T>,
{
fn min_encoded_len() -> usize {
T::min_encoded_len()
}
fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
Ok(T::decode(input)?.into())
}
......@@ -393,10 +360,6 @@ impl<T: Encode, E: Encode> Encode for Result<T, E> {
}
impl<T: Decode, E: Decode> Decode for Result<T, E> {
fn min_encoded_len() -> usize {
1 + T::min_encoded_len()
}
fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
match input.read_byte()? {
0 => Ok(Ok(T::decode(input)?)),
......@@ -431,10 +394,6 @@ impl Encode for OptionBool {
}
impl Decode for OptionBool {
fn min_encoded_len() -> usize {
1
}
fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
match input.read_byte()? {
0 => Ok(OptionBool(None)),
......@@ -465,10 +424,6 @@ impl<T: Encode> Encode for Option<T> {
}
impl<T: Decode> Decode for Option<T> {
fn min_encoded_len() -> usize {
1
}
fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
match input.read_byte()? {
0 => Ok(None),
......@@ -489,13 +444,7 @@ macro_rules! impl_array {