Skip to content

Commit

Permalink
Fix string length validation for non ascii strings (#776)
Browse files Browse the repository at this point in the history
  • Loading branch information
NicoSchmidt1703 authored Feb 20, 2025
1 parent 01fc57b commit cd34ab5
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 5 deletions.
4 changes: 2 additions & 2 deletions typify-impl/src/type_entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1513,7 +1513,7 @@ impl TypeEntry {
let v = v as usize;
let err = format!("longer than {} characters", v);
quote! {
if value.len() > #v {
if value.chars().count() > #v {
return Err(#err.into());
}
}
Expand All @@ -1522,7 +1522,7 @@ impl TypeEntry {
let v = v as usize;
let err = format!("shorter than {} characters", v);
quote! {
if value.len() < #v {
if value.chars().count() < #v {
return Err(#err.into());
}
}
Expand Down
20 changes: 20 additions & 0 deletions typify-test/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,25 @@ impl JsonSchema for LoginName {
}
}

struct NonAsciiChars;
impl JsonSchema for NonAsciiChars {
fn schema_name() -> String {
"NonAsciiChars".to_string()
}

fn json_schema(_: &mut schemars::gen::SchemaGenerator) -> Schema {
schemars::schema::SchemaObject {
string: Some(Box::new(schemars::schema::StringValidation {
max_length: Some(8),
min_length: Some(2),
pattern: None,
})),
..Default::default()
}
.into()
}
}

struct Pancakes;
impl JsonSchema for Pancakes {
fn schema_name() -> String {
Expand Down Expand Up @@ -109,6 +128,7 @@ fn main() {

WithSet::add(&mut type_space);
LoginName::add(&mut type_space);
NonAsciiChars::add(&mut type_space);
UnknownFormat::add(&mut type_space);
ipnetwork::IpNetwork::add(&mut type_space);

Expand Down
6 changes: 6 additions & 0 deletions typify-test/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ fn test_string_constraints() {
assert!(LoginName::try_from("ahl").is_ok());
}

#[test]
fn test_string_constraints_for_non_ascii_chars() {
assert!(NonAsciiChars::try_from("🍔🍔🍔🍔🍔🍔🍔🍔").is_ok());
assert!(NonAsciiChars::try_from("🍔").is_err());
}

#[test]
fn test_unknown_format() {
// An unknown format string should just render as a string.
Expand Down
2 changes: 1 addition & 1 deletion typify/tests/schemas/id-or-name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ impl ::std::convert::From<&Name> for Name {
impl ::std::str::FromStr for Name {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.len() > 63usize {
if value.chars().count() > 63usize {
return Err("longer than 63 characters".into());
}
if regress :: Regex :: new ("^(?![0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$)^[a-z][a-z0-9-]*[a-zA-Z0-9]$") . unwrap () . find (value) . is_none () { return Err ("doesn't match pattern \"^(?![0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$)^[a-z][a-z0-9-]*[a-zA-Z0-9]$\"" . into ()) ; }
Expand Down
4 changes: 2 additions & 2 deletions typify/tests/schemas/rust-collisions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1511,10 +1511,10 @@ impl ::std::convert::From<&StringNewtype> for StringNewtype {
impl ::std::str::FromStr for StringNewtype {
type Err = self::error::ConversionError;
fn from_str(value: &str) -> ::std::result::Result<Self, self::error::ConversionError> {
if value.len() > 100usize {
if value.chars().count() > 100usize {
return Err("longer than 100 characters".into());
}
if value.len() < 1usize {
if value.chars().count() < 1usize {
return Err("shorter than 1 characters".into());
}
Ok(Self(value.to_string()))
Expand Down

0 comments on commit cd34ab5

Please sign in to comment.