@@ -29,7 +29,7 @@ impl StrLike for CStr {
2929 if self . to_str ( ) . is_ok ( ) {
3030 sys:: kCFStringEncodingUTF8
3131 } else {
32- sys:: kCFStringEncodingNonLossyASCII
32+ sys:: kCFStringEncodingASCII
3333 }
3434 }
3535
@@ -139,7 +139,7 @@ impl CFString {
139139 }
140140
141141 /// Get this value as a null-terminated C-string
142- pub fn get_cstring ( & self ) -> CString {
142+ pub fn get_cstring ( & self ) -> Option < CString > {
143143 let len = self . len ( ) * 4 + 1 ;
144144 let mut buf = vec ! [ 0 ; len] ;
145145 // SAFETY: Self is guaranteed valid. Buffer is definitely of sufficient length to hold the
@@ -154,24 +154,28 @@ impl CFString {
154154 } ;
155155 if res {
156156 let buf = buf. into_iter ( ) . take_while ( |& c| c != 0 ) . collect :: < Vec < _ > > ( ) ;
157- CString :: new ( buf) . unwrap ( )
157+ if buf. len ( ) != self . len ( ) {
158+ None
159+ } else {
160+ Some ( CString :: new ( buf) . unwrap ( ) )
161+ }
158162 } else {
159- panic ! ( "Invalid C String" )
163+ None
160164 }
161165 }
162166
163167 /// Attempt to get a reference to this value as a `CStr`, if the value is natively UTF-8,
164168 /// otherwise allocate a CString in that encoding.
165- pub fn as_cstr ( & self ) -> Cow < ' _ , CStr > {
169+ pub fn as_cstr ( & self ) -> Option < Cow < ' _ , CStr > > {
166170 // SAFETY: Self is guaranteed valid
167171 let cstr =
168172 unsafe { sys:: CFStringGetCStringPtr ( self . as_type_ref ( ) , sys:: kCFStringEncodingUTF8) } ;
169173 if cstr. is_null ( ) {
170- Cow :: Owned ( self . get_cstring ( ) )
174+ self . get_cstring ( ) . map ( Cow :: Owned )
171175 } else {
172176 // SAFETY: If non-null, the return value of CFStringGetCStringPtr is guaranteed to be a
173177 // valid C-string
174- Cow :: Borrowed ( unsafe { CStr :: from_ptr ( cstr) } )
178+ Some ( Cow :: Borrowed ( unsafe { CStr :: from_ptr ( cstr) } ) )
175179 }
176180 }
177181}
@@ -188,23 +192,23 @@ mod tests {
188192 let cstr = CFString :: new ( c"foo" ) ;
189193 assert_eq ! ( cstr. as_str( ) , Cow :: Borrowed ( "foo" ) ) ;
190194
195+ // Invalid UTF-8 CStrings are treated as extended-ASCII.
191196 let non_str = CFString :: new ( c"\xC3 \x28 bar" ) ;
192- assert_eq ! ( non_str. as_str( ) , Cow :: <str >:: Owned ( "\0 \0 bar " . to_string( ) ) ) ;
197+ assert_eq ! ( non_str. as_str( ) , Cow :: <str >:: Owned ( "Ã(bar " . to_string( ) ) ) ;
193198 }
194199
195200 #[ test]
196201 fn test_as_cstr ( ) {
197202 let str = CFString :: new ( "foo" ) ;
198- assert_eq ! ( str . as_cstr( ) , Cow :: <CStr >:: Owned ( c"foo" . to_owned( ) ) ) ;
203+ assert_eq ! ( str . as_cstr( ) , Some ( Cow :: <CStr >:: Owned ( c"foo" . to_owned( ) ) ) ) ;
199204
200205 let cstr = CFString :: new ( c"foo" ) ;
201- assert_eq ! ( cstr. as_cstr( ) , Cow :: Borrowed ( c"foo" ) ) ;
206+ assert_eq ! ( cstr. as_cstr( ) , Some ( Cow :: Borrowed ( c"foo" ) ) ) ;
202207 }
203208
204209 #[ test]
205- #[ should_panic]
206210 fn test_as_non_cstr ( ) {
207211 let non_cstr = CFString :: new ( "fo\0 o" ) ;
208- non_cstr. as_cstr ( ) ;
212+ assert ! ( non_cstr. as_cstr( ) . is_none ( ) ) ;
209213 }
210214}
0 commit comments