Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add in missing nullptr check when calling std::slice::from_raw_parts #416

Merged
merged 2 commits into from
Sep 29, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions rosidl_runtime_rs/src/sequence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,18 +261,26 @@ where
///
/// Equivalent to `&seq[..]`.
pub fn as_slice(&self) -> &[T] {
// SAFETY: self.data points to self.size consecutive, initialized elements and
// isn't modified externally.
unsafe { std::slice::from_raw_parts(self.data, self.size) }
if self.data.is_null() {
&[]
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

} else {
// SAFETY: self.data is not null and points to self.size consecutive,
// initialized elements and isn't modified externally.
unsafe { std::slice::from_raw_parts(self.data, self.size) }
}
}

/// Extracts a mutable slice containing the entire sequence.
///
/// Equivalent to `&mut seq[..]`.
pub fn as_mut_slice(&mut self) -> &mut [T] {
// SAFETY: self.data points to self.size consecutive, initialized elements and
// isn't modified externally.
unsafe { std::slice::from_raw_parts_mut(self.data, self.size) }
if self.data.is_null() {
&mut []
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, now that I'm looking at this, I'm not sure this would work. If someone started pushing to this mutable slice self.data would never get updated, so this likely would compile but exhibit incorrect runtime behavior.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to write a unit test for this scenario? Just to make sure that it's working, and also as a warning sign in case future changes cause it to break?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to write a unit test for this scenario?

Good point, added a unit test for the base cases. But also, just digging around the slice API, doesn't seem like this is really a concern to mutate the slice as its empty, and the only mutation that can be done will be with the fixed size.

i.e.

let mut slice = Sequence::<i32>::default().as_mut_slice();

// I can't do anything useful with slice now
// slice[0] = 42 will segfault because the len of the slice is zero.
// I actually don't think it matters, its just not really idiomatic rust

} else {
// SAFETY: self.data is not null and points to self.size consecutive,
// initialized elements and isn't modified externally.
unsafe { std::slice::from_raw_parts_mut(self.data, self.size) }
}
}
}

Expand Down Expand Up @@ -666,6 +674,12 @@ mod tests {
}
}

#[test]
fn test_empty_sequence() {
assert!(Sequence::<i32>::default().is_empty());
assert!(BoundedSequence::<i32, 5>::default().is_empty());
}

quickcheck! {
fn test_extend(xs: Vec<i32>, ys: Vec<i32>) -> bool {
let mut xs_seq = Sequence::new(xs.len());
Expand Down
Loading