From: Matt Corallo Date: Sat, 30 Jan 2021 22:15:22 +0000 (-0500) Subject: [bindings] Allow cloning opaque types when inner is NULL X-Git-Tag: v0.0.13~32^2~2 X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=03a6a243ac2752763942f414f2ac3a93b29aabc2;p=rust-lightning [bindings] Allow cloning opaque types when inner is NULL Previously we'd segfault trying to deref the NULL page, but there is no reason to not simply clone by creating another opaque instance with a null inner. This comes up specifically when cloning ChannelSigners as the pubkeys instance is NULL on construction before get_pubkeys is called. --- diff --git a/c-bindings-gen/src/main.rs b/c-bindings-gen/src/main.rs index d927d2ae..97fc9b87 100644 --- a/c-bindings-gen/src/main.rs +++ b/c-bindings-gen/src/main.rs @@ -559,7 +559,8 @@ fn writeln_opaque(w: &mut W, ident: &syn::Ident, struct_name: writeln!(w, "impl Clone for {} {{", struct_name).unwrap(); writeln!(w, "\tfn clone(&self) -> Self {{").unwrap(); writeln!(w, "\t\tSelf {{").unwrap(); - writeln!(w, "\t\t\tinner: Box::into_raw(Box::new(unsafe {{ &*self.inner }}.clone())),").unwrap(); + writeln!(w, "\t\t\tinner: if self.inner.is_null() {{ std::ptr::null_mut() }} else {{").unwrap(); + writeln!(w, "\t\t\t\tBox::into_raw(Box::new(unsafe {{ &*self.inner }}.clone())) }},").unwrap(); writeln!(w, "\t\t\tis_owned: true,").unwrap(); writeln!(w, "\t\t}}\n\t}}\n}}").unwrap(); writeln!(w, "#[allow(unused)]").unwrap(); @@ -569,7 +570,7 @@ fn writeln_opaque(w: &mut W, ident: &syn::Ident, struct_name: writeln!(w, "}}").unwrap(); writeln!(w, "#[no_mangle]").unwrap(); writeln!(w, "pub extern \"C\" fn {}_clone(orig: &{}) -> {} {{", struct_name, struct_name, struct_name).unwrap(); - writeln!(w, "\t{} {{ inner: Box::into_raw(Box::new(unsafe {{ &*orig.inner }}.clone())), is_owned: true }}", struct_name).unwrap(); + writeln!(w, "\torig.clone()").unwrap(); writeln!(w, "}}").unwrap(); }