Skip to content

Commit

Permalink
Change every function pointer type to an Option
Browse files Browse the repository at this point in the history
Rust's function pointer types do not permit null values, so constructing
one from null (with transmute, or by being passed a null pointer over
FFI) results in undefined behavior. Nullable function pointer types
should be represented as an `Option<fn(...) -> ...>`, which has the same
ABI as `fn(...) -> ...` but allows null values.

For well-behaved CLAP hosts and plugins, this should not be an issue,
since none of the function pointers found in the API are ever permitted
to be null. However, hosts and plugins are not always well behaved, and
it's desirable to be able to explicitly handle null function pointers
without invoking UB, at least in the setting of a plugin validator or
similar. So, this change wraps every function pointer type in an
`Option`.
  • Loading branch information
glowcoil committed Jul 3, 2022
1 parent 7db714c commit efc0940
Show file tree
Hide file tree
Showing 35 changed files with 403 additions and 297 deletions.
6 changes: 3 additions & 3 deletions src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::os::raw::c_char;
#[derive(Debug, Copy, Clone)]
pub struct clap_plugin_entry {
pub clap_version: clap_version,
pub init: unsafe extern "C" fn(plugin_path: *const c_char) -> bool,
pub deinit: unsafe extern "C" fn(),
pub get_factory: unsafe extern "C" fn(factory_id: *const c_char) -> *const c_void,
pub init: Option<unsafe extern "C" fn(plugin_path: *const c_char) -> bool>,
pub deinit: Option<unsafe extern "C" fn()>,
pub get_factory: Option<unsafe extern "C" fn(factory_id: *const c_char) -> *const c_void>,
}
22 changes: 13 additions & 9 deletions src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,13 @@ pub struct clap_event_midi2 {
#[derive(Debug, Copy, Clone)]
pub struct clap_input_events {
pub ctx: *mut c_void,
pub size: unsafe extern "C" fn(list: *const clap_input_events) -> u32,
pub get: unsafe extern "C" fn(
list: *const clap_input_events,
index: u32,
) -> *const clap_event_header,
pub size: Option<unsafe extern "C" fn(list: *const clap_input_events) -> u32>,
pub get: Option<
unsafe extern "C" fn(
list: *const clap_input_events,
index: u32,
) -> *const clap_event_header,
>,
}

unsafe impl Send for clap_input_events {}
Expand All @@ -183,10 +185,12 @@ unsafe impl Sync for clap_input_events {}
#[derive(Debug, Copy, Clone)]
pub struct clap_output_events {
pub ctx: *mut c_void,
pub try_push: unsafe extern "C" fn(
list: *const clap_output_events,
event: *const clap_event_header,
) -> bool,
pub try_push: Option<
unsafe extern "C" fn(
list: *const clap_output_events,
event: *const clap_event_header,
) -> bool,
>,
}

unsafe impl Send for clap_output_events {}
Expand Down
21 changes: 12 additions & 9 deletions src/ext/audio_ports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@ unsafe impl Sync for clap_audio_port_info {}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct clap_plugin_audio_ports {
pub count: unsafe extern "C" fn(plugin: *const clap_plugin, is_input: bool) -> u32,
pub get: unsafe extern "C" fn(
plugin: *const clap_plugin,
index: u32,
is_input: bool,
info: *mut clap_audio_port_info,
) -> bool,
pub count: Option<unsafe extern "C" fn(plugin: *const clap_plugin, is_input: bool) -> u32>,
pub get: Option<
unsafe extern "C" fn(
plugin: *const clap_plugin,
index: u32,
is_input: bool,
info: *mut clap_audio_port_info,
) -> bool,
>,
}

pub const CLAP_AUDIO_PORTS_RESCAN_NAMES: u32 = 1 << 0;
Expand All @@ -50,6 +52,7 @@ pub const CLAP_AUDIO_PORTS_RESCAN_LIST: u32 = 1 << 5;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct clap_host_audio_ports {
pub is_rescan_flag_supported: unsafe extern "C" fn(host: *const clap_host, flag: u32) -> bool,
pub rescan: unsafe extern "C" fn(host: *const clap_host, flags: u32),
pub is_rescan_flag_supported:
Option<unsafe extern "C" fn(host: *const clap_host, flag: u32) -> bool>,
pub rescan: Option<unsafe extern "C" fn(host: *const clap_host, flags: u32)>,
}
19 changes: 11 additions & 8 deletions src/ext/audio_ports_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,20 @@ unsafe impl Sync for clap_audio_ports_config {}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct clap_plugin_audio_ports_config {
pub count: unsafe extern "C" fn(plugin: *const clap_plugin) -> u32,
pub get: unsafe extern "C" fn(
plugin: *const clap_plugin,
index: u32,
config: *mut clap_audio_ports_config,
) -> bool,
pub select: unsafe extern "C" fn(plugin: *const clap_plugin, config_id: clap_id) -> bool,
pub count: Option<unsafe extern "C" fn(plugin: *const clap_plugin) -> u32>,
pub get: Option<
unsafe extern "C" fn(
plugin: *const clap_plugin,
index: u32,
config: *mut clap_audio_ports_config,
) -> bool,
>,
pub select:
Option<unsafe extern "C" fn(plugin: *const clap_plugin, config_id: clap_id) -> bool>,
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct clap_host_audio_ports_config {
pub rescan: unsafe extern "C" fn(host: *const clap_host),
pub rescan: Option<unsafe extern "C" fn(host: *const clap_host)>,
}
16 changes: 9 additions & 7 deletions src/ext/draft/ambisonic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,18 @@ pub struct clap_ambisonic_info {
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct clap_plugin_ambisonic {
pub get_info: unsafe extern "C" fn(
plugin: *const clap_plugin,
is_input: bool,
port_index: u32,
info: *mut clap_ambisonic_info,
) -> bool,
pub get_info: Option<
unsafe extern "C" fn(
plugin: *const clap_plugin,
is_input: bool,
port_index: u32,
info: *mut clap_ambisonic_info,
) -> bool,
>,
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct clap_host_ambisonic {
pub changed: unsafe extern "C" fn(host: *const clap_host),
pub changed: Option<unsafe extern "C" fn(host: *const clap_host)>,
}
12 changes: 7 additions & 5 deletions src/ext/draft/check_for_update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,16 @@ unsafe impl Sync for clap_check_for_update_info {}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct clap_plugin_check_for_update {
pub check: unsafe extern "C" fn(plugin: *const clap_plugin, include_preview: bool),
pub check: Option<unsafe extern "C" fn(plugin: *const clap_plugin, include_preview: bool)>,
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct clap_host_check_for_update {
pub on_new_version: unsafe extern "C" fn(
host: *const clap_host,
update_info: *const clap_check_for_update_info,
),
pub on_new_version: Option<
unsafe extern "C" fn(
host: *const clap_host,
update_info: *const clap_check_for_update_info,
),
>,
}
18 changes: 10 additions & 8 deletions src/ext/draft/cv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,19 @@ pub const CLAP_CV_PITCH: u32 = 2;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct clap_plugin_cv {
pub get_channel_type: unsafe extern "C" fn(
plugin: *const clap_plugin,
is_input: bool,
port_index: u32,
channel_index: u32,
channel_type: *mut u32,
) -> bool,
pub get_channel_type: Option<
unsafe extern "C" fn(
plugin: *const clap_plugin,
is_input: bool,
port_index: u32,
channel_index: u32,
channel_type: *mut u32,
) -> bool,
>,
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct clap_host_cv {
pub changed: unsafe extern "C" fn(host: *const clap_host),
pub changed: Option<unsafe extern "C" fn(host: *const clap_host)>,
}
56 changes: 32 additions & 24 deletions src/ext/draft/file_reference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,33 +22,41 @@ unsafe impl Sync for clap_file_reference {}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct clap_plugin_file_reference {
pub count: unsafe extern "C" fn(plugin: *const clap_plugin) -> u32,
pub get: unsafe extern "C" fn(
plugin: *const clap_plugin,
index: u32,
file_reference: *mut clap_file_reference,
) -> bool,
pub get_blake3_digest: unsafe extern "C" fn(
plugin: *const clap_plugin,
resource_id: clap_id,
digest: *mut u8,
) -> bool,
pub get_file_size: unsafe extern "C" fn(
plugin: *const clap_plugin,
resource_id: clap_id,
size: *mut u64,
) -> bool,
pub update_path: unsafe extern "C" fn(
plugin: *const clap_plugin,
resource_id: clap_id,
path: *const c_char,
) -> bool,
pub save_resources: unsafe extern "C" fn(plugin: *const clap_plugin) -> bool,
pub count: Option<unsafe extern "C" fn(plugin: *const clap_plugin) -> u32>,
pub get: Option<
unsafe extern "C" fn(
plugin: *const clap_plugin,
index: u32,
file_reference: *mut clap_file_reference,
) -> bool,
>,
pub get_blake3_digest: Option<
unsafe extern "C" fn(
plugin: *const clap_plugin,
resource_id: clap_id,
digest: *mut u8,
) -> bool,
>,
pub get_file_size: Option<
unsafe extern "C" fn(
plugin: *const clap_plugin,
resource_id: clap_id,
size: *mut u64,
) -> bool,
>,
pub update_path: Option<
unsafe extern "C" fn(
plugin: *const clap_plugin,
resource_id: clap_id,
path: *const c_char,
) -> bool,
>,
pub save_resources: Option<unsafe extern "C" fn(plugin: *const clap_plugin) -> bool>,
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct clap_host_file_reference {
pub changed: unsafe extern "C" fn(host: *const clap_host),
pub set_dirty: unsafe extern "C" fn(host: *const clap_host, resource_id: clap_id),
pub changed: Option<unsafe extern "C" fn(host: *const clap_host)>,
pub set_dirty: Option<unsafe extern "C" fn(host: *const clap_host, resource_id: clap_id)>,
}
16 changes: 9 additions & 7 deletions src/ext/draft/midi_mappings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,18 @@ pub struct clap_midi_mapping {
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct clap_plugin_midi_mappings {
pub count: unsafe extern "C" fn(plugin: *const clap_plugin) -> u32,
pub get: unsafe extern "C" fn(
plugin: *const clap_plugin,
index: u32,
mapping: *mut clap_midi_mapping,
) -> bool,
pub count: Option<unsafe extern "C" fn(plugin: *const clap_plugin) -> u32>,
pub get: Option<
unsafe extern "C" fn(
plugin: *const clap_plugin,
index: u32,
mapping: *mut clap_midi_mapping,
) -> bool,
>,
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct clap_host_midi_mappings {
pub changed: unsafe extern "C" fn(host: *const clap_host),
pub changed: Option<unsafe extern "C" fn(host: *const clap_host)>,
}
3 changes: 2 additions & 1 deletion src/ext/draft/preset_load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ pub const CLAP_EXT_PRESET_LOAD: &CStr =
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct clap_plugin_preset_load {
pub from_file: unsafe extern "C" fn(plugin: *const clap_plugin, path: *const c_char) -> bool,
pub from_file:
Option<unsafe extern "C" fn(plugin: *const clap_plugin, path: *const c_char) -> bool>,
}
18 changes: 10 additions & 8 deletions src/ext/draft/quick_controls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,19 @@ unsafe impl Sync for clap_quick_controls_page {}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct clap_plugin_quick_controls {
pub count: unsafe extern "C" fn(plugin: *const clap_plugin) -> u32,
pub get: unsafe extern "C" fn(
plugin: *const clap_plugin,
page_index: u32,
page: *mut clap_quick_controls_page,
) -> bool,
pub count: Option<unsafe extern "C" fn(plugin: *const clap_plugin) -> u32>,
pub get: Option<
unsafe extern "C" fn(
plugin: *const clap_plugin,
page_index: u32,
page: *mut clap_quick_controls_page,
) -> bool,
>,
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct clap_host_quick_controls {
pub changed: unsafe extern "C" fn(host: *const clap_host),
pub suggest_page: unsafe extern "C" fn(host: *const clap_host, page_id: clap_id),
pub changed: Option<unsafe extern "C" fn(host: *const clap_host)>,
pub suggest_page: Option<unsafe extern "C" fn(host: *const clap_host, page_id: clap_id)>,
}
34 changes: 19 additions & 15 deletions src/ext/draft/surround.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,28 @@ pub const CLAP_SURROUND_TBR: u32 = 17;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct clap_plugin_surround {
pub get_channel_map: unsafe extern "C" fn(
plugin: *const clap_plugin,
is_input: bool,
port_index: u32,
channel_map: *mut u8,
channel_map_capacity: u32,
) -> u32,
pub changed: unsafe extern "C" fn(plugin: *const clap_plugin),
pub get_channel_map: Option<
unsafe extern "C" fn(
plugin: *const clap_plugin,
is_input: bool,
port_index: u32,
channel_map: *mut u8,
channel_map_capacity: u32,
) -> u32,
>,
pub changed: Option<unsafe extern "C" fn(plugin: *const clap_plugin)>,
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct clap_host_surround {
pub changed: unsafe extern "C" fn(host: *const clap_host),
pub get_preferred_channel_map: unsafe extern "C" fn(
plugin: *const clap_host,
channel_map: *mut u8,
channel_map_capacity: u32,
channel_count: *mut u32,
),
pub changed: Option<unsafe extern "C" fn(host: *const clap_host)>,
pub get_preferred_channel_map: Option<
unsafe extern "C" fn(
plugin: *const clap_host,
channel_map: *mut u8,
channel_map_capacity: u32,
channel_count: *mut u32,
),
>,
}
5 changes: 3 additions & 2 deletions src/ext/draft/track_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@ unsafe impl Sync for clap_track_info {}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct clap_plugin_track_info {
pub changed: unsafe extern "C" fn(plugin: *const clap_plugin),
pub changed: Option<unsafe extern "C" fn(plugin: *const clap_plugin)>,
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct clap_host_track_info {
pub get: unsafe extern "C" fn(host: *const clap_host, info: *mut clap_track_info) -> bool,
pub get:
Option<unsafe extern "C" fn(host: *const clap_host, info: *mut clap_track_info) -> bool>,
}
Loading

0 comments on commit efc0940

Please sign in to comment.