From 02db20594d9ddb4bfeabf7d4889d8e1b84273033 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 27 Oct 2023 23:43:56 -0700 Subject: [PATCH] Update xdrgen --- Makefile | 2 +- src/curr/generated.rs | 36 ++++++++++++++++++++++++++++++------ src/next/generated.rs | 36 ++++++++++++++++++++++++++++++------ tests/vecm.rs | 36 +++++++++++++++++++++++++++++++++++- 4 files changed, 96 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index c0bb103d..c324785c 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ CARGO_HACK_ARGS=--feature-powerset --exclude-features default --group-features b CARGO_DOC_ARGS?=--open -XDRGEN_VERSION=64612a24 +XDRGEN_VERSION=f334abd0 XDRGEN_TYPES_CUSTOM_STR_IMPL=PublicKey,AccountId,MuxedAccount,MuxedAccountMed25519,SignerKey,SignerKeyEd25519SignedPayload,NodeId,ScAddress all: build test diff --git a/src/curr/generated.rs b/src/curr/generated.rs index 1870b4bd..638c93fc 100644 --- a/src/curr/generated.rs +++ b/src/curr/generated.rs @@ -71,6 +71,9 @@ use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, #[cfg(feature = "std")] use core::marker::PhantomData; +#[cfg(feature = "std")] +const MAX_PREALLOCATED_BYTES_READ: usize = 1024; // 1KB + // When feature alloc is turned off use static lifetime Box and Vec types. #[cfg(not(feature = "alloc"))] mod noalloc { @@ -1287,8 +1290,15 @@ impl ReadXdr for VecM { return Err(Error::LengthExceedsMax); } - let mut vec = vec![0u8; len as usize]; - r.read_exact(&mut vec)?; + let mut vec = vec![0u8; 0]; + let mut len_remaining = len as usize; + while len_remaining > 0 { + let len_read = core::cmp::min(len_remaining, MAX_PREALLOCATED_BYTES_READ); + let offset = vec.len(); + vec.resize(vec.len() + len_read, 0); + r.read_exact(&mut vec[offset..])?; + len_remaining -= len_read; + } let pad = &mut [0u8; 3][..pad_len(len as usize)]; r.read_exact(pad)?; @@ -1685,8 +1695,15 @@ impl ReadXdr for BytesM { return Err(Error::LengthExceedsMax); } - let mut vec = vec![0u8; len as usize]; - r.read_exact(&mut vec)?; + let mut vec = vec![0u8; 0]; + let mut len_remaining = len as usize; + while len_remaining > 0 { + let len_read = core::cmp::min(len_remaining, MAX_PREALLOCATED_BYTES_READ); + let offset = vec.len(); + vec.resize(vec.len() + len_read, 0); + r.read_exact(&mut vec[offset..])?; + len_remaining -= len_read; + } let pad = &mut [0u8; 3][..pad_len(len as usize)]; r.read_exact(pad)?; @@ -2068,8 +2085,15 @@ impl ReadXdr for StringM { return Err(Error::LengthExceedsMax); } - let mut vec = vec![0u8; len as usize]; - r.read_exact(&mut vec)?; + let mut vec = vec![0u8; 0]; + let mut len_remaining = len as usize; + while len_remaining > 0 { + let len_read = core::cmp::min(len_remaining, MAX_PREALLOCATED_BYTES_READ); + let offset = vec.len(); + vec.resize(vec.len() + len_read, 0); + r.read_exact(&mut vec[offset..])?; + len_remaining -= len_read; + } let pad = &mut [0u8; 3][..pad_len(len as usize)]; r.read_exact(pad)?; diff --git a/src/next/generated.rs b/src/next/generated.rs index 107c18f8..0a66fe96 100644 --- a/src/next/generated.rs +++ b/src/next/generated.rs @@ -71,6 +71,9 @@ use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, #[cfg(feature = "std")] use core::marker::PhantomData; +#[cfg(feature = "std")] +const MAX_PREALLOCATED_BYTES_READ: usize = 1024; // 1KB + // When feature alloc is turned off use static lifetime Box and Vec types. #[cfg(not(feature = "alloc"))] mod noalloc { @@ -1287,8 +1290,15 @@ impl ReadXdr for VecM { return Err(Error::LengthExceedsMax); } - let mut vec = vec![0u8; len as usize]; - r.read_exact(&mut vec)?; + let mut vec = vec![0u8; 0]; + let mut len_remaining = len as usize; + while len_remaining > 0 { + let len_read = core::cmp::min(len_remaining, MAX_PREALLOCATED_BYTES_READ); + let offset = vec.len(); + vec.resize(vec.len() + len_read, 0); + r.read_exact(&mut vec[offset..])?; + len_remaining -= len_read; + } let pad = &mut [0u8; 3][..pad_len(len as usize)]; r.read_exact(pad)?; @@ -1685,8 +1695,15 @@ impl ReadXdr for BytesM { return Err(Error::LengthExceedsMax); } - let mut vec = vec![0u8; len as usize]; - r.read_exact(&mut vec)?; + let mut vec = vec![0u8; 0]; + let mut len_remaining = len as usize; + while len_remaining > 0 { + let len_read = core::cmp::min(len_remaining, MAX_PREALLOCATED_BYTES_READ); + let offset = vec.len(); + vec.resize(vec.len() + len_read, 0); + r.read_exact(&mut vec[offset..])?; + len_remaining -= len_read; + } let pad = &mut [0u8; 3][..pad_len(len as usize)]; r.read_exact(pad)?; @@ -2068,8 +2085,15 @@ impl ReadXdr for StringM { return Err(Error::LengthExceedsMax); } - let mut vec = vec![0u8; len as usize]; - r.read_exact(&mut vec)?; + let mut vec = vec![0u8; 0]; + let mut len_remaining = len as usize; + while len_remaining > 0 { + let len_read = core::cmp::min(len_remaining, MAX_PREALLOCATED_BYTES_READ); + let offset = vec.len(); + vec.resize(vec.len() + len_read, 0); + r.read_exact(&mut vec[offset..])?; + len_remaining -= len_read; + } let pad = &mut [0u8; 3][..pad_len(len as usize)]; r.read_exact(pad)?; diff --git a/tests/vecm.rs b/tests/vecm.rs index ae899af0..1285cd1d 100644 --- a/tests/vecm.rs +++ b/tests/vecm.rs @@ -9,7 +9,7 @@ use stellar_xdr::curr as stellar_xdr; #[cfg(feature = "next")] use stellar_xdr::next as stellar_xdr; -use stellar_xdr::{ReadXdr, ScVal}; +use stellar_xdr::{BytesM, ReadXdr, ScVal}; #[test] fn valid_len() { @@ -42,3 +42,37 @@ fn invalid_len() { let result = ScVal::from_xdr(data); assert!(result.is_err()); } + +#[test] +fn valid_bytes_len() { + let data = [ + 0x00, 0x00, 0x00, 0x08, // length + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + ]; + let result: Result = BytesM::from_xdr(data); + assert_eq!( + result, + Ok(BytesM::try_from([1, 2, 3, 4, 5, 6, 7, 8]).unwrap()) + ); +} + +#[test] +fn valid_bytes_len_greater_than_preallocated_bytes_limit() { + let mut data = [0x01u8; 3000]; + data[0] = 0x00; // length + data[1] = 0x00; // length + data[2] = 0x0B; // length + data[3] = 0xB4; // length + let result: Result = BytesM::from_xdr(data); + assert_eq!(result, Ok(BytesM::try_from([0x01u8; 2996]).unwrap())); +} + +#[test] +fn invalid_bytes_len() { + let data = [ + 0xFF, 0xFF, 0xFF, 0xFF, // length + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + ]; + let result: Result = BytesM::from_xdr(data); + assert!(result.is_err()); +}