@@ -91,20 +91,36 @@ impl CStr {
91
91
///
92
92
/// The provided slice must be `NUL`-terminated, does not contain any
93
93
/// interior `NUL` bytes.
94
- pub fn from_bytes_with_nul ( bytes : & [ u8 ] ) -> Result < & Self , CStrConvertError > {
94
+ pub const fn from_bytes_with_nul ( bytes : & [ u8 ] ) -> Result < & Self , CStrConvertError > {
95
95
if bytes. is_empty ( ) {
96
96
return Err ( CStrConvertError :: NotNulTerminated ) ;
97
97
}
98
98
if bytes[ bytes. len ( ) - 1 ] != 0 {
99
99
return Err ( CStrConvertError :: NotNulTerminated ) ;
100
100
}
101
- if bytes[ ..bytes. len ( ) ] . contains ( & 0 ) {
102
- return Err ( CStrConvertError :: InteriorNul ) ;
101
+ let mut i = 0 ;
102
+ while i < bytes. len ( ) - 1 {
103
+ if bytes[ i] == 0 {
104
+ return Err ( CStrConvertError :: InteriorNul ) ;
105
+ }
106
+ i += 1 ;
103
107
}
104
108
// SAFETY: We just checked that all properties hold.
105
109
Ok ( unsafe { Self :: from_bytes_with_nul_unchecked ( bytes) } )
106
110
}
107
111
112
+ /// Creates a [`CStr`] from a `[u8]`, panic if input is not valid.
113
+ ///
114
+ /// This function is only meant to be used by `c_str!` macro, so
115
+ /// crates using `c_str!` macro don't have to enable `const_panic` feature.
116
+ #[ doc( hidden) ]
117
+ pub const fn from_bytes_with_nul_unwrap ( bytes : & [ u8 ] ) -> & Self {
118
+ match Self :: from_bytes_with_nul ( bytes) {
119
+ Ok ( v) => v,
120
+ Err ( _) => panic ! ( "string contains interior NUL" ) ,
121
+ }
122
+ }
123
+
108
124
/// Creates a [`CStr`] from a `[u8]` without performing any additional
109
125
/// checks.
110
126
///
@@ -220,10 +236,8 @@ where
220
236
#[ macro_export]
221
237
macro_rules! c_str {
222
238
( $str: literal) => { {
223
- // FIXME: Check that `$str` does not contain interior `NUL`.
224
239
const S : & str = concat!( $str, "\0 " ) ;
225
- const C : & $crate:: str :: CStr =
226
- { unsafe { $crate:: str :: CStr :: from_bytes_with_nul_unchecked( S . as_bytes( ) ) } } ;
240
+ const C : & $crate:: str :: CStr = $crate:: str :: CStr :: from_bytes_with_nul_unwrap( S . as_bytes( ) ) ;
227
241
C
228
242
} } ;
229
243
}
0 commit comments