fix(detect): fix possible memory leak

This commit is contained in:
Federico Terzi 2021-08-10 21:10:56 +02:00
parent a54d850cf3
commit 0f6c32350e

View File

@ -24,12 +24,11 @@ pub struct Keymap {
impl Keymap { impl Keymap {
pub fn new(context: &Context, rmlvo: Option<KeyboardConfig>) -> Result<Keymap> { pub fn new(context: &Context, rmlvo: Option<KeyboardConfig>) -> Result<Keymap> {
let owned_rmlvo = rmlvo.map(Self::generate_owned_rmlvo); let owned_rmlvo = Self::generate_owned_rmlvo(rmlvo);
let names = owned_rmlvo.as_ref().map(Self::generate_names); let names = Self::generate_names(&owned_rmlvo);
let names_ptr = names.map_or(std::ptr::null(), |names| &names);
let raw_keymap = unsafe { let raw_keymap = unsafe {
xkb_keymap_new_from_names(context.get_handle(), names_ptr, XKB_KEYMAP_COMPILE_NO_FLAGS) xkb_keymap_new_from_names(context.get_handle(), &names, XKB_KEYMAP_COMPILE_NO_FLAGS)
}; };
let keymap = scopeguard::guard(raw_keymap, |raw_keymap| unsafe { let keymap = scopeguard::guard(raw_keymap, |raw_keymap| unsafe {
xkb_keymap_unref(raw_keymap); xkb_keymap_unref(raw_keymap);
@ -48,54 +47,44 @@ impl Keymap {
self.keymap self.keymap
} }
fn generate_owned_rmlvo(rmlvo: KeyboardConfig) -> OwnedRawKeyboardConfig { fn generate_owned_rmlvo(rmlvo: Option<KeyboardConfig>) -> OwnedRawKeyboardConfig {
let rules = rmlvo let rules = rmlvo
.rules .as_ref()
.map(|s| CString::new(s).expect("unable to create CString for keymap")); .and_then(|config| config.rules.clone())
.unwrap_or_default();
let model = rmlvo let model = rmlvo
.model .as_ref()
.map(|s| CString::new(s).expect("unable to create CString for keymap")); .and_then(|config| config.model.clone())
.unwrap_or_default();
let layout = rmlvo let layout = rmlvo
.layout .as_ref()
.map(|s| CString::new(s).expect("unable to create CString for keymap")); .and_then(|config| config.layout.clone())
.unwrap_or_default();
let variant = rmlvo let variant = rmlvo
.variant .as_ref()
.map(|s| CString::new(s).expect("unable to create CString for keymap")); .and_then(|config| config.variant.clone())
.unwrap_or_default();
let options = rmlvo let options = rmlvo
.options .as_ref()
.map(|s| CString::new(s).expect("unable to create CString for keymap")); .and_then(|config| config.options.clone())
.unwrap_or_default();
OwnedRawKeyboardConfig { OwnedRawKeyboardConfig {
rules, rules: CString::new(rules).expect("unable to create CString for keymap"),
model, model: CString::new(model).expect("unable to create CString for keymap"),
layout, layout: CString::new(layout).expect("unable to create CString for keymap"),
variant, variant: CString::new(variant).expect("unable to create CString for keymap"),
options, options: CString::new(options).expect("unable to create CString for keymap"),
} }
} }
fn generate_names(owned_config: &OwnedRawKeyboardConfig) -> xkb_rule_names { fn generate_names(owned_config: &OwnedRawKeyboardConfig) -> xkb_rule_names {
xkb_rule_names { xkb_rule_names {
rules: owned_config rules: owned_config.rules.as_ptr(),
.rules model: owned_config.model.as_ptr(),
.as_ref() layout: owned_config.layout.as_ptr(),
.map_or(std::ptr::null(), |s| s.as_ptr()), variant: owned_config.variant.as_ptr(),
model: owned_config options: owned_config.options.as_ptr(),
.model
.as_ref()
.map_or(std::ptr::null(), |s| s.as_ptr()),
layout: owned_config
.layout
.as_ref()
.map_or(std::ptr::null(), |s| s.as_ptr()),
variant: owned_config
.variant
.as_ref()
.map_or(std::ptr::null(), |s| s.as_ptr()),
options: owned_config
.options
.as_ref()
.map_or(std::ptr::null(), |s| s.as_ptr()),
} }
} }
} }
@ -115,9 +104,9 @@ pub enum KeymapError {
} }
struct OwnedRawKeyboardConfig { struct OwnedRawKeyboardConfig {
rules: Option<CString>, rules: CString,
model: Option<CString>, model: CString,
layout: Option<CString>, layout: CString,
variant: Option<CString>, variant: CString,
options: Option<CString>, options: CString,
} }