structure.rs: Fix passing a dangling pointer (!)

If we have "x: Option<String>", and try to pass a C string to a C
function like

  some_c_func (x.map_or (ptr::null (), |s| String::to_glib_none (&s).0));

Then some_c_func() gets a dangling pointer.  The Stash that glib-rs
creates to store the temporary C string only has the lifetime of the
closure, so by the time some_c_func() is called, the Stash has already
been dropped.

I understand that *that* happens; I don't understand why Rust lets us
get away with it (maybe because we are just passing pointers around, and
not ownership-tracked references?)

This is the Valgrind log, FWIW:

            let class = property_bag::lookup (pbag, "class");
            let id = property_bag::lookup (pbag, "id");

            unsafe { rsvg_parse_style_attrs (handle,
                                             raw_node,
                                             str::to_glib_none ("svg").0,
                                             class.map_or (ptr::null (), |s| String::to_glib_none (&s).0),
                                             id.map_or (ptr::null (), |s| String::to_glib_none (&s).0),
                                             pbag); }

==7321== Invalid read of size 1
==7321==    at 0x4C2F2A2: strlen (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==7321==    by 0x795DD89: vfprintf (in /lib64/libc-2.25.so)
==7321==    by 0x7A0F807: __vasprintf_chk (in /lib64/libc-2.25.so)
==7321==    by 0x6E294A8: g_vasprintf (in /usr/lib64/libglib-2.0.so.0.5200.1)
==7321==    by 0x6E03FBC: g_strdup_vprintf (in /usr/lib64/libglib-2.0.so.0.5200.1)
==7321==    by 0x6E04078: g_strdup_printf (in /usr/lib64/libglib-2.0.so.0.5200.1)
==7321==    by 0x4E76221: rsvg_parse_style_attrs (rsvg-styles.c:1493)
==7321==    by 0x4F45621: rsvg_internals::structure::rsvg_node_svg_apply_atts::_$u7b$$u7b$closure$u7d$$u7d$::hb7b2d3cd2f7c7d5d (structure.rs:561)
==7321==    by 0x4EDB68C: rsvg_internals::node::Node::with_impl::h88684eea38e6e1fd (node.rs:201)
==7321==    by 0x4F452D6: rsvg_node_svg_apply_atts (structure.rs:554)
==7321==    by 0x4E79BDE: rsvg_end_element (rsvg-base.c:847)
==7321==    by 0x57C676C: ??? (in /usr/lib64/libxml2.so.2.9.4)
==7321==  Address 0xc313360 is 0 bytes inside a block of size 9 free'd
==7321==    at 0x4C2D2DB: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==7321==    by 0x4EBB97C: alloc::heap::deallocate::h6e0d0f9d31bcfa2f (heap.rs:113)
==7321==    by 0x4EBBC3B: alloc::heap::box_free::h18dbd884648a8b49 (heap.rs:162)
==7321==    by 0x4EB41B2: drop::h4f84cb290e8a5854 (in /home/federico/src/librsvg-latest/.libs/librsvg-2.so.2.41.1)
==7321==    by 0x4E867F8: drop_contents::h929e7f93fb30bf14 (in /home/federico/src/librsvg-latest/.libs/librsvg-2.so.2.41.1)
==7321==    by 0x4EB4FD6: drop::h929e7f93fb30bf14 (in /home/federico/src/librsvg-latest/.libs/librsvg-2.so.2.41.1)
==7321==    by 0x4EB4B4C: drop::h78bf7138ba782926 (in /home/federico/src/librsvg-latest/.libs/librsvg-2.so.2.41.1)
==7321==    by 0x4F453E8: rsvg_internals::structure::rsvg_node_svg_apply_atts::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h66dfed3b9ec8f9dc (structure.rs:565)
==7321==    by 0x4E8F406: _$LT$core..option..Option$LT$T$GT$$GT$::map_or::h31e2639fe31ed744 (option.rs:404)
==7321==    by 0x4F455E9: rsvg_internals::structure::rsvg_node_svg_apply_atts::_$u7b$$u7b$closure$u7d$$u7d$::hb7b2d3cd2f7c7d5d (structure.rs:565)
==7321==    by 0x4EDB68C: rsvg_internals::node::Node::with_impl::h88684eea38e6e1fd (node.rs:201)
==7321==    by 0x4F452D6: rsvg_node_svg_apply_atts (structure.rs:554)
==7321==  Block was alloc'd at
==7321==    at 0x4C2E2CF: realloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==7321==    by 0x4FFBED1: reallocate (heap.rs:79)
==7321==    by 0x4FFBED1: reserve_exact<u8> (raw_vec.rs:319)
==7321==    by 0x4FFBED1: reserve_exact<u8> (vec.rs:479)
==7321==    by 0x4FFBED1: std::ffi::c_str::CString::from_vec_unchecked::hb6396f8c4a1f41e5 (c_str.rs:224)
==7321==    by 0x4FFBE61: std::ffi::c_str::CString::_new::h4d618af53b7229c0 (c_str.rs:201)
==7321==    by 0x4E98318: std::ffi::c_str::CString::new::h12e4003256bfa812 (c_str.rs:195)
==7321==    by 0x4E83989: _$LT$collections..string..String$u20$as$u20$glib..translate..ToGlibPtr$LT$$u27$a$C$$u20$$BP$const$u20$i8$GT$$GT$::to_glib_none::h5555f4a2685fe24b (translate.rs:360)
==7321==    by 0x4F453BB: rsvg_internals::structure::rsvg_node_svg_apply_atts::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h66dfed3b9ec8f9dc (structure.rs:565)
==7321==    by 0x4E8F406: _$LT$core..option..Option$LT$T$GT$$GT$::map_or::h31e2639fe31ed744 (option.rs:404)
==7321==    by 0x4F455E9: rsvg_internals::structure::rsvg_node_svg_apply_atts::_$u7b$$u7b$closure$u7d$$u7d$::hb7b2d3cd2f7c7d5d (structure.rs:565)
==7321==    by 0x4EDB68C: rsvg_internals::node::Node::with_impl::h88684eea38e6e1fd (node.rs:201)
==7321==    by 0x4F452D6: rsvg_node_svg_apply_atts (structure.rs:554)
==7321==    by 0x4E79BDE: rsvg_end_element (rsvg-base.c:847)
==7321==    by 0x57C676C: ??? (in /usr/lib64/libxml2.so.2.9.4)
parent 24d736b5
......@@ -558,11 +558,14 @@ pub extern fn rsvg_node_svg_apply_atts (raw_node: *const RsvgNode, handle: *cons
let class = property_bag::lookup (pbag, "class");
let id = property_bag::lookup (pbag, "id");
let c_class = class.to_glib_none ();
let c_id = id.to_glib_none ();
unsafe { rsvg_parse_style_attrs (handle,
raw_node,
str::to_glib_none ("svg").0,
class.map_or (ptr::null (), |s| String::to_glib_none (&s).0),
id.map_or (ptr::null (), |s| String::to_glib_none (&s).0),
c_class.0,
c_id.0,
pbag); }
}
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment