From f4d57a66522183d4927b47af422e8f321182111f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Laignel?= Date: Mon, 11 Jun 2018 22:21:51 +0200 Subject: [PATCH] Fix memory issue building a `Sample` with an `info` `Structure` The following code in a `[test]`: ``` rust let info = Structure::builder("sample.info") .field("f3", &123i32) .build(); let sample = Sample::new::( None, None, None, Some(info.as_ref()) ); ``` generates one of the followings executing `cargo test`: ``` - segmentation fault - signal: 6, SIGABRT: process abort signal - signal: 11, SIGSEGV: invalid memory reference ``` This is due to `ffi::gst_sample_new` expecting to take ownership of the `info` `Structure`. --- gstreamer/src/sample.rs | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/gstreamer/src/sample.rs b/gstreamer/src/sample.rs index b65778c8a..07f8f7286 100644 --- a/gstreamer/src/sample.rs +++ b/gstreamer/src/sample.rs @@ -22,6 +22,7 @@ use Caps; use FormattedSegment; use FormattedValue; use Segment; +use Structure; use StructureRef; pub type Sample = GstRc; @@ -36,16 +37,16 @@ impl GstRc { buffer: Option<&Buffer>, caps: Option<&Caps>, segment: Option<&FormattedSegment>, - info: Option<&StructureRef>, + info: Option, ) -> Self { assert_initialized_main_thread!(); unsafe { - let info = info.map(|i| i.as_ptr()).unwrap_or(ptr::null()); + let info = info.map(|i| i.into_ptr()).unwrap_or(ptr::null_mut()); from_glib_full(ffi::gst_sample_new( buffer.to_glib_none().0, caps.to_glib_none().0, - mut_override(segment.to_glib_none().0), + segment.to_glib_none().0, mut_override(info), )) } @@ -55,7 +56,7 @@ impl GstRc { buffer_list: Option<&BufferList>, caps: Option<&Caps>, segment: Option<&FormattedSegment>, - info: Option<&StructureRef>, + info: Option, ) -> Self { assert_initialized_main_thread!(); let sample = Self::new(None, caps, segment, info); @@ -122,3 +123,23 @@ impl fmt::Debug for SampleRef { unsafe impl Sync for SampleRef {} unsafe impl Send for SampleRef {} + +#[cfg(test)] +mod tests { + + #[test] + fn test_sample_new_with_info() { + use GenericFormattedValue; + use Sample; + use Structure; + + ::init().unwrap(); + + let info = Structure::builder("sample.info") + .field("f3", &123i32) + .build(); + let sample = Sample::new::(None, None, None, Some(info)); + + assert!(sample.get_info().is_some()); + } +}