Skip to content

Commit 1f84001

Browse files
Fix StringM::from_str max length validation (#500)
* validate StringM max length in from_str * Update tests/stringm.rs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 336e78c commit 1f84001

4 files changed

Lines changed: 71 additions & 14 deletions

File tree

src/curr/generated.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1976,7 +1976,7 @@ impl<const MAX: u32> core::str::FromStr for StringM<MAX> {
19761976
type Err = Error;
19771977
fn from_str(s: &str) -> core::result::Result<Self, Self::Err> {
19781978
let b = escape_bytes::unescape(s.as_bytes()).map_err(|_| Error::Invalid)?;
1979-
Ok(Self(b))
1979+
b.try_into()
19801980
}
19811981
}
19821982

src/next/generated.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1976,7 +1976,7 @@ impl<const MAX: u32> core::str::FromStr for StringM<MAX> {
19761976
type Err = Error;
19771977
fn from_str(s: &str) -> core::result::Result<Self, Self::Err> {
19781978
let b = escape_bytes::unescape(s.as_bytes()).map_err(|_| Error::Invalid)?;
1979-
Ok(Self(b))
1979+
b.try_into()
19801980
}
19811981
}
19821982

tests/stringm.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#![cfg(all(
2+
any(feature = "curr", feature = "next"),
3+
not(all(feature = "curr", feature = "next"))
4+
))]
5+
#![cfg(feature = "std")]
6+
7+
#[cfg(feature = "curr")]
8+
use stellar_xdr::curr as stellar_xdr;
9+
#[cfg(feature = "next")]
10+
use stellar_xdr::next as stellar_xdr;
11+
12+
use stellar_xdr::{Error, StringM};
13+
14+
use std::str::FromStr;
15+
16+
#[test]
17+
fn stringm_from_str_at_max() {
18+
// Exactly at the limit should succeed.
19+
let result = StringM::<3>::from_str("abc");
20+
assert!(result.is_ok());
21+
assert_eq!(result.unwrap().as_vec(), b"abc");
22+
}
23+
24+
#[test]
25+
fn stringm_from_str_within_max() {
26+
// Within the limit should succeed.
27+
let result = StringM::<3>::from_str("ab");
28+
assert!(result.is_ok());
29+
assert_eq!(result.unwrap().as_vec(), b"ab");
30+
}
31+
32+
#[test]
33+
fn stringm_from_str_exceeding_max() {
34+
let result = StringM::<3>::from_str("abcd");
35+
assert_eq!(result, Err(Error::LengthExceedsMax));
36+
}
37+
38+
#[test]
39+
fn stringm_from_str_empty() {
40+
let result = StringM::<3>::from_str("");
41+
assert!(result.is_ok());
42+
assert_eq!(result.unwrap().as_vec(), b"");
43+
}

xdr-generator/generator/header.rs

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ use std::string::FromUtf8Error;
3333
#[cfg(feature = "arbitrary")]
3434
use arbitrary::Arbitrary;
3535

36-
#[cfg(all(feature = "schemars", feature = "alloc", feature = "std"))]
37-
use std::borrow::Cow;
3836
#[cfg(all(feature = "schemars", feature = "alloc", not(feature = "std")))]
3937
use alloc::borrow::Cow;
38+
#[cfg(all(feature = "schemars", feature = "alloc", feature = "std"))]
39+
use std::borrow::Cow;
4040

4141
// TODO: Add support for read/write xdr fns when std not available.
4242

@@ -72,11 +72,11 @@ pub enum Error {
7272
impl PartialEq for Error {
7373
fn eq(&self, other: &Self) -> bool {
7474
match (self, other) {
75-
(Self::Invalid, Self::Invalid)
76-
| (Self::Unsupported, Self::Unsupported)
75+
(Self::Invalid, Self::Invalid)
76+
| (Self::Unsupported, Self::Unsupported)
7777
| (Self::LengthExceedsMax, Self::LengthExceedsMax)
78-
| (Self::LengthMismatch, Self::LengthMismatch)
79-
| (Self::NonZeroPadding, Self::NonZeroPadding) => true,
78+
| (Self::LengthMismatch, Self::LengthMismatch)
79+
| (Self::NonZeroPadding, Self::NonZeroPadding) => true,
8080

8181
(Self::Utf8Error(l), Self::Utf8Error(r)) => l == r,
8282

@@ -605,7 +605,7 @@ where
605605
base64::engine::general_purpose::GeneralPurpose,
606606
SkipWhitespace<&mut R>,
607607
>,
608-
Self
608+
Self,
609609
> {
610610
let dec = base64::read::DecoderReader::new(
611611
SkipWhitespace::new(&mut r.inner),
@@ -940,7 +940,11 @@ impl<T: WriteXdr, const N: usize> WriteXdr for [T; N] {
940940

941941
#[cfg(feature = "alloc")]
942942
#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
943-
#[cfg_attr(feature = "serde", serde_with::serde_as, derive(serde::Serialize, serde::Deserialize))]
943+
#[cfg_attr(
944+
feature = "serde",
945+
serde_with::serde_as,
946+
derive(serde::Serialize, serde::Deserialize)
947+
)]
944948
#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
945949
pub struct VecM<T, const MAX: u32 = { u32::MAX }>(Vec<T>);
946950

@@ -1022,7 +1026,11 @@ where
10221026
where
10231027
S: serde::Serializer,
10241028
{
1025-
serializer.collect_seq(source.iter().map(|item| serde_with::ser::SerializeAsWrap::<T, U>::new(item)))
1029+
serializer.collect_seq(
1030+
source
1031+
.iter()
1032+
.map(|item| serde_with::ser::SerializeAsWrap::<T, U>::new(item)),
1033+
)
10261034
}
10271035
}
10281036

@@ -1895,7 +1903,7 @@ impl<const MAX: u32> core::str::FromStr for StringM<MAX> {
18951903
type Err = Error;
18961904
fn from_str(s: &str) -> core::result::Result<Self, Self::Err> {
18971905
let b = escape_bytes::unescape(s.as_bytes()).map_err(|_| Error::Invalid)?;
1898-
Ok(Self(b))
1906+
b.try_into()
18991907
}
19001908
}
19011909

@@ -3171,7 +3179,10 @@ mod tests_for_number_or_string {
31713179
fn deserialize_i64_from_json_reader() {
31723180
let json = r#"{"val": "123"}"#;
31733181
let expected = TestI64 { val: 123 };
3174-
assert_eq!(serde_json::from_reader::<_, TestI64>(Cursor::new(json)).unwrap(), expected);
3182+
assert_eq!(
3183+
serde_json::from_reader::<_, TestI64>(Cursor::new(json)).unwrap(),
3184+
expected
3185+
);
31753186
}
31763187

31773188
#[test]
@@ -3470,7 +3481,10 @@ mod tests_for_number_or_string {
34703481
fn deserialize_u64_from_json_reader() {
34713482
let json = r#"{"val": "123"}"#;
34723483
let expected = TestU64 { val: 123 };
3473-
assert_eq!(serde_json::from_reader::<_, TestU64>(Cursor::new(json)).unwrap(), expected);
3484+
assert_eq!(
3485+
serde_json::from_reader::<_, TestU64>(Cursor::new(json)).unwrap(),
3486+
expected
3487+
);
34743488
}
34753489

34763490
#[test]

0 commit comments

Comments
 (0)