Handle empty slices correctly

Passing `NULL` to `slice::from_raw_parts` is invalid.
This commit is contained in:
Sebastian Dröge 2022-02-07 12:21:13 +02:00
parent ddd4e3a79a
commit 0173b73170
11 changed files with 90 additions and 13 deletions

View file

@ -341,6 +341,10 @@ impl<T> AudioBufferRef<T> {
)); ));
} }
if self.plane_size() == 0 {
return Ok(&[]);
}
unsafe { unsafe {
Ok(slice::from_raw_parts( Ok(slice::from_raw_parts(
(*self.audio_buffer.planes.add(plane as usize)) as *const u8, (*self.audio_buffer.planes.add(plane as usize)) as *const u8,
@ -470,6 +474,10 @@ impl<'a> AudioBufferRef<&'a mut gst::BufferRef> {
)); ));
} }
if self.plane_size() == 0 {
return Ok(&mut []);
}
unsafe { unsafe {
Ok(slice::from_raw_parts_mut( Ok(slice::from_raw_parts_mut(
(*self.audio_buffer.planes.add(plane as usize)) as *mut u8, (*self.audio_buffer.planes.add(plane as usize)) as *mut u8,

View file

@ -294,7 +294,11 @@ unsafe extern "C" fn audiosink_write<T: AudioSinkImpl>(
let instance = &*(ptr as *mut T::Instance); let instance = &*(ptr as *mut T::Instance);
let imp = instance.imp(); let imp = instance.imp();
let wrap: Borrowed<AudioSink> = from_glib_borrow(ptr); let wrap: Borrowed<AudioSink> = from_glib_borrow(ptr);
let data_slice = std::slice::from_raw_parts(data as *const u8, length as usize); let data_slice = if length == 0 {
&[]
} else {
std::slice::from_raw_parts(data as *const u8, length as usize)
};
gst::panic_to_error!(&wrap, imp.panicked(), -1, { gst::panic_to_error!(&wrap, imp.panicked(), -1, {
imp.write(wrap.unsafe_cast_ref(), data_slice).unwrap_or(-1) imp.write(wrap.unsafe_cast_ref(), data_slice).unwrap_or(-1)

View file

@ -311,7 +311,11 @@ unsafe extern "C" fn audiosrc_read<T: AudioSrcImpl>(
let instance = &*(ptr as *mut T::Instance); let instance = &*(ptr as *mut T::Instance);
let imp = instance.imp(); let imp = instance.imp();
let wrap: Borrowed<AudioSrc> = from_glib_borrow(ptr); let wrap: Borrowed<AudioSrc> = from_glib_borrow(ptr);
let data_slice = std::slice::from_raw_parts_mut(data as *mut u8, length as usize); let data_slice = if length == 0 {
&mut []
} else {
std::slice::from_raw_parts_mut(data as *mut u8, length as usize)
};
gst::panic_to_error!(&wrap, imp.panicked(), 0, { gst::panic_to_error!(&wrap, imp.panicked(), 0, {
let (res, timestamp_res) = imp let (res, timestamp_res) = imp

View file

@ -333,7 +333,11 @@ impl<'a, T> RTPBuffer<'a, T> {
&mut size, &mut size,
)); ));
if result { if result {
if size == 0 {
Some(&[])
} else {
Some(slice::from_raw_parts(data as *const u8, size as usize)) Some(slice::from_raw_parts(data as *const u8, size as usize))
}
} else { } else {
None None
} }
@ -358,10 +362,14 @@ impl<'a, T> RTPBuffer<'a, T> {
&mut size, &mut size,
)); ));
if result { if result {
if size == 0 {
Some((appbits, &[]))
} else {
Some(( Some((
appbits, appbits,
slice::from_raw_parts(data as *const u8, size as usize), slice::from_raw_parts(data as *const u8, size as usize),
)) ))
}
} else { } else {
None None
} }

View file

@ -386,7 +386,11 @@ unsafe extern "C" fn write<T: RTPHeaderExtensionImpl>(
gst::BufferRef::from_ptr(input), gst::BufferRef::from_ptr(input),
from_glib(write_flags), from_glib(write_flags),
gst::BufferRef::from_mut_ptr(output), gst::BufferRef::from_mut_ptr(output),
std::slice::from_raw_parts_mut(output_data, output_data_len), if output_data_len == 0 {
&mut []
} else {
std::slice::from_raw_parts_mut(output_data, output_data_len)
},
) { ) {
Ok(len) => len as isize, Ok(len) => len as isize,
Err(err) => { Err(err) => {
@ -412,7 +416,11 @@ unsafe extern "C" fn read<T: RTPHeaderExtensionImpl>(
match imp.read( match imp.read(
wrap.unsafe_cast_ref(), wrap.unsafe_cast_ref(),
from_glib(read_flags), from_glib(read_flags),
std::slice::from_raw_parts(input_data, input_data_len), if input_data_len == 0 {
&[]
} else {
std::slice::from_raw_parts(input_data, input_data_len)
},
gst::BufferRef::from_mut_ptr(output), gst::BufferRef::from_mut_ptr(output),
) { ) {
Ok(_) => true, Ok(_) => true,

View file

@ -164,6 +164,10 @@ impl<T> VideoFrame<T> {
// components in the plane is the same, which is probably safe // components in the plane is the same, which is probably safe
let h = format_info.scale_height(plane as u8, self.height()); let h = format_info.scale_height(plane as u8, self.height());
if w == 0 || h == 0 {
return Ok(&[]);
}
unsafe { unsafe {
Ok(slice::from_raw_parts( Ok(slice::from_raw_parts(
self.frame.data[plane as usize] as *const u8, self.frame.data[plane as usize] as *const u8,
@ -378,6 +382,10 @@ impl VideoFrame<Writable> {
// components in the plane is the same, which is probably safe // components in the plane is the same, which is probably safe
let h = format_info.scale_height(plane as u8, self.height()); let h = format_info.scale_height(plane as u8, self.height());
if w == 0 || h == 0 {
return Ok(&mut []);
}
unsafe { unsafe {
Ok(slice::from_raw_parts_mut( Ok(slice::from_raw_parts_mut(
self.frame.data[plane as usize] as *mut u8, self.frame.data[plane as usize] as *mut u8,
@ -536,6 +544,10 @@ impl<T> VideoFrameRef<T> {
// components in the plane is the same, which is probably safe // components in the plane is the same, which is probably safe
let h = format_info.scale_height(plane as u8, self.height()); let h = format_info.scale_height(plane as u8, self.height());
if w == 0 || h == 0 {
return Ok(&[]);
}
unsafe { unsafe {
Ok(slice::from_raw_parts( Ok(slice::from_raw_parts(
self.frame.data[plane as usize] as *const u8, self.frame.data[plane as usize] as *const u8,
@ -770,6 +782,10 @@ impl<'a> VideoFrameRef<&'a mut gst::BufferRef> {
// components in the plane is the same, which is probably safe // components in the plane is the same, which is probably safe
let h = format_info.scale_height(plane as u8, self.height()); let h = format_info.scale_height(plane as u8, self.height());
if w == 0 || h == 0 {
return Ok(&mut []);
}
unsafe { unsafe {
Ok(slice::from_raw_parts_mut( Ok(slice::from_raw_parts_mut(
self.frame.data[plane as usize] as *mut u8, self.frame.data[plane as usize] as *mut u8,

View file

@ -625,6 +625,9 @@ impl VideoCaptionMeta {
#[doc(alias = "get_data")] #[doc(alias = "get_data")]
pub fn data(&self) -> &[u8] { pub fn data(&self) -> &[u8] {
if self.0.size == 0 {
return &[];
}
unsafe { unsafe {
use std::slice; use std::slice;

View file

@ -1055,12 +1055,18 @@ impl<'a, T> BufferMap<'a, T> {
} }
pub fn as_slice(&self) -> &[u8] { pub fn as_slice(&self) -> &[u8] {
if self.map_info.size == 0 {
return &[];
}
unsafe { slice::from_raw_parts(self.map_info.data as *const u8, self.map_info.size) } unsafe { slice::from_raw_parts(self.map_info.data as *const u8, self.map_info.size) }
} }
} }
impl<'a> BufferMap<'a, Writable> { impl<'a> BufferMap<'a, Writable> {
pub fn as_mut_slice(&mut self) -> &mut [u8] { pub fn as_mut_slice(&mut self) -> &mut [u8] {
if self.map_info.size == 0 {
return &mut [];
}
unsafe { slice::from_raw_parts_mut(self.map_info.data as *mut u8, self.map_info.size) } unsafe { slice::from_raw_parts_mut(self.map_info.data as *mut u8, self.map_info.size) }
} }
} }
@ -1118,6 +1124,9 @@ unsafe impl<'a, T> Sync for BufferMap<'a, T> {}
impl<T> MappedBuffer<T> { impl<T> MappedBuffer<T> {
pub fn as_slice(&self) -> &[u8] { pub fn as_slice(&self) -> &[u8] {
if self.map_info.size == 0 {
return &[];
}
unsafe { slice::from_raw_parts(self.map_info.data as *const u8, self.map_info.size) } unsafe { slice::from_raw_parts(self.map_info.data as *const u8, self.map_info.size) }
} }
@ -1143,6 +1152,9 @@ impl<T> MappedBuffer<T> {
impl MappedBuffer<Writable> { impl MappedBuffer<Writable> {
pub fn as_mut_slice(&mut self) -> &mut [u8] { pub fn as_mut_slice(&mut self) -> &mut [u8] {
if self.map_info.size == 0 {
return &mut [];
}
unsafe { slice::from_raw_parts_mut(self.map_info.data as *mut u8, self.map_info.size) } unsafe { slice::from_raw_parts_mut(self.map_info.data as *mut u8, self.map_info.size) }
} }
} }

View file

@ -331,12 +331,18 @@ impl<'a, T> MemoryMap<'a, T> {
} }
pub fn as_slice(&self) -> &[u8] { pub fn as_slice(&self) -> &[u8] {
if self.map_info.size == 0 {
return &[];
}
unsafe { slice::from_raw_parts(self.map_info.data as *const u8, self.map_info.size) } unsafe { slice::from_raw_parts(self.map_info.data as *const u8, self.map_info.size) }
} }
} }
impl<'a> MemoryMap<'a, Writable> { impl<'a> MemoryMap<'a, Writable> {
pub fn as_mut_slice(&mut self) -> &mut [u8] { pub fn as_mut_slice(&mut self) -> &mut [u8] {
if self.map_info.size == 0 {
return &mut [];
}
unsafe { slice::from_raw_parts_mut(self.map_info.data as *mut u8, self.map_info.size) } unsafe { slice::from_raw_parts_mut(self.map_info.data as *mut u8, self.map_info.size) }
} }
} }
@ -394,6 +400,9 @@ unsafe impl<'a, T> Sync for MemoryMap<'a, T> {}
impl<T> MappedMemory<T> { impl<T> MappedMemory<T> {
pub fn as_slice(&self) -> &[u8] { pub fn as_slice(&self) -> &[u8] {
if self.map_info.size == 0 {
return &[];
}
unsafe { slice::from_raw_parts(self.map_info.data as *const u8, self.map_info.size) } unsafe { slice::from_raw_parts(self.map_info.data as *const u8, self.map_info.size) }
} }
@ -419,6 +428,9 @@ impl<T> MappedMemory<T> {
impl MappedMemory<Writable> { impl MappedMemory<Writable> {
pub fn as_mut_slice(&mut self) -> &mut [u8] { pub fn as_mut_slice(&mut self) -> &mut [u8] {
if self.map_info.size == 0 {
return &mut [];
}
unsafe { slice::from_raw_parts_mut(self.map_info.data as *mut u8, self.map_info.size) } unsafe { slice::from_raw_parts_mut(self.map_info.data as *mut u8, self.map_info.size) }
} }
} }

View file

@ -63,6 +63,8 @@ impl TypeFind {
let data = ffi::gst_type_find_peek(&mut self.0, offset, size); let data = ffi::gst_type_find_peek(&mut self.0, offset, size);
if data.is_null() { if data.is_null() {
None None
} else if size == 0 {
Some(&[])
} else { } else {
Some(slice::from_raw_parts(data, size as usize)) Some(slice::from_raw_parts(data, size as usize))
} }

View file

@ -709,7 +709,7 @@ unsafe impl<'a> glib::value::FromValue<'a> for Array {
unsafe fn from_value(value: &'a glib::Value) -> Self { unsafe fn from_value(value: &'a glib::Value) -> Self {
skip_assert_initialized!(); skip_assert_initialized!();
let arr = (*value.to_glib_none().0).data[0].v_pointer as *const glib::ffi::GArray; let arr = (*value.to_glib_none().0).data[0].v_pointer as *const glib::ffi::GArray;
if arr.is_null() { if arr.is_null() || (*arr).len == 0 {
Self(Vec::new()) Self(Vec::new())
} else { } else {
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
@ -782,7 +782,7 @@ unsafe impl<'a> glib::value::FromValue<'a> for ArrayRef<'a> {
unsafe fn from_value(value: &'a glib::Value) -> Self { unsafe fn from_value(value: &'a glib::Value) -> Self {
skip_assert_initialized!(); skip_assert_initialized!();
let arr = (*value.to_glib_none().0).data[0].v_pointer as *const glib::ffi::GArray; let arr = (*value.to_glib_none().0).data[0].v_pointer as *const glib::ffi::GArray;
if arr.is_null() { if arr.is_null() || (*arr).len == 0 {
Self(&[]) Self(&[])
} else { } else {
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
@ -879,7 +879,7 @@ unsafe impl<'a> glib::value::FromValue<'a> for List {
unsafe fn from_value(value: &'a glib::Value) -> Self { unsafe fn from_value(value: &'a glib::Value) -> Self {
skip_assert_initialized!(); skip_assert_initialized!();
let arr = (*value.to_glib_none().0).data[0].v_pointer as *const glib::ffi::GArray; let arr = (*value.to_glib_none().0).data[0].v_pointer as *const glib::ffi::GArray;
if arr.is_null() { if arr.is_null() || (*arr).len == 0 {
Self(Vec::new()) Self(Vec::new())
} else { } else {
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
@ -952,7 +952,7 @@ unsafe impl<'a> glib::value::FromValue<'a> for ListRef<'a> {
unsafe fn from_value(value: &'a glib::Value) -> Self { unsafe fn from_value(value: &'a glib::Value) -> Self {
skip_assert_initialized!(); skip_assert_initialized!();
let arr = (*value.to_glib_none().0).data[0].v_pointer as *const glib::ffi::GArray; let arr = (*value.to_glib_none().0).data[0].v_pointer as *const glib::ffi::GArray;
if arr.is_null() { if arr.is_null() || (*arr).len == 0 {
Self(&[]) Self(&[])
} else { } else {
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]