Skip to content
  • Federico Mena Quintero's avatar
    structure.rs: Fix passing a dangling pointer (!) · d0d393ff
    Federico Mena Quintero authored
    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)
    d0d393ff