From 03a6a243ac2752763942f414f2ac3a93b29aabc2 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sat, 30 Jan 2021 17:15:22 -0500 Subject: [PATCH] [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. --- c-bindings-gen/src/main.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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(); } -- 2.30.2