Skip to content

Commit fdbe88f

Browse files
committed
Verify struct and union identifiers in objc2-encode
1 parent 54be2ce commit fdbe88f

File tree

2 files changed

+43
-7
lines changed

2 files changed

+43
-7
lines changed

objc2-encode/src/encoding.rs

+17-5
Original file line numberDiff line numberDiff line change
@@ -489,11 +489,6 @@ mod tests {
489489
!"{SomeStruct=}";
490490
}
491491
492-
fn struct_unicode() {
493-
Encoding::Struct("☃", &[Encoding::Char]);
494-
"{☃=c}";
495-
}
496-
497492
fn pointer_struct() {
498493
Encoding::Pointer(&Encoding::Struct("SomeStruct", &[Encoding::Char, Encoding::Int]));
499494
!Encoding::Pointer(&Encoding::Struct("SomeStruct", &[Encoding::Int, Encoding::Char]));
@@ -590,5 +585,22 @@ mod tests {
590585
);
591586
"{abc=^[8B](def=@?)^^b255?}";
592587
}
588+
589+
fn identifier() {
590+
Encoding::Struct("_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", &[]);
591+
"{_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=}";
592+
}
593+
}
594+
595+
#[test]
596+
#[should_panic = "Struct name was not a valid identifier"]
597+
fn struct_unicode() {
598+
let _ = Encoding::Struct("☃", &[Encoding::Char]).to_string();
599+
}
600+
601+
#[test]
602+
#[should_panic = "Union name was not a valid identifier"]
603+
fn union_invalid_identifier() {
604+
let _ = Encoding::Union("a-b", &[Encoding::Char]).equivalent_to_str("(☃=c)");
593605
}
594606
}

objc2-encode/src/helper.rs

+26-2
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,32 @@ impl<'a> Helper<'a> {
198198
Pointer(t) => Self::Indirection(IndirectionKind::Pointer, t),
199199
Atomic(t) => Self::Indirection(IndirectionKind::Atomic, t),
200200
Array(len, item) => Self::Array(len, item),
201-
Struct(name, fields) => Self::Container(ContainerKind::Struct, name, fields),
202-
Union(name, members) => Self::Container(ContainerKind::Union, name, members),
201+
Struct(name, fields) => {
202+
if !verify_name(name) {
203+
panic!("Struct name was not a valid identifier");
204+
}
205+
Self::Container(ContainerKind::Struct, name, fields)
206+
}
207+
Union(name, members) => {
208+
if !verify_name(name) {
209+
panic!("Union name was not a valid identifier");
210+
}
211+
Self::Container(ContainerKind::Union, name, members)
212+
}
203213
}
204214
}
205215
}
216+
217+
/// Check whether the name is a valid identifier
218+
const fn verify_name(name: &str) -> bool {
219+
let bytes = name.as_bytes();
220+
let mut i = 0;
221+
while i < bytes.len() {
222+
let byte = bytes[i];
223+
if !(byte.is_ascii_alphanumeric() || byte == b'_') {
224+
return false;
225+
}
226+
i += 1;
227+
}
228+
true
229+
}

0 commit comments

Comments
 (0)