summaryrefslogtreecommitdiffstats
path: root/third_party/rust/parity-wasm/src/elements/primitives.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/parity-wasm/src/elements/primitives.rs')
-rw-r--r--third_party/rust/parity-wasm/src/elements/primitives.rs902
1 files changed, 902 insertions, 0 deletions
diff --git a/third_party/rust/parity-wasm/src/elements/primitives.rs b/third_party/rust/parity-wasm/src/elements/primitives.rs
new file mode 100644
index 0000000000..149419f20b
--- /dev/null
+++ b/third_party/rust/parity-wasm/src/elements/primitives.rs
@@ -0,0 +1,902 @@
+use alloc::{string::String, vec::Vec};
+use crate::{io, elements};
+use super::{Error, Deserialize, Serialize};
+
+/// Unsigned variable-length integer, limited to 32 bits,
+/// represented by at most 5 bytes that may contain padding 0x80 bytes.
+#[derive(Debug, Copy, Clone, PartialEq)]
+pub struct VarUint32(u32);
+
+impl From<VarUint32> for usize {
+ fn from(var: VarUint32) -> usize {
+ var.0 as usize
+ }
+}
+
+impl From<VarUint32> for u32 {
+ fn from(var: VarUint32) -> u32 {
+ var.0
+ }
+}
+
+impl From<u32> for VarUint32 {
+ fn from(i: u32) -> VarUint32 {
+ VarUint32(i)
+ }
+}
+
+impl From<usize> for VarUint32 {
+ fn from(i: usize) -> VarUint32 {
+ assert!(i <= u32::max_value() as usize);
+ VarUint32(i as u32)
+ }
+}
+
+impl Deserialize for VarUint32 {
+ type Error = Error;
+
+ fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
+ let mut res = 0;
+ let mut shift = 0;
+ let mut u8buf = [0u8; 1];
+ loop {
+ if shift > 31 { return Err(Error::InvalidVarUint32); }
+
+ reader.read(&mut u8buf)?;
+ let b = u8buf[0] as u32;
+ res |= (b & 0x7f).checked_shl(shift).ok_or(Error::InvalidVarUint32)?;
+ shift += 7;
+ if (b >> 7) == 0 {
+ if shift >= 32 && (b as u8).leading_zeros() < 4 {
+ return Err(Error::InvalidVarInt32);
+ }
+ break;
+ }
+ }
+ Ok(VarUint32(res))
+ }
+}
+
+impl Serialize for VarUint32 {
+ type Error = Error;
+
+ fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
+ let mut buf = [0u8; 1];
+ let mut v = self.0;
+ loop {
+ buf[0] = (v & 0b0111_1111) as u8;
+ v >>= 7;
+ if v > 0 {
+ buf[0] |= 0b1000_0000;
+ }
+ writer.write(&buf[..])?;
+ if v == 0 { break; }
+ }
+
+ Ok(())
+ }
+}
+
+/// Unsigned variable-length integer, limited to 64 bits,
+/// represented by at most 9 bytes that may contain padding 0x80 bytes.
+#[derive(Debug, Copy, Clone, PartialEq)]
+pub struct VarUint64(u64);
+
+impl From<VarUint64> for u64 {
+ fn from(var: VarUint64) -> u64 {
+ var.0
+ }
+}
+
+impl Deserialize for VarUint64 {
+ type Error = Error;
+
+ fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
+ let mut res = 0;
+ let mut shift = 0;
+ let mut u8buf = [0u8; 1];
+ loop {
+ if shift > 63 { return Err(Error::InvalidVarUint64); }
+
+ reader.read(&mut u8buf)?;
+ let b = u8buf[0] as u64;
+ res |= (b & 0x7f).checked_shl(shift).ok_or(Error::InvalidVarUint64)?;
+ shift += 7;
+ if (b >> 7) == 0 {
+ if shift >= 64 && (b as u8).leading_zeros() < 7 {
+ return Err(Error::InvalidVarInt64);
+ }
+ break;
+ }
+ }
+ Ok(VarUint64(res))
+ }
+}
+
+impl Serialize for VarUint64 {
+ type Error = Error;
+
+ fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
+ let mut buf = [0u8; 1];
+ let mut v = self.0;
+ loop {
+ buf[0] = (v & 0b0111_1111) as u8;
+ v >>= 7;
+ if v > 0 {
+ buf[0] |= 0b1000_0000;
+ }
+ writer.write(&buf[..])?;
+ if v == 0 { break; }
+ }
+
+ Ok(())
+ }
+}
+
+impl From<u64> for VarUint64 {
+ fn from(u: u64) -> VarUint64 {
+ VarUint64(u)
+ }
+}
+
+/// 7-bit unsigned integer, encoded in LEB128 (always 1 byte length).
+#[derive(Debug, Copy, Clone, PartialEq)]
+pub struct VarUint7(u8);
+
+impl From<VarUint7> for u8 {
+ fn from(v: VarUint7) -> u8 {
+ v.0
+ }
+}
+
+impl From<u8> for VarUint7 {
+ fn from(v: u8) -> Self {
+ VarUint7(v)
+ }
+}
+
+impl Deserialize for VarUint7 {
+ type Error = Error;
+
+ fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
+ let mut u8buf = [0u8; 1];
+ reader.read(&mut u8buf)?;
+ Ok(VarUint7(u8buf[0]))
+ }
+}
+
+impl Serialize for VarUint7 {
+ type Error = Error;
+
+ fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
+ // todo check range?
+ writer.write(&[self.0])?;
+ Ok(())
+ }
+}
+
+/// 7-bit signed integer, encoded in LEB128 (always 1 byte length)
+#[derive(Debug, Copy, Clone, PartialEq)]
+pub struct VarInt7(i8);
+
+impl From<VarInt7> for i8 {
+ fn from(v: VarInt7) -> i8 {
+ v.0
+ }
+}
+
+impl From<i8> for VarInt7 {
+ fn from(v: i8) -> VarInt7 {
+ VarInt7(v)
+ }
+}
+
+impl Deserialize for VarInt7 {
+ type Error = Error;
+
+ fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
+ let mut u8buf = [0u8; 1];
+ reader.read(&mut u8buf)?;
+
+ // check if number is not continued!
+ if u8buf[0] & 0b1000_0000 != 0 {
+ return Err(Error::InvalidVarInt7(u8buf[0]));
+ }
+
+ // expand sign
+ if u8buf[0] & 0b0100_0000 == 0b0100_0000 { u8buf[0] |= 0b1000_0000 }
+
+ Ok(VarInt7(u8buf[0] as i8))
+ }
+}
+
+impl Serialize for VarInt7 {
+ type Error = Error;
+
+ fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
+ // todo check range?
+ let mut b: u8 = self.0 as u8;
+ if self.0 < 0 { b |= 0b0100_0000; b &= 0b0111_1111; }
+ writer.write(&[b])?;
+ Ok(())
+ }
+}
+
+/// 8-bit unsigned integer, NOT encoded in LEB128;
+/// it's just a single byte.
+#[derive(Debug, Copy, Clone, PartialEq)]
+pub struct Uint8(u8);
+
+impl From<Uint8> for u8 {
+ fn from(v: Uint8) -> u8 {
+ v.0
+ }
+}
+
+impl From<u8> for Uint8 {
+ fn from(v: u8) -> Self {
+ Uint8(v)
+ }
+}
+
+impl Deserialize for Uint8 {
+ type Error = Error;
+
+ fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
+ let mut u8buf = [0u8; 1];
+ reader.read(&mut u8buf)?;
+ Ok(Uint8(u8buf[0]))
+ }
+}
+
+impl Serialize for Uint8 {
+ type Error = Error;
+
+ fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
+ writer.write(&[self.0])?;
+ Ok(())
+ }
+}
+
+
+/// 32-bit signed integer, encoded in LEB128 (can be 1-5 bytes length).
+#[derive(Debug, Copy, Clone, PartialEq)]
+pub struct VarInt32(i32);
+
+impl From<VarInt32> for i32 {
+ fn from(v: VarInt32) -> i32 {
+ v.0
+ }
+}
+
+impl From<i32> for VarInt32 {
+ fn from(v: i32) -> VarInt32 {
+ VarInt32(v)
+ }
+}
+
+impl Deserialize for VarInt32 {
+ type Error = Error;
+
+ fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
+ let mut res = 0;
+ let mut shift = 0;
+ let mut u8buf = [0u8; 1];
+ loop {
+ if shift > 31 { return Err(Error::InvalidVarInt32); }
+ reader.read(&mut u8buf)?;
+ let b = u8buf[0];
+
+ res |= ((b & 0x7f) as i32).checked_shl(shift).ok_or(Error::InvalidVarInt32)?;
+
+ shift += 7;
+ if (b >> 7) == 0 {
+ if shift < 32 && b & 0b0100_0000 == 0b0100_0000 {
+ res |= (1i32 << shift).wrapping_neg();
+ } else if shift >= 32 && b & 0b0100_0000 == 0b0100_0000 {
+ if (!(b | 0b1000_0000)).leading_zeros() < 5 {
+ return Err(Error::InvalidVarInt32);
+ }
+ } else if shift >= 32 && b & 0b0100_0000 == 0 {
+ if b.leading_zeros() < 5 {
+ return Err(Error::InvalidVarInt32);
+ }
+ }
+ break;
+ }
+ }
+ Ok(VarInt32(res))
+ }
+}
+
+impl Serialize for VarInt32 {
+ type Error = Error;
+
+ fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
+ let mut buf = [0u8; 1];
+ let mut v = self.0;
+ let mut more = true;
+ while more {
+ buf[0] = (v & 0b0111_1111) as u8;
+ v >>= 7;
+ if (v == 0 && buf[0] & 0b0100_0000 == 0) || (v == -1 && buf[0] & 0b0100_0000 == 0b0100_0000) {
+ more = false
+ } else {
+ buf[0] |= 0b1000_0000
+ }
+
+ writer.write(&buf[..])?;
+ }
+
+ Ok(())
+ }
+}
+
+/// 64-bit signed integer, encoded in LEB128 (can be 1-9 bytes length).
+#[derive(Debug, Copy, Clone, PartialEq)]
+pub struct VarInt64(i64);
+
+impl From<VarInt64> for i64 {
+ fn from(v: VarInt64) -> i64 {
+ v.0
+ }
+}
+
+impl From<i64> for VarInt64 {
+ fn from(v: i64) -> VarInt64 {
+ VarInt64(v)
+ }
+}
+
+impl Deserialize for VarInt64 {
+ type Error = Error;
+
+ fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
+ let mut res = 0i64;
+ let mut shift = 0;
+ let mut u8buf = [0u8; 1];
+
+ loop {
+ if shift > 63 { return Err(Error::InvalidVarInt64); }
+ reader.read(&mut u8buf)?;
+ let b = u8buf[0];
+
+ res |= ((b & 0x7f) as i64).checked_shl(shift).ok_or(Error::InvalidVarInt64)?;
+
+ shift += 7;
+ if (b >> 7) == 0 {
+ if shift < 64 && b & 0b0100_0000 == 0b0100_0000 {
+ res |= (1i64 << shift).wrapping_neg();
+ } else if shift >= 64 && b & 0b0100_0000 == 0b0100_0000 {
+ if (b | 0b1000_0000) as i8 != -1 {
+ return Err(Error::InvalidVarInt64);
+ }
+ } else if shift >= 64 && b != 0 {
+ return Err(Error::InvalidVarInt64);
+ }
+ break;
+ }
+ }
+ Ok(VarInt64(res))
+ }
+}
+
+impl Serialize for VarInt64 {
+ type Error = Error;
+
+ fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
+ let mut buf = [0u8; 1];
+ let mut v = self.0;
+ let mut more = true;
+ while more {
+ buf[0] = (v & 0b0111_1111) as u8;
+ v >>= 7;
+ if (v == 0 && buf[0] & 0b0100_0000 == 0) || (v == -1 && buf[0] & 0b0100_0000 == 0b0100_0000) {
+ more = false
+ } else {
+ buf[0] |= 0b1000_0000
+ }
+
+ writer.write(&buf[..])?;
+ }
+
+ Ok(())
+ }
+}
+
+/// 32-bit unsigned integer, encoded in little endian.
+#[derive(Debug, Copy, Clone, PartialEq)]
+pub struct Uint32(u32);
+
+impl Deserialize for Uint32 {
+ type Error = Error;
+
+ fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
+ let mut buf = [0u8; 4];
+ reader.read(&mut buf)?;
+ // todo check range
+ Ok(u32::from_le_bytes(buf).into())
+ }
+}
+
+impl From<Uint32> for u32 {
+ fn from(var: Uint32) -> u32 {
+ var.0
+ }
+}
+
+impl Serialize for Uint32 {
+ type Error = Error;
+
+ fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
+ writer.write(&self.0.to_le_bytes())?;
+ Ok(())
+ }
+}
+
+impl From<u32> for Uint32 {
+ fn from(u: u32) -> Self { Uint32(u) }
+}
+
+/// 64-bit unsigned integer, encoded in little endian.
+#[derive(Debug, Copy, Clone, PartialEq)]
+pub struct Uint64(u64);
+
+impl Deserialize for Uint64 {
+ type Error = Error;
+
+ fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
+ let mut buf = [0u8; 8];
+ reader.read(&mut buf)?;
+ // todo check range
+ Ok(u64::from_le_bytes(buf).into())
+ }
+}
+
+impl Serialize for Uint64 {
+ type Error = Error;
+
+ fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
+ writer.write(&self.0.to_le_bytes())?;
+ Ok(())
+ }
+}
+
+impl From<u64> for Uint64 {
+ fn from(u: u64) -> Self { Uint64(u) }
+}
+
+impl From<Uint64> for u64 {
+ fn from(var: Uint64) -> u64 {
+ var.0
+ }
+}
+
+
+/// VarUint1, 1-bit value (0/1).
+#[derive(Debug, Copy, Clone, PartialEq)]
+pub struct VarUint1(bool);
+
+impl From<VarUint1> for bool {
+ fn from(v: VarUint1) -> bool {
+ v.0
+ }
+}
+
+impl From<bool> for VarUint1 {
+ fn from(b: bool) -> Self {
+ VarUint1(b)
+ }
+}
+
+impl Deserialize for VarUint1 {
+ type Error = Error;
+
+ fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
+ let mut u8buf = [0u8; 1];
+ reader.read(&mut u8buf)?;
+ match u8buf[0] {
+ 0 => Ok(VarUint1(false)),
+ 1 => Ok(VarUint1(true)),
+ v @ _ => Err(Error::InvalidVarUint1(v)),
+ }
+ }
+}
+
+impl Serialize for VarUint1 {
+ type Error = Error;
+
+ fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
+ writer.write(&[
+ if self.0 { 1u8 } else { 0u8 }
+ ])?;
+ Ok(())
+ }
+}
+
+impl Deserialize for String {
+ type Error = Error;
+
+ fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
+ let length = u32::from(VarUint32::deserialize(reader)?) as usize;
+ if length > 0 {
+ String::from_utf8(buffered_read!(1024, length, reader)).map_err(|_| Error::NonUtf8String)
+ }
+ else {
+ Ok(String::new())
+ }
+ }
+}
+
+impl Serialize for String {
+ type Error = Error;
+
+ fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Error> {
+ VarUint32::from(self.len()).serialize(writer)?;
+ writer.write(&self.into_bytes()[..])?;
+ Ok(())
+ }
+}
+
+/// List for reading sequence of elements typed `T`, given
+/// they are preceded by length (serialized as VarUint32).
+#[derive(Debug, Clone)]
+pub struct CountedList<T: Deserialize>(Vec<T>);
+
+impl<T: Deserialize> CountedList<T> {
+ /// Destroy counted list returing inner vector.
+ pub fn into_inner(self) -> Vec<T> { self.0 }
+}
+
+impl<T: Deserialize> Deserialize for CountedList<T> where T::Error: From<Error> {
+ type Error = T::Error;
+
+ fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
+ let count: usize = VarUint32::deserialize(reader)?.into();
+ let mut result = Vec::new();
+ for _ in 0..count { result.push(T::deserialize(reader)?); }
+ Ok(CountedList(result))
+ }
+}
+
+/// Helper struct to write payload which is preceded by
+/// it's own length in bytes.
+#[derive(Debug)]
+pub struct CountedWriter<'a, W: 'a + io::Write> {
+ writer: &'a mut W,
+ data: Vec<u8>,
+}
+
+impl<'a, W: 'a + io::Write> CountedWriter<'a, W> {
+ /// New counted writer on top of the given serial writer.
+ pub fn new(writer: &'a mut W) -> Self {
+ CountedWriter {
+ writer: writer,
+ data: Vec::new(),
+ }
+ }
+
+ /// Finish counted writer routing, which writes accumulated length
+ /// and actual payload.
+ pub fn done(self) -> io::Result<()> {
+ let writer = self.writer;
+ let data = self.data;
+ VarUint32::from(data.len())
+ .serialize(writer)
+ .map_err(|_| io::Error::InvalidData)?;
+ writer.write(&data[..])?;
+ Ok(())
+ }
+}
+
+impl<'a, W: 'a + io::Write> io::Write for CountedWriter<'a, W> {
+ fn write(&mut self, buf: &[u8]) -> io::Result<()> {
+ self.data.extend_from_slice(buf);
+ Ok(())
+ }
+}
+
+/// Helper struct to write series of `T` preceded by the length of the sequence
+/// serialized as VarUint32.
+#[derive(Debug, Clone)]
+pub struct CountedListWriter<I: Serialize<Error=elements::Error>, T: IntoIterator<Item=I>>(pub usize, pub T);
+
+impl<I: Serialize<Error=elements::Error>, T: IntoIterator<Item=I>> Serialize for CountedListWriter<I, T> {
+ type Error = Error;
+
+ fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
+ let len_us = self.0;
+ let data = self.1;
+ let len: VarUint32 = len_us.into();
+ len.serialize(writer)?;
+ for data_element in data { data_element.serialize(writer)? }
+
+ Ok(())
+ }
+}
+
+
+#[cfg(test)]
+mod tests {
+
+ use super::super::{deserialize_buffer, Serialize};
+ use super::{CountedList, VarInt7, VarUint32, VarInt32, VarInt64, VarUint64};
+ use crate::elements::Error;
+
+ fn varuint32_ser_test(val: u32, expected: Vec<u8>) {
+ let mut buf = Vec::new();
+ let v1: VarUint32 = val.into();
+ v1.serialize(&mut buf).expect("to be serialized ok");
+ assert_eq!(expected, buf);
+ }
+
+ fn varuint32_de_test(dt: Vec<u8>, expected: u32) {
+ let val: VarUint32 = super::super::deserialize_buffer(&dt).expect("buf to be serialized");
+ assert_eq!(expected, val.into());
+ }
+
+ fn varuint32_serde_test(dt: Vec<u8>, val: u32) {
+ varuint32_de_test(dt.clone(), val);
+ varuint32_ser_test(val, dt);
+ }
+
+ fn varint32_ser_test(val: i32, expected: Vec<u8>) {
+ let mut buf = Vec::new();
+ let v1: VarInt32 = val.into();
+ v1.serialize(&mut buf).expect("to be serialized ok");
+ assert_eq!(expected, buf);
+ }
+
+ fn varint32_de_test(dt: Vec<u8>, expected: i32) {
+ let val: VarInt32 = super::super::deserialize_buffer(&dt).expect("buf to be serialized");
+ assert_eq!(expected, val.into());
+ }
+
+ fn varint32_serde_test(dt: Vec<u8>, val: i32) {
+ varint32_de_test(dt.clone(), val);
+ varint32_ser_test(val, dt);
+ }
+
+ fn varuint64_ser_test(val: u64, expected: Vec<u8>) {
+ let mut buf = Vec::new();
+ let v1: VarUint64 = val.into();
+ v1.serialize(&mut buf).expect("to be serialized ok");
+ assert_eq!(expected, buf);
+ }
+
+ fn varuint64_de_test(dt: Vec<u8>, expected: u64) {
+ let val: VarUint64 = super::super::deserialize_buffer(&dt).expect("buf to be serialized");
+ assert_eq!(expected, val.into());
+ }
+
+ fn varuint64_serde_test(dt: Vec<u8>, val: u64) {
+ varuint64_de_test(dt.clone(), val);
+ varuint64_ser_test(val, dt);
+ }
+
+ fn varint64_ser_test(val: i64, expected: Vec<u8>) {
+ let mut buf = Vec::new();
+ let v1: VarInt64 = val.into();
+ v1.serialize(&mut buf).expect("to be serialized ok");
+ assert_eq!(expected, buf);
+ }
+
+ fn varint64_de_test(dt: Vec<u8>, expected: i64) {
+ let val: VarInt64 = super::super::deserialize_buffer(&dt).expect("buf to be serialized");
+ assert_eq!(expected, val.into());
+ }
+
+ fn varint64_serde_test(dt: Vec<u8>, val: i64) {
+ varint64_de_test(dt.clone(), val);
+ varint64_ser_test(val, dt);
+ }
+
+ #[test]
+ fn varuint32_0() {
+ varuint32_serde_test(vec![0u8; 1], 0);
+ }
+
+ #[test]
+ fn varuint32_1() {
+ varuint32_serde_test(vec![1u8; 1], 1);
+ }
+
+ #[test]
+ fn varuint32_135() {
+ varuint32_serde_test(vec![135u8, 0x01], 135);
+ }
+
+ #[test]
+ fn varuint32_8192() {
+ varuint32_serde_test(vec![0x80, 0x40], 8192);
+ }
+
+ #[test]
+ fn varint32_8192() {
+ varint32_serde_test(vec![0x80, 0xc0, 0x00], 8192);
+ }
+
+ #[test]
+ fn varint32_neg_8192() {
+ varint32_serde_test(vec![0x80, 0x40], -8192);
+ }
+
+ #[test]
+ fn varuint64_0() {
+ varuint64_serde_test(vec![0u8; 1], 0);
+ }
+
+ #[test]
+ fn varuint64_1() {
+ varuint64_serde_test(vec![1u8; 1], 1);
+ }
+
+ #[test]
+ fn varuint64_135() {
+ varuint64_serde_test(vec![135u8, 0x01], 135);
+ }
+
+ #[test]
+ fn varuint64_8192() {
+ varuint64_serde_test(vec![0x80, 0x40], 8192);
+ }
+
+ #[test]
+ fn varint64_8192() {
+ varint64_serde_test(vec![0x80, 0xc0, 0x00], 8192);
+ }
+
+ #[test]
+ fn varint64_neg_8192() {
+ varint64_serde_test(vec![0x80, 0x40], -8192);
+ }
+
+ #[test]
+ fn varint64_min() {
+ varint64_serde_test(
+ vec![0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f],
+ -9223372036854775808,
+ );
+ }
+
+ #[test]
+ fn varint64_bad_extended() {
+ let res = deserialize_buffer::<VarInt64>(&[0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x6f][..]);
+ assert!(res.is_err());
+ }
+
+ #[test]
+ fn varint32_bad_extended() {
+ let res = deserialize_buffer::<VarInt32>(&[0x80, 0x80, 0x80, 0x80, 0x6f][..]);
+ assert!(res.is_err());
+ }
+
+ #[test]
+ fn varint32_bad_extended2() {
+ let res = deserialize_buffer::<VarInt32>(&[0x80, 0x80, 0x80, 0x80, 0x41][..]);
+ assert!(res.is_err());
+ }
+
+ #[test]
+ fn varint64_max() {
+ varint64_serde_test(
+ vec![0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00],
+ 9223372036854775807,
+ );
+ }
+
+ #[test]
+ fn varint64_too_long() {
+ assert!(
+ deserialize_buffer::<VarInt64>(
+ &[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00][..],
+ ).is_err()
+ );
+ }
+
+ #[test]
+ fn varint32_too_long() {
+ assert!(
+ deserialize_buffer::<VarInt32>(
+ &[0xff, 0xff, 0xff, 0xff, 0xff, 0x00][..],
+ ).is_err()
+ );
+ }
+
+ #[test]
+ fn varuint64_too_long() {
+ assert!(
+ deserialize_buffer::<VarUint64>(
+ &[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00][..],
+ ).is_err()
+ );
+ }
+
+ #[test]
+ fn varuint32_too_long() {
+ assert!(
+ deserialize_buffer::<VarUint32>(
+ &[0xff, 0xff, 0xff, 0xff, 0xff, 0x00][..],
+ ).is_err()
+ );
+ }
+
+ #[test]
+ fn varuint32_too_long_trailing() {
+ assert!(
+ deserialize_buffer::<VarUint32>(
+ &[0xff, 0xff, 0xff, 0xff, 0x7f][..],
+ ).is_err()
+ );
+ }
+
+ #[test]
+ fn varuint64_too_long_trailing() {
+ assert!(
+ deserialize_buffer::<VarUint64>(
+ &[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x04][..],
+ ).is_err()
+ );
+ }
+
+ #[test]
+ fn varint32_min() {
+ varint32_serde_test(
+ vec![0x80, 0x80, 0x80, 0x80, 0x78],
+ -2147483648,
+ );
+ }
+
+ #[test]
+ fn varint7_invalid() {
+ match deserialize_buffer::<VarInt7>(&[240]) {
+ Err(Error::InvalidVarInt7(_)) => {},
+ _ => panic!("Should be invalid varint7 error!")
+ }
+ }
+
+ #[test]
+ fn varint7_neg() {
+ assert_eq!(-0x10i8, deserialize_buffer::<VarInt7>(&[0x70]).expect("fail").into());
+ }
+
+ #[test]
+ fn varuint32_too_long_nulled() {
+ match deserialize_buffer::<VarUint32>(
+ &[0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x78]
+ ) {
+ Err(Error::InvalidVarUint32) => {},
+ _ => panic!("Should be invalid varuint32"),
+ }
+ }
+
+ #[test]
+ fn varint32_max() {
+ varint32_serde_test(
+ vec![0xff, 0xff, 0xff, 0xff, 0x07],
+ 2147483647,
+ );
+ }
+
+
+ #[test]
+ fn counted_list() {
+ let payload = [
+ 133u8, //(128+5), length is 5
+ 0x80, 0x80, 0x80, 0x0, // padding
+ 0x01,
+ 0x7d,
+ 0x05,
+ 0x07,
+ 0x09,
+ ];
+
+ let list: CountedList<VarInt7> =
+ deserialize_buffer(&payload).expect("type_section be deserialized");
+
+ let vars = list.into_inner();
+ assert_eq!(5, vars.len());
+ let v3: i8 = (*vars.get(1).unwrap()).into();
+ assert_eq!(-0x03i8, v3);
+ }
+}