Skip to content

Commit d728e9f

Browse files
niemeyertwistedfall
authored andcommitted
src/templ.rs: fix handling of C string slices
CommandLineParser is currently misbehaving due to improper data in its input argv parameter. The problem is caused by a blind cast of argv entries from &str into a C-like string, which does not offer the null termination guarantees. To fix that, create an actual CString and hold it while the pointer is in use. It's worth noting that the mutable version of the macro still relies on undefined behavior, but this time of CString which does not guarantee correctness if its data is written into.
1 parent c2ff7dc commit d728e9f

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

src/templ.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,17 +79,26 @@ macro_rules! string_array_arg {
7979
($name: ident) => {
8080
let $name = $name
8181
.iter()
82-
.map(|x| x.as_ptr().cast::<::std::ffi::c_char>())
82+
.map(|x| ::std::ffi::CString::new(*x).expect("invalid C string"))
83+
.collect::<::std::vec::Vec<_>>();
84+
let $name = $name
85+
.iter()
86+
.map(|x| x.as_ptr())
8387
.collect::<::std::vec::Vec<_>>();
8488
};
8589
}
8690

8791
#[allow(unused_macros)]
8892
macro_rules! string_array_arg_mut {
8993
($name: ident) => {
94+
let $name = $name
95+
.iter()
96+
.map(|x| ::std::ffi::CString::new(*x).expect("invalid C string"))
97+
.collect::<::std::vec::Vec<_>>();
98+
// Casting to mut below trusts on undefined CString behavior.
9099
let mut $name = $name
91100
.iter()
92-
.map(|x| x.as_ptr().cast::<::std::ffi::c_char>().cast_mut())
101+
.map(|x| x.as_ptr().cast_mut())
93102
.collect::<::std::vec::Vec<_>>();
94103
};
95104
}

0 commit comments

Comments
 (0)