Split encode::Error into two parts
The `consensus::encode::Error` contains an IO error but reading from a buffer only ever errors for EOF. We converted all instances of EOF to `MissingData` already so now we can split the IO error apart from the actual encoding errors variants.
This commit is contained in:
parent
b04142c745
commit
33566ac58c
|
@ -315,10 +315,11 @@ impl Decodable for BlockTransactionsRequest {
|
||||||
.checked_mul(mem::size_of::<Transaction>())
|
.checked_mul(mem::size_of::<Transaction>())
|
||||||
.ok_or(consensus::parse_failed_error("invalid length"))?;
|
.ok_or(consensus::parse_failed_error("invalid length"))?;
|
||||||
if byte_size > encode::MAX_VEC_SIZE {
|
if byte_size > encode::MAX_VEC_SIZE {
|
||||||
return Err(encode::Error::OversizedVectorAllocation {
|
return Err(encode::ParseError::OversizedVectorAllocation {
|
||||||
requested: byte_size,
|
requested: byte_size,
|
||||||
max: encode::MAX_VEC_SIZE,
|
max: encode::MAX_VEC_SIZE,
|
||||||
});
|
}
|
||||||
|
.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut indexes = Vec::with_capacity(nb_indexes);
|
let mut indexes = Vec::with_capacity(nb_indexes);
|
||||||
|
|
|
@ -913,7 +913,7 @@ impl Decodable for Transaction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We don't support anything else
|
// We don't support anything else
|
||||||
x => Err(encode::Error::UnsupportedSegwitFlag(x)),
|
x => Err(encode::ParseError::UnsupportedSegwitFlag(x).into()),
|
||||||
}
|
}
|
||||||
// non-segwit
|
// non-segwit
|
||||||
} else {
|
} else {
|
||||||
|
@ -1486,7 +1486,7 @@ mod tests {
|
||||||
let tx_bytes = hex!("0000fd000001021921212121212121212121f8b372b0239cc1dff600000000004f4f4f4f4f4f4f4f000000000000000000000000000000333732343133380d000000000000000000000000000000ff000000000009000dff000000000000000800000000000000000d");
|
let tx_bytes = hex!("0000fd000001021921212121212121212121f8b372b0239cc1dff600000000004f4f4f4f4f4f4f4f000000000000000000000000000000333732343133380d000000000000000000000000000000ff000000000009000dff000000000000000800000000000000000d");
|
||||||
let tx: Result<Transaction, _> = deserialize(&tx_bytes);
|
let tx: Result<Transaction, _> = deserialize(&tx_bytes);
|
||||||
assert!(tx.is_err());
|
assert!(tx.is_err());
|
||||||
assert!(tx.unwrap_err().to_string().contains("witness flag set but no witnesses present"));
|
assert!(matches!(tx.unwrap_err(), crate::consensus::Error::Parse(_)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -26,10 +26,11 @@ impl Decodable for Witness {
|
||||||
// Minimum size of witness element is 1 byte, so if the count is
|
// Minimum size of witness element is 1 byte, so if the count is
|
||||||
// greater than MAX_VEC_SIZE we must return an error.
|
// greater than MAX_VEC_SIZE we must return an error.
|
||||||
if witness_elements > MAX_VEC_SIZE {
|
if witness_elements > MAX_VEC_SIZE {
|
||||||
return Err(self::Error::OversizedVectorAllocation {
|
return Err(encode::ParseError::OversizedVectorAllocation {
|
||||||
requested: witness_elements,
|
requested: witness_elements,
|
||||||
max: MAX_VEC_SIZE,
|
max: MAX_VEC_SIZE,
|
||||||
});
|
}
|
||||||
|
.into());
|
||||||
}
|
}
|
||||||
if witness_elements == 0 {
|
if witness_elements == 0 {
|
||||||
Ok(Witness::default())
|
Ok(Witness::default())
|
||||||
|
@ -48,21 +49,26 @@ impl Decodable for Witness {
|
||||||
let element_size_len = compact_size::encoded_size(element_size);
|
let element_size_len = compact_size::encoded_size(element_size);
|
||||||
let required_len = cursor
|
let required_len = cursor
|
||||||
.checked_add(element_size)
|
.checked_add(element_size)
|
||||||
.ok_or(self::Error::OversizedVectorAllocation {
|
.ok_or(encode::Error::Parse(
|
||||||
requested: usize::MAX,
|
encode::ParseError::OversizedVectorAllocation {
|
||||||
max: MAX_VEC_SIZE,
|
requested: usize::MAX,
|
||||||
})?
|
max: MAX_VEC_SIZE,
|
||||||
|
},
|
||||||
|
))?
|
||||||
.checked_add(element_size_len)
|
.checked_add(element_size_len)
|
||||||
.ok_or(self::Error::OversizedVectorAllocation {
|
.ok_or(encode::Error::Parse(
|
||||||
requested: usize::MAX,
|
encode::ParseError::OversizedVectorAllocation {
|
||||||
max: MAX_VEC_SIZE,
|
requested: usize::MAX,
|
||||||
})?;
|
max: MAX_VEC_SIZE,
|
||||||
|
},
|
||||||
|
))?;
|
||||||
|
|
||||||
if required_len > MAX_VEC_SIZE + witness_index_space {
|
if required_len > MAX_VEC_SIZE + witness_index_space {
|
||||||
return Err(self::Error::OversizedVectorAllocation {
|
return Err(encode::ParseError::OversizedVectorAllocation {
|
||||||
requested: required_len,
|
requested: required_len,
|
||||||
max: MAX_VEC_SIZE,
|
max: MAX_VEC_SIZE,
|
||||||
});
|
}
|
||||||
|
.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// We will do content.rotate_left(witness_index_space) later.
|
// We will do content.rotate_left(witness_index_space) later.
|
||||||
|
|
|
@ -36,7 +36,7 @@ use crate::taproot::TapLeafHash;
|
||||||
use crate::transaction::{Transaction, TxIn, TxOut};
|
use crate::transaction::{Transaction, TxIn, TxOut};
|
||||||
|
|
||||||
#[rustfmt::skip] // Keep public re-exports separate.
|
#[rustfmt::skip] // Keep public re-exports separate.
|
||||||
pub use super::{Error, FromHexError};
|
pub use super::{Error, FromHexError, ParseError};
|
||||||
|
|
||||||
/// Encodes an object into a vector.
|
/// Encodes an object into a vector.
|
||||||
pub fn serialize<T: Encodable + ?Sized>(data: &T) -> Vec<u8> {
|
pub fn serialize<T: Encodable + ?Sized>(data: &T) -> Vec<u8> {
|
||||||
|
@ -76,6 +76,7 @@ pub fn deserialize_hex<T: Decodable>(hex: &str) -> Result<T, FromHexError> {
|
||||||
/// doesn't consume the entire vector.
|
/// doesn't consume the entire vector.
|
||||||
pub fn deserialize_partial<T: Decodable>(data: &[u8]) -> Result<(T, usize), Error> {
|
pub fn deserialize_partial<T: Decodable>(data: &[u8]) -> Result<(T, usize), Error> {
|
||||||
let mut decoder = Cursor::new(data);
|
let mut decoder = Cursor::new(data);
|
||||||
|
|
||||||
let rv = Decodable::consensus_decode_from_finite_reader(&mut decoder)?;
|
let rv = Decodable::consensus_decode_from_finite_reader(&mut decoder)?;
|
||||||
let consumed = decoder.position() as usize;
|
let consumed = decoder.position() as usize;
|
||||||
|
|
||||||
|
@ -224,7 +225,7 @@ impl<R: Read + ?Sized> ReadExt for R {
|
||||||
0xFF => {
|
0xFF => {
|
||||||
let x = self.read_u64()?;
|
let x = self.read_u64()?;
|
||||||
if x < 0x1_0000_0000 { // I.e., would have fit in a `u32`.
|
if x < 0x1_0000_0000 { // I.e., would have fit in a `u32`.
|
||||||
Err(Error::NonMinimalVarInt)
|
Err(ParseError::NonMinimalVarInt.into())
|
||||||
} else {
|
} else {
|
||||||
Ok(x)
|
Ok(x)
|
||||||
}
|
}
|
||||||
|
@ -232,7 +233,7 @@ impl<R: Read + ?Sized> ReadExt for R {
|
||||||
0xFE => {
|
0xFE => {
|
||||||
let x = self.read_u32()?;
|
let x = self.read_u32()?;
|
||||||
if x < 0x1_0000 { // I.e., would have fit in a `u16`.
|
if x < 0x1_0000 { // I.e., would have fit in a `u16`.
|
||||||
Err(Error::NonMinimalVarInt)
|
Err(ParseError::NonMinimalVarInt.into())
|
||||||
} else {
|
} else {
|
||||||
Ok(x as u64)
|
Ok(x as u64)
|
||||||
}
|
}
|
||||||
|
@ -240,7 +241,7 @@ impl<R: Read + ?Sized> ReadExt for R {
|
||||||
0xFD => {
|
0xFD => {
|
||||||
let x = self.read_u16()?;
|
let x = self.read_u16()?;
|
||||||
if x < 0xFD { // Could have been encoded as a `u8`.
|
if x < 0xFD { // Could have been encoded as a `u8`.
|
||||||
Err(Error::NonMinimalVarInt)
|
Err(ParseError::NonMinimalVarInt.into())
|
||||||
} else {
|
} else {
|
||||||
Ok(x as u64)
|
Ok(x as u64)
|
||||||
}
|
}
|
||||||
|
@ -649,7 +650,8 @@ impl Decodable for CheckedData {
|
||||||
let data = read_bytes_from_finite_reader(r, opts)?;
|
let data = read_bytes_from_finite_reader(r, opts)?;
|
||||||
let expected_checksum = sha2_checksum(&data);
|
let expected_checksum = sha2_checksum(&data);
|
||||||
if expected_checksum != checksum {
|
if expected_checksum != checksum {
|
||||||
Err(self::Error::InvalidChecksum { expected: expected_checksum, actual: checksum })
|
Err(ParseError::InvalidChecksum { expected: expected_checksum, actual: checksum }
|
||||||
|
.into())
|
||||||
} else {
|
} else {
|
||||||
Ok(CheckedData { data, checksum })
|
Ok(CheckedData { data, checksum })
|
||||||
}
|
}
|
||||||
|
@ -858,50 +860,50 @@ mod tests {
|
||||||
discriminant(
|
discriminant(
|
||||||
&test_varint_encode(0xFF, &(0x100000000_u64 - 1).to_le_bytes()).unwrap_err()
|
&test_varint_encode(0xFF, &(0x100000000_u64 - 1).to_le_bytes()).unwrap_err()
|
||||||
),
|
),
|
||||||
discriminant(&Error::NonMinimalVarInt)
|
discriminant(&ParseError::NonMinimalVarInt.into())
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
discriminant(&test_varint_encode(0xFE, &(0x10000_u64 - 1).to_le_bytes()).unwrap_err()),
|
discriminant(&test_varint_encode(0xFE, &(0x10000_u64 - 1).to_le_bytes()).unwrap_err()),
|
||||||
discriminant(&Error::NonMinimalVarInt)
|
discriminant(&ParseError::NonMinimalVarInt.into())
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
discriminant(&test_varint_encode(0xFD, &(0xFD_u64 - 1).to_le_bytes()).unwrap_err()),
|
discriminant(&test_varint_encode(0xFD, &(0xFD_u64 - 1).to_le_bytes()).unwrap_err()),
|
||||||
discriminant(&Error::NonMinimalVarInt)
|
discriminant(&ParseError::NonMinimalVarInt.into())
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
discriminant(&deserialize::<Vec<u8>>(&[0xfd, 0x00, 0x00]).unwrap_err()),
|
discriminant(&deserialize::<Vec<u8>>(&[0xfd, 0x00, 0x00]).unwrap_err()),
|
||||||
discriminant(&Error::NonMinimalVarInt)
|
discriminant(&ParseError::NonMinimalVarInt.into())
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
discriminant(&deserialize::<Vec<u8>>(&[0xfd, 0xfc, 0x00]).unwrap_err()),
|
discriminant(&deserialize::<Vec<u8>>(&[0xfd, 0xfc, 0x00]).unwrap_err()),
|
||||||
discriminant(&Error::NonMinimalVarInt)
|
discriminant(&ParseError::NonMinimalVarInt.into())
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
discriminant(&deserialize::<Vec<u8>>(&[0xfd, 0xfc, 0x00]).unwrap_err()),
|
discriminant(&deserialize::<Vec<u8>>(&[0xfd, 0xfc, 0x00]).unwrap_err()),
|
||||||
discriminant(&Error::NonMinimalVarInt)
|
discriminant(&ParseError::NonMinimalVarInt.into())
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
discriminant(&deserialize::<Vec<u8>>(&[0xfe, 0xff, 0x00, 0x00, 0x00]).unwrap_err()),
|
discriminant(&deserialize::<Vec<u8>>(&[0xfe, 0xff, 0x00, 0x00, 0x00]).unwrap_err()),
|
||||||
discriminant(&Error::NonMinimalVarInt)
|
discriminant(&ParseError::NonMinimalVarInt.into())
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
discriminant(&deserialize::<Vec<u8>>(&[0xfe, 0xff, 0xff, 0x00, 0x00]).unwrap_err()),
|
discriminant(&deserialize::<Vec<u8>>(&[0xfe, 0xff, 0xff, 0x00, 0x00]).unwrap_err()),
|
||||||
discriminant(&Error::NonMinimalVarInt)
|
discriminant(&ParseError::NonMinimalVarInt.into())
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
discriminant(
|
discriminant(
|
||||||
&deserialize::<Vec<u8>>(&[0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
|
&deserialize::<Vec<u8>>(&[0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
|
||||||
.unwrap_err()
|
.unwrap_err()
|
||||||
),
|
),
|
||||||
discriminant(&Error::NonMinimalVarInt)
|
discriminant(&ParseError::NonMinimalVarInt.into())
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
discriminant(
|
discriminant(
|
||||||
&deserialize::<Vec<u8>>(&[0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00])
|
&deserialize::<Vec<u8>>(&[0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00])
|
||||||
.unwrap_err()
|
.unwrap_err()
|
||||||
),
|
),
|
||||||
discriminant(&Error::NonMinimalVarInt)
|
discriminant(&ParseError::NonMinimalVarInt.into())
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut vec_256 = vec![0; 259];
|
let mut vec_256 = vec![0; 259];
|
||||||
|
@ -1031,7 +1033,10 @@ mod tests {
|
||||||
// by making sure it fails with `MissingData` and not an `OversizedVectorAllocation` Error.
|
// by making sure it fails with `MissingData` and not an `OversizedVectorAllocation` Error.
|
||||||
let err =
|
let err =
|
||||||
deserialize::<CheckedData>(&serialize(&(super::MAX_VEC_SIZE as u32))).unwrap_err();
|
deserialize::<CheckedData>(&serialize(&(super::MAX_VEC_SIZE as u32))).unwrap_err();
|
||||||
assert!(matches!(err, Error::MissingData));
|
match err {
|
||||||
|
Error::Io(e) => panic!("unexpected I/O error {}", e),
|
||||||
|
Error::Parse(e) => assert_eq!(e, ParseError::MissingData),
|
||||||
|
}
|
||||||
|
|
||||||
test_len_is_max_vec::<u8>();
|
test_len_is_max_vec::<u8>();
|
||||||
test_len_is_max_vec::<BlockHash>();
|
test_len_is_max_vec::<BlockHash>();
|
||||||
|
@ -1056,7 +1061,10 @@ mod tests {
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
buf.emit_compact_size(super::MAX_VEC_SIZE / mem::size_of::<T>()).unwrap();
|
buf.emit_compact_size(super::MAX_VEC_SIZE / mem::size_of::<T>()).unwrap();
|
||||||
let err = deserialize::<Vec<T>>(&buf).unwrap_err();
|
let err = deserialize::<Vec<T>>(&buf).unwrap_err();
|
||||||
assert!(matches!(err, Error::MissingData));
|
match err {
|
||||||
|
Error::Io(e) => panic!("unexpected I/O error {}", e),
|
||||||
|
Error::Parse(e) => assert_eq!(e, ParseError::MissingData),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -56,6 +56,54 @@ impl<E: fmt::Debug + std::error::Error + 'static> std::error::Error for DecodeEr
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// And I/O error.
|
/// And I/O error.
|
||||||
Io(io::Error),
|
Io(io::Error),
|
||||||
|
/// Error parsing encoded object.
|
||||||
|
Parse(ParseError),
|
||||||
|
}
|
||||||
|
|
||||||
|
internals::impl_from_infallible!(Error);
|
||||||
|
|
||||||
|
impl fmt::Display for Error {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
use Error::*;
|
||||||
|
|
||||||
|
match *self {
|
||||||
|
Io(ref e) => write_err!(f, "IO error"; e),
|
||||||
|
Parse(ref e) => write_err!(f, "error parsing encoded object"; e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
impl std::error::Error for Error {
|
||||||
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
|
use Error::*;
|
||||||
|
|
||||||
|
match *self {
|
||||||
|
Io(ref e) => Some(e),
|
||||||
|
Parse(ref e) => Some(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<io::Error> for Error {
|
||||||
|
fn from(e: io::Error) -> Self {
|
||||||
|
use io::ErrorKind;
|
||||||
|
|
||||||
|
match e.kind() {
|
||||||
|
ErrorKind::UnexpectedEof => Error::Parse(ParseError::MissingData),
|
||||||
|
_ => Error::Io(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ParseError> for Error {
|
||||||
|
fn from(e: ParseError) -> Self { Error::Parse(e) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Encoding is invalid.
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
#[non_exhaustive]
|
||||||
|
pub enum ParseError {
|
||||||
/// Missing data (early end of file or slice too short).
|
/// Missing data (early end of file or slice too short).
|
||||||
MissingData, // TODO: Can we add more context?
|
MissingData, // TODO: Can we add more context?
|
||||||
/// Tried to allocate an oversized vector.
|
/// Tried to allocate an oversized vector.
|
||||||
|
@ -80,14 +128,13 @@ pub enum Error {
|
||||||
UnsupportedSegwitFlag(u8),
|
UnsupportedSegwitFlag(u8),
|
||||||
}
|
}
|
||||||
|
|
||||||
internals::impl_from_infallible!(Error);
|
internals::impl_from_infallible!(ParseError);
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
impl fmt::Display for ParseError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
use Error::*;
|
use ParseError::*;
|
||||||
|
|
||||||
match *self {
|
match *self {
|
||||||
Io(ref e) => write_err!(f, "IO error"; e),
|
|
||||||
MissingData => write!(f, "missing data (early end of file or slice too short)"),
|
MissingData => write!(f, "missing data (early end of file or slice too short)"),
|
||||||
OversizedVectorAllocation { requested: ref r, max: ref m } =>
|
OversizedVectorAllocation { requested: ref r, max: ref m } =>
|
||||||
write!(f, "allocation of oversized vector: requested {}, maximum {}", r, m),
|
write!(f, "allocation of oversized vector: requested {}, maximum {}", r, m),
|
||||||
|
@ -102,12 +149,11 @@ impl fmt::Display for Error {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl std::error::Error for Error {
|
impl std::error::Error for ParseError {
|
||||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
use Error::*;
|
use ParseError::*;
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Io(e) => Some(e),
|
|
||||||
MissingData
|
MissingData
|
||||||
| OversizedVectorAllocation { .. }
|
| OversizedVectorAllocation { .. }
|
||||||
| InvalidChecksum { .. }
|
| InvalidChecksum { .. }
|
||||||
|
@ -118,17 +164,6 @@ impl std::error::Error for Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<io::Error> for Error {
|
|
||||||
fn from(e: io::Error) -> Self {
|
|
||||||
use io::ErrorKind;
|
|
||||||
|
|
||||||
match e.kind() {
|
|
||||||
ErrorKind::UnexpectedEof => Error::MissingData,
|
|
||||||
_ => Error::Io(e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Hex deserialization error.
|
/// Hex deserialization error.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum FromHexError {
|
pub enum FromHexError {
|
||||||
|
@ -169,4 +204,6 @@ impl From<OddLengthStringError> for FromHexError {
|
||||||
|
|
||||||
/// Constructs a `Error::ParseFailed` error.
|
/// Constructs a `Error::ParseFailed` error.
|
||||||
// This whole variant should go away because of the inner string.
|
// This whole variant should go away because of the inner string.
|
||||||
pub(crate) fn parse_failed_error(msg: &'static str) -> Error { Error::ParseFailed(msg) }
|
pub(crate) fn parse_failed_error(msg: &'static str) -> Error {
|
||||||
|
Error::Parse(ParseError::ParseFailed(msg))
|
||||||
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ use crate::consensus;
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
pub use self::{
|
pub use self::{
|
||||||
encode::{deserialize, deserialize_partial, serialize, Decodable, Encodable, ReadExt, WriteExt},
|
encode::{deserialize, deserialize_partial, serialize, Decodable, Encodable, ReadExt, WriteExt},
|
||||||
error::{Error, FromHexError, DecodeError},
|
error::{Error, FromHexError, DecodeError, ParseError},
|
||||||
};
|
};
|
||||||
pub(crate) use self::error::parse_failed_error;
|
pub(crate) use self::error::parse_failed_error;
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,7 @@ use serde::de::{SeqAccess, Unexpected, Visitor};
|
||||||
use serde::ser::SerializeSeq;
|
use serde::ser::SerializeSeq;
|
||||||
use serde::{Deserializer, Serializer};
|
use serde::{Deserializer, Serializer};
|
||||||
|
|
||||||
use super::encode::Error as ConsensusError;
|
use super::{Decodable, Encodable, Error, ParseError};
|
||||||
use super::{Decodable, Encodable};
|
|
||||||
use crate::consensus::{DecodeError, IterReader};
|
use crate::consensus::{DecodeError, IterReader};
|
||||||
|
|
||||||
/// Hex-encoding strategy
|
/// Hex-encoding strategy
|
||||||
|
@ -358,26 +357,25 @@ impl<D: fmt::Display> serde::de::Expected for DisplayExpected<D> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// not a trait impl because we panic on some variants
|
// not a trait impl because we panic on some variants
|
||||||
fn consensus_error_into_serde<E: serde::de::Error>(error: ConsensusError) -> E {
|
fn consensus_error_into_serde<E: serde::de::Error>(error: ParseError) -> E {
|
||||||
match error {
|
match error {
|
||||||
ConsensusError::Io(error) => panic!("unexpected IO error {:?}", error),
|
ParseError::MissingData =>
|
||||||
ConsensusError::MissingData =>
|
|
||||||
E::custom("missing data (early end of file or slice too short)"),
|
E::custom("missing data (early end of file or slice too short)"),
|
||||||
ConsensusError::OversizedVectorAllocation { requested, max } => E::custom(format_args!(
|
ParseError::OversizedVectorAllocation { requested, max } => E::custom(format_args!(
|
||||||
"the requested allocation of {} items exceeds maximum of {}",
|
"the requested allocation of {} items exceeds maximum of {}",
|
||||||
requested, max
|
requested, max
|
||||||
)),
|
)),
|
||||||
ConsensusError::InvalidChecksum { expected, actual } => E::invalid_value(
|
ParseError::InvalidChecksum { expected, actual } => E::invalid_value(
|
||||||
Unexpected::Bytes(&actual),
|
Unexpected::Bytes(&actual),
|
||||||
&DisplayExpected(format_args!(
|
&DisplayExpected(format_args!(
|
||||||
"checksum {:02x}{:02x}{:02x}{:02x}",
|
"checksum {:02x}{:02x}{:02x}{:02x}",
|
||||||
expected[0], expected[1], expected[2], expected[3]
|
expected[0], expected[1], expected[2], expected[3]
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
ConsensusError::NonMinimalVarInt =>
|
ParseError::NonMinimalVarInt =>
|
||||||
E::custom(format_args!("compact size was not encoded minimally")),
|
E::custom(format_args!("compact size was not encoded minimally")),
|
||||||
ConsensusError::ParseFailed(msg) => E::custom(msg),
|
ParseError::ParseFailed(msg) => E::custom(msg),
|
||||||
ConsensusError::UnsupportedSegwitFlag(flag) =>
|
ParseError::UnsupportedSegwitFlag(flag) =>
|
||||||
E::invalid_value(Unexpected::Unsigned(flag.into()), &"segwit version 1 flag"),
|
E::invalid_value(Unexpected::Unsigned(flag.into()), &"segwit version 1 flag"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -390,7 +388,9 @@ where
|
||||||
match self {
|
match self {
|
||||||
DecodeError::Other(error) => error,
|
DecodeError::Other(error) => error,
|
||||||
DecodeError::TooManyBytes => E::custom(format_args!("got more bytes than expected")),
|
DecodeError::TooManyBytes => E::custom(format_args!("got more bytes than expected")),
|
||||||
DecodeError::Consensus(error) => consensus_error_into_serde(error),
|
DecodeError::Consensus(Error::Parse(e)) => consensus_error_into_serde(e),
|
||||||
|
DecodeError::Consensus(Error::Io(_)) =>
|
||||||
|
unreachable!("iterator never returns I/O error"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -403,7 +403,9 @@ where
|
||||||
match self {
|
match self {
|
||||||
DecodeError::Other(error) => error.into_de_error(),
|
DecodeError::Other(error) => error.into_de_error(),
|
||||||
DecodeError::TooManyBytes => DE::custom(format_args!("got more bytes than expected")),
|
DecodeError::TooManyBytes => DE::custom(format_args!("got more bytes than expected")),
|
||||||
DecodeError::Consensus(error) => consensus_error_into_serde(error),
|
DecodeError::Consensus(Error::Parse(e)) => consensus_error_into_serde(e),
|
||||||
|
DecodeError::Consensus(Error::Io(_)) =>
|
||||||
|
unreachable!("iterator never returns I/O error"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -426,10 +426,11 @@ impl Decodable for PartialMerkleTree {
|
||||||
|
|
||||||
let nb_bytes_for_bits = r.read_compact_size()? as usize;
|
let nb_bytes_for_bits = r.read_compact_size()? as usize;
|
||||||
if nb_bytes_for_bits > MAX_VEC_SIZE {
|
if nb_bytes_for_bits > MAX_VEC_SIZE {
|
||||||
return Err(encode::Error::OversizedVectorAllocation {
|
return Err(encode::ParseError::OversizedVectorAllocation {
|
||||||
requested: nb_bytes_for_bits,
|
requested: nb_bytes_for_bits,
|
||||||
max: MAX_VEC_SIZE,
|
max: MAX_VEC_SIZE,
|
||||||
});
|
}
|
||||||
|
.into());
|
||||||
}
|
}
|
||||||
let mut bits = vec![false; nb_bytes_for_bits * 8];
|
let mut bits = vec![false; nb_bytes_for_bits * 8];
|
||||||
for chunk in bits.chunks_mut(8) {
|
for chunk in bits.chunks_mut(8) {
|
||||||
|
|
|
@ -82,10 +82,10 @@ impl Key {
|
||||||
let key_byte_size: u64 = byte_size - 1;
|
let key_byte_size: u64 = byte_size - 1;
|
||||||
|
|
||||||
if key_byte_size > MAX_VEC_SIZE.to_u64() {
|
if key_byte_size > MAX_VEC_SIZE.to_u64() {
|
||||||
return Err(encode::Error::OversizedVectorAllocation {
|
return Err(encode::Error::Parse(encode::ParseError::OversizedVectorAllocation {
|
||||||
requested: key_byte_size as usize,
|
requested: key_byte_size as usize,
|
||||||
max: MAX_VEC_SIZE,
|
max: MAX_VEC_SIZE,
|
||||||
}
|
})
|
||||||
.into());
|
.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue