@@ -5,7 +5,7 @@ use std::{ffi, fmt, ptr};
55
66use crate :: client:: common:: CREATE_OR_DESTROY_CLIENT_MUTEX ;
77use crate :: jack_enums:: CodeOrMessage ;
8- use crate :: jack_utils:: collect_strs;
8+ use crate :: jack_utils:: { collect_strs, to_cstring } ;
99use crate :: properties:: PropertyChangeHandler ;
1010use crate :: transport:: Transport ;
1111use crate :: {
@@ -120,24 +120,23 @@ impl Client {
120120 return Err ( Error :: LibraryError ( err. to_string ( ) ) ) ;
121121 }
122122
123+ let client_name = to_cstring ( client_name) ?;
124+ let server_name = server_name. map ( to_cstring) . transpose ( ) ?;
125+
123126 crate :: logging:: maybe_init_logging ( ) ;
124127 let mut status_bits = 0 ;
125- let client_name = ffi:: CString :: new ( client_name) . unwrap ( ) ;
126128 let client = match server_name {
127129 None => unsafe {
128130 j:: jack_client_open ( client_name. as_ptr ( ) , options. bits ( ) , & mut status_bits)
129131 } ,
130- Some ( server_name) => {
131- let server_name = ffi:: CString :: new ( server_name) . unwrap ( ) ;
132- unsafe {
133- j:: jack_client_open_with_server_name (
134- client_name. as_ptr ( ) ,
135- options. bits ( ) ,
136- & mut status_bits,
137- server_name. as_ptr ( ) ,
138- )
139- }
140- }
132+ Some ( server_name) => unsafe {
133+ j:: jack_client_open_with_server_name (
134+ client_name. as_ptr ( ) ,
135+ options. bits ( ) ,
136+ & mut status_bits,
137+ server_name. as_ptr ( ) ,
138+ )
139+ } ,
141140 } ;
142141 let status = ClientStatus :: from_bits ( status_bits) . unwrap_or_else ( ClientStatus :: empty) ;
143142 if client. is_null ( ) {
@@ -244,7 +243,7 @@ impl Client {
244243 raw : * mut jack_sys:: jack_client_t ,
245244 name : & str ,
246245 ) -> Option < jack_sys:: jack_uuid_t > {
247- let name = ffi:: CString :: new ( name) . unwrap ( ) ;
246+ let name = ffi:: CString :: new ( name) . ok ( ) ? ;
248247 let mut uuid: jack_sys:: jack_uuid_t = Default :: default ( ) ;
249248 unsafe {
250249 let uuid_s = jack_sys:: jack_get_uuid_for_client_name ( raw, name. as_ptr ( ) ) ;
@@ -294,7 +293,7 @@ impl Client {
294293
295294 /// Get the name of a client by its `&str` uuid.
296295 pub fn name_by_uuid_str ( & self , uuid : & str ) -> Option < String > {
297- let uuid = ffi:: CString :: new ( uuid) . unwrap ( ) ;
296+ let uuid = ffi:: CString :: new ( uuid) . ok ( ) ? ;
298297 unsafe { self . name_by_uuid_raw ( uuid. as_ptr ( ) ) }
299298 }
300299
@@ -316,8 +315,14 @@ impl Client {
316315 type_name_pattern : Option < & str > ,
317316 flags : PortFlags ,
318317 ) -> Vec < String > {
319- let port_name_pattern_cstr = ffi:: CString :: new ( port_name_pattern. unwrap_or ( "" ) ) . unwrap ( ) ;
320- let type_name_pattern_cstr = ffi:: CString :: new ( type_name_pattern. unwrap_or ( "" ) ) . unwrap ( ) ;
318+ // A pattern containing a NUL byte can't be passed to JACK, and no port name or type
319+ // contains one, so nothing matches.
320+ let ( Ok ( port_name_pattern_cstr) , Ok ( type_name_pattern_cstr) ) = (
321+ ffi:: CString :: new ( port_name_pattern. unwrap_or ( "" ) ) ,
322+ ffi:: CString :: new ( type_name_pattern. unwrap_or ( "" ) ) ,
323+ ) else {
324+ return Vec :: new ( ) ;
325+ } ;
321326 let flags = libc:: c_ulong:: from ( flags. bits ( ) ) ;
322327 unsafe {
323328 let ports = j:: jack_get_ports (
@@ -352,8 +357,8 @@ impl Client {
352357 if port_spec. jack_port_type ( ) . is_empty ( ) {
353358 return Err ( Error :: PortRegistrationError ( port_name. to_string ( ) ) ) ;
354359 }
355- let port_name_c = ffi :: CString :: new ( port_name) . unwrap ( ) ;
356- let port_type_c = ffi :: CString :: new ( port_spec. jack_port_type ( ) ) . unwrap ( ) ;
360+ let port_name_c = to_cstring ( port_name) ? ;
361+ let port_type_c = to_cstring ( port_spec. jack_port_type ( ) ) ? ;
357362 let port_flags = port_spec. jack_flags ( ) . bits ( ) ;
358363 let buffer_size = port_spec. jack_buffer_size ( ) ;
359364 let pp = unsafe {
@@ -384,7 +389,8 @@ impl Client {
384389
385390 /// Get a `Port` by its port name.
386391 pub fn port_by_name ( & self , port_name : & str ) -> Option < Port < Unowned > > {
387- let port_name = ffi:: CString :: new ( port_name) . unwrap ( ) ;
392+ // No port name contains a NUL byte.
393+ let port_name = ffi:: CString :: new ( port_name) . ok ( ) ?;
388394 let pp = unsafe { j:: jack_port_by_name ( self . raw ( ) , port_name. as_ptr ( ) ) } ;
389395 if pp. is_null ( ) {
390396 None
@@ -412,9 +418,9 @@ impl Client {
412418 client_bin_name : & str ,
413419 client_args : & str ,
414420 ) -> Result < InternalClientID , Error > {
415- let ffi_client_name = ffi :: CString :: new ( client_name) . unwrap ( ) ;
416- let ffi_client_bin = ffi :: CString :: new ( client_bin_name) . unwrap ( ) ;
417- let ffi_client_args = ffi :: CString :: new ( client_args) . unwrap ( ) ;
421+ let ffi_client_name = to_cstring ( client_name) ? ;
422+ let ffi_client_bin = to_cstring ( client_bin_name) ? ;
423+ let ffi_client_args = to_cstring ( client_args) ? ;
418424
419425 let mut status_bits = 0 ;
420426 let options: j:: Enum_JackOptions = j:: JackLoadName | j:: JackLoadInit ;
@@ -506,7 +512,7 @@ impl Client {
506512 port_name : & str ,
507513 enable_monitor : bool ,
508514 ) -> Result < ( ) , Error > {
509- let port_name_cstr = ffi :: CString :: new ( port_name) . unwrap ( ) ;
515+ let port_name_cstr = to_cstring ( port_name) ? ;
510516 let res = unsafe {
511517 j:: jack_port_request_monitor_by_name (
512518 self . raw ( ) ,
@@ -558,15 +564,15 @@ impl Client {
558564 /// 3. The port flags of the `destination_port` must include `IS_INPUT`.
559565 /// 4. Both ports must be owned by active clients.
560566 ///
561- /// # Panics
562- /// Panics if it is not possible to convert `source_port` or `destination_port` to a `CString` .
567+ /// Returns `Err(Error::InteriorNul)` if `source_port` or `destination_port` contains a NUL
568+ /// byte .
563569 pub fn connect_ports_by_name (
564570 & self ,
565571 source_port : & str ,
566572 destination_port : & str ,
567573 ) -> Result < ( ) , Error > {
568- let source_cstr = ffi :: CString :: new ( source_port) . unwrap ( ) ;
569- let destination_cstr = ffi :: CString :: new ( destination_port) . unwrap ( ) ;
574+ let source_cstr = to_cstring ( source_port) ? ;
575+ let destination_cstr = to_cstring ( destination_port) ? ;
570576 let res =
571577 unsafe { j:: jack_connect ( self . raw ( ) , source_cstr. as_ptr ( ) , destination_cstr. as_ptr ( ) ) } ;
572578 match res {
@@ -661,8 +667,8 @@ impl Client {
661667 source_port : & str ,
662668 destination_port : & str ,
663669 ) -> Result < ( ) , Error > {
664- let source_port = ffi :: CString :: new ( source_port) . unwrap ( ) ;
665- let destination_port = ffi :: CString :: new ( destination_port) . unwrap ( ) ;
670+ let source_port = to_cstring ( source_port) ? ;
671+ let destination_port = to_cstring ( destination_port) ? ;
666672 let res = unsafe {
667673 j:: jack_disconnect ( self . raw ( ) , source_port. as_ptr ( ) , destination_port. as_ptr ( ) )
668674 } ;
@@ -674,12 +680,16 @@ impl Client {
674680
675681 /// The buffer size of a port type
676682 ///
683+ /// Returns 0 if `port_type` contains a NUL byte, since no port type does.
684+ ///
677685 /// # Safety
678686 ///
679687 /// * This function may only be called in a buffer size callback.
680688 pub unsafe fn type_buffer_size ( & self , port_type : & str ) -> usize {
681689 unsafe {
682- let port_type = ffi:: CString :: new ( port_type) . unwrap ( ) ;
690+ let Ok ( port_type) = ffi:: CString :: new ( port_type) else {
691+ return 0 ;
692+ } ;
683693 j:: jack_port_type_get_buffer_size ( self . raw ( ) , port_type. as_ptr ( ) )
684694 }
685695 }
0 commit comments