Skip to content

Commit

Permalink
Verify struct and union identifiers in objc2-encode
Browse files Browse the repository at this point in the history
  • Loading branch information
madsmtm committed Aug 9, 2022
1 parent 54be2ce commit fdbe88f
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 7 deletions.
22 changes: 17 additions & 5 deletions objc2-encode/src/encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -489,11 +489,6 @@ mod tests {
!"{SomeStruct=}";
}
fn struct_unicode() {
Encoding::Struct("☃", &[Encoding::Char]);
"{☃=c}";
}

fn pointer_struct() {
Encoding::Pointer(&Encoding::Struct("SomeStruct", &[Encoding::Char, Encoding::Int]));
!Encoding::Pointer(&Encoding::Struct("SomeStruct", &[Encoding::Int, Encoding::Char]));
Expand Down Expand Up @@ -590,5 +585,22 @@ mod tests {
);
"{abc=^[8B](def=@?)^^b255?}";
}
fn identifier() {
Encoding::Struct("_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", &[]);
"{_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=}";
}
}
#[test]
#[should_panic = "Struct name was not a valid identifier"]
fn struct_unicode() {
let _ = Encoding::Struct("☃", &[Encoding::Char]).to_string();
}

#[test]
#[should_panic = "Union name was not a valid identifier"]
fn union_invalid_identifier() {
let _ = Encoding::Union("a-b", &[Encoding::Char]).equivalent_to_str("(☃=c)");
}
}
28 changes: 26 additions & 2 deletions objc2-encode/src/helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,32 @@ impl<'a> Helper<'a> {
Pointer(t) => Self::Indirection(IndirectionKind::Pointer, t),
Atomic(t) => Self::Indirection(IndirectionKind::Atomic, t),
Array(len, item) => Self::Array(len, item),
Struct(name, fields) => Self::Container(ContainerKind::Struct, name, fields),
Union(name, members) => Self::Container(ContainerKind::Union, name, members),
Struct(name, fields) => {
if !verify_name(name) {
panic!("Struct name was not a valid identifier");
}
Self::Container(ContainerKind::Struct, name, fields)
}
Union(name, members) => {
if !verify_name(name) {
panic!("Union name was not a valid identifier");
}
Self::Container(ContainerKind::Union, name, members)
}
}
}
}

/// Check whether the name is a valid identifier
const fn verify_name(name: &str) -> bool {
let bytes = name.as_bytes();
let mut i = 0;
while i < bytes.len() {
let byte = bytes[i];
if !(byte.is_ascii_alphanumeric() || byte == b'_') {
return false;
}
i += 1;
}
true
}

0 comments on commit fdbe88f

Please sign in to comment.