Skip to content

Commit c10a929

Browse files
committed
Safely enforce thread name requirements
1 parent cc4ed95 commit c10a929

File tree

1 file changed

+28
-11
lines changed

1 file changed

+28
-11
lines changed

std/src/thread/mod.rs

+28-11
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ mod tests;
161161
use crate::any::Any;
162162
use crate::cell::{OnceCell, UnsafeCell};
163163
use crate::env;
164-
use crate::ffi::{CStr, CString};
164+
use crate::ffi::CStr;
165165
use crate::fmt;
166166
use crate::io;
167167
use crate::marker::PhantomData;
@@ -487,11 +487,7 @@ impl Builder {
487487
amt
488488
});
489489

490-
let my_thread = name.map_or_else(Thread::new_unnamed, |name| unsafe {
491-
Thread::new(
492-
CString::new(name).expect("thread name may not contain interior null bytes"),
493-
)
494-
});
490+
let my_thread = name.map_or_else(Thread::new_unnamed, |name| Thread::new(name.into()));
495491
let their_thread = my_thread.clone();
496492

497493
let my_packet: Arc<Packet<'scope, T>> = Arc::new(Packet {
@@ -1273,10 +1269,34 @@ impl ThreadId {
12731269
/// The internal representation of a `Thread`'s name.
12741270
enum ThreadName {
12751271
Main,
1276-
Other(CString),
1272+
Other(ThreadNameString),
12771273
Unnamed,
12781274
}
12791275

1276+
// This module ensures private fields are kept private, which is necessary to enforce the safety requirements.
1277+
mod thread_name_string {
1278+
use crate::ffi::{CStr, CString};
1279+
1280+
/// Like a `String` it's guaranteed UTF-8 and like a `CString` it's null terminated.
1281+
pub(crate) struct ThreadNameString {
1282+
inner: CString,
1283+
}
1284+
impl core::ops::Deref for ThreadNameString {
1285+
type Target = CStr;
1286+
fn deref(&self) -> &CStr {
1287+
&self.inner
1288+
}
1289+
}
1290+
impl From<String> for ThreadNameString {
1291+
fn from(s: String) -> Self {
1292+
Self {
1293+
inner: CString::new(s).expect("thread name may not contain interior null bytes"),
1294+
}
1295+
}
1296+
}
1297+
}
1298+
pub(crate) use thread_name_string::ThreadNameString;
1299+
12801300
/// The internal representation of a `Thread` handle
12811301
struct Inner {
12821302
name: ThreadName, // Guaranteed to be UTF-8
@@ -1316,10 +1336,7 @@ pub struct Thread {
13161336

13171337
impl Thread {
13181338
/// Used only internally to construct a thread object without spawning.
1319-
///
1320-
/// # Safety
1321-
/// `name` must be valid UTF-8.
1322-
pub(crate) unsafe fn new(name: CString) -> Thread {
1339+
pub(crate) fn new(name: ThreadNameString) -> Thread {
13231340
unsafe { Self::new_inner(ThreadName::Other(name)) }
13241341
}
13251342

0 commit comments

Comments
 (0)