Skip to content

Commit 2720033

Browse files
committed
Do not include NUL-terminator in computed length
1 parent 4fae2c6 commit 2720033

File tree

1 file changed

+22
-13
lines changed

1 file changed

+22
-13
lines changed

core/src/panic/location.rs

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::ffi::CStr;
22
use crate::fmt;
3+
use crate::marker::PhantomData;
34

45
/// A struct containing information about the location of a panic.
56
///
@@ -33,14 +34,13 @@ use crate::fmt;
3334
#[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
3435
#[stable(feature = "panic_hooks", since = "1.10.0")]
3536
pub struct Location<'a> {
36-
// Note: this filename will have exactly one nul byte at its end, but otherwise
37-
// it must never contain interior nul bytes. This is relied on for the conversion
38-
// to `CStr` below.
39-
//
40-
// The prefix of the string without the trailing nul byte will be a regular UTF8 `str`.
41-
file_bytes_with_nul: &'a [u8],
37+
// A raw pointer is used rather than a reference because the pointer is valid for one more byte
38+
// than the length stored in this pointer; the additional byte is the NUL-terminator used by
39+
// `Location::file_with_nul`.
40+
filename: *const str,
4241
line: u32,
4342
col: u32,
43+
_filename: PhantomData<&'a str>,
4444
}
4545

4646
#[stable(feature = "panic_hooks", since = "1.10.0")]
@@ -143,10 +143,8 @@ impl<'a> Location<'a> {
143143
#[stable(feature = "panic_hooks", since = "1.10.0")]
144144
#[rustc_const_stable(feature = "const_location_fields", since = "1.79.0")]
145145
pub const fn file(&self) -> &str {
146-
let str_len = self.file_bytes_with_nul.len() - 1;
147-
// SAFETY: `file_bytes_with_nul` without the trailing nul byte is guaranteed to be
148-
// valid UTF8.
149-
unsafe { crate::str::from_raw_parts(self.file_bytes_with_nul.as_ptr(), str_len) }
146+
// SAFETY: The filename is valid.
147+
unsafe { &*self.filename }
150148
}
151149

152150
/// Returns the name of the source file as a nul-terminated `CStr`.
@@ -157,9 +155,15 @@ impl<'a> Location<'a> {
157155
#[unstable(feature = "file_with_nul", issue = "141727")]
158156
#[inline]
159157
pub const fn file_with_nul(&self) -> &CStr {
160-
// SAFETY: `file_bytes_with_nul` is guaranteed to have a trailing nul byte and no
161-
// interior nul bytes.
162-
unsafe { CStr::from_bytes_with_nul_unchecked(self.file_bytes_with_nul) }
158+
// SAFETY: The filename is valid for `filename_len+1` bytes, so this addition can't
159+
// overflow.
160+
let cstr_len = unsafe { crate::mem::size_of_val_raw(self.filename).unchecked_add(1) };
161+
162+
// SAFETY: The filename is valid for `filename_len+1` bytes.
163+
let slice = unsafe { crate::slice::from_raw_parts(self.filename as *const _, cstr_len) };
164+
165+
// SAFETY: The filename is guaranteed to have a trailing nul byte and no interior nul bytes.
166+
unsafe { CStr::from_bytes_with_nul_unchecked(slice) }
163167
}
164168

165169
/// Returns the line number from which the panic originated.
@@ -220,3 +224,8 @@ impl fmt::Display for Location<'_> {
220224
write!(formatter, "{}:{}:{}", self.file(), self.line, self.col)
221225
}
222226
}
227+
228+
#[stable(feature = "panic_hooks", since = "1.10.0")]
229+
unsafe impl Send for Location<'_> {}
230+
#[stable(feature = "panic_hooks", since = "1.10.0")]
231+
unsafe impl Sync for Location<'_> {}

0 commit comments

Comments
 (0)