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



commit d0d393ffa0ce98b9dd86ccd428b385a0bfa8dba2
Author: Federico Mena Quintero <federico gnome org>
Date:   Mon May 22 07:50:41 2017 -0500

    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)

 rust/src/structure.rs |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)
---
diff --git a/rust/src/structure.rs b/rust/src/structure.rs
index b7c51dc..c891941 100644
--- a/rust/src/structure.rs
+++ b/rust/src/structure.rs
@@ -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); }
         }
     });


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]