From 0e256957ba03735e600e6a1625f49f3fc646e9ec Mon Sep 17 00:00:00 2001 From: Rafael Caricio Date: Sat, 13 Jun 2020 16:27:02 +0200 Subject: [PATCH] Fix UB --- examples/button_click.rs | 2 +- lvgl-codegen/src/lib.rs | 46 ++++++++++++++++++++++++++++++++++++++-- lvgl-sys/vendor/lvgl | 2 +- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/examples/button_click.rs b/examples/button_click.rs index 364ce37..420ab84 100644 --- a/examples/button_click.rs +++ b/examples/button_click.rs @@ -92,7 +92,7 @@ fn main() -> Result<(), LvError> { } } - sleep(Duration::from_millis(25)); + sleep(Duration::from_millis(5)); } stop_ch.send(true).unwrap(); diff --git a/lvgl-codegen/src/lib.rs b/lvgl-codegen/src/lib.rs index 9f37505..f4e308e 100644 --- a/lvgl-codegen/src/lib.rs +++ b/lvgl-codegen/src/lib.rs @@ -18,6 +18,7 @@ lazy_static! { ("int32_t", "i32"), ("uint8_t", "u8"), ("bool", "bool"), + ("_Bool", "bool"), ("const char *", "&str"), ] .iter() @@ -148,6 +149,30 @@ impl Rusty for LvFunc { } }); + let args_processing = self + .args + .iter() + .enumerate() + .fold(quote!(), |args, (i, arg)| { + // if first arg is `const`, then it should be immutable + let next_arg = if i == 0 { + quote!() + } else { + let var = arg.get_processing(); + quote!(#var) + }; + if args.is_empty() { + quote! { + #next_arg + } + } else { + quote! { + #args + #next_arg + } + } + }); + let args_call = self .args .iter() @@ -174,6 +199,7 @@ impl Rusty for LvFunc { // TODO: Handle methods that return types Ok(quote! { pub fn #func_name(#args_decl) -> crate::LvResult<()> { + #args_processing unsafe { lvgl_sys::#original_func_name(#args_call); } @@ -215,15 +241,30 @@ impl LvArg { } pub fn get_name_ident(&self) -> Ident { + // Filter Rust language keywords syn::parse_str::(self.name.as_str()) .unwrap_or_else(|_| format_ident!("r#{}", self.name.as_str())) } + pub fn get_processing(&self) -> TokenStream { + let ident = self.get_name_ident(); + // TODO: A better way to handle this, instead of `is_sometype()`, is using the Rust + // type system itself. + if self.typ.is_str() { + quote! { + let #ident = cstr_core::CString::new(#ident)?; + } + } else { + // No need to pre-process this type of argument + quote! {} + } + } + pub fn get_value_usage(&self) -> TokenStream { let ident = self.get_name_ident(); if self.typ.is_str() { quote! { - cstr_core::CString::new(#ident).unwrap().into_raw() + #ident.as_ptr() } } else { quote! { @@ -499,10 +540,11 @@ mod test { let code = label_set_text.code(&parent_widget).unwrap(); let expected_code = quote! { pub fn set_text(&mut self, text: &str) -> crate::LvResult<()> { + let text = cstr_core::CString::new(text)?; unsafe { lvgl_sys::lv_label_set_text( self.core.raw()?.as_mut(), - cstr_core::CString::new(text).unwrap().into_raw() + text.as_ptr() ); } Ok(()) diff --git a/lvgl-sys/vendor/lvgl b/lvgl-sys/vendor/lvgl index 91b9977..1ca1934 160000 --- a/lvgl-sys/vendor/lvgl +++ b/lvgl-sys/vendor/lvgl @@ -1 +1 @@ -Subproject commit 91b997769e7a2b7eb410371725b1e3a7cb6ecde8 +Subproject commit 1ca1934dbe8e826ef1ed1690005fb678fea3a1f3