Skip to content

Commit 5b2cced

Browse files
committed
Handle all OpenFX errors
A *real* `#[must_use]` annotation should stop any unhandled errors from slipping through. *This* fixes the Nuke crash--we were dereferencing a null pointer returned by a function call that errored.
1 parent c83e95d commit 5b2cced

File tree

3 files changed

+174
-92
lines changed

3 files changed

+174
-92
lines changed

crates/openfx-plugin/build.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ fn main() {
1919
.header("wrapper.h")
2020
.blocklist_function("OfxGetNumberOfPlugins")
2121
.blocklist_function("OfxGetPlugin")
22-
.must_use_type("OfxStatus")
22+
// We wrap the OfxStatus enum in a newtype struct so we can annotate it with #[must_use].
23+
.blocklist_type("OfxStatus")
24+
.blocklist_var("kOfxStat.+")
2325
// Tell cargo to invalidate the built crate whenever any of the
2426
// included header files changed.
2527
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))

crates/openfx-plugin/src/bindings.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,60 @@
44
#![allow(unused)]
55
#![allow(clippy::all)]
66

7+
#[must_use]
8+
#[repr(transparent)]
9+
#[derive(Clone, Copy, PartialEq, Eq)]
10+
pub struct OfxStatus(pub std::ffi::c_int);
11+
12+
impl std::fmt::Debug for OfxStatus {
13+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14+
match self.0 {
15+
0 => f.write_str("kOfxStatOK"),
16+
1 => f.write_str("kOfxStatFailed"),
17+
2 => f.write_str("kOfxStatErrFatal"),
18+
3 => f.write_str("kOfxStatErrUnknown"),
19+
4 => f.write_str("kOfxStatErrMissingHostFeature"),
20+
5 => f.write_str("kOfxStatErrUnsupported"),
21+
6 => f.write_str("kOfxStatErrExists"),
22+
7 => f.write_str("kOfxStatErrFormat"),
23+
8 => f.write_str("kOfxStatErrMemory"),
24+
9 => f.write_str("kOfxStatErrBadHandle"),
25+
10 => f.write_str("kOfxStatErrBadIndex"),
26+
11 => f.write_str("kOfxStatErrValue"),
27+
12 => f.write_str("kOfxStatReplyYes"),
28+
13 => f.write_str("kOfxStatReplyNo"),
29+
14 => f.write_str("kOfxStatReplyDefault"),
30+
_ => f.debug_tuple("OfxStatus").field(&self.0).finish(),
31+
}
32+
}
33+
}
34+
35+
impl From<std::ffi::c_int> for OfxStatus {
36+
fn from(value: std::ffi::c_int) -> Self {
37+
Self(value)
38+
}
39+
}
40+
41+
// bindgen can't import these
42+
#[allow(dead_code)]
43+
pub mod OfxStat {
44+
use crate::bindings::OfxStatus;
45+
46+
pub const kOfxStatOK: OfxStatus = OfxStatus(0);
47+
pub const kOfxStatFailed: OfxStatus = OfxStatus(1);
48+
pub const kOfxStatErrFatal: OfxStatus = OfxStatus(2);
49+
pub const kOfxStatErrUnknown: OfxStatus = OfxStatus(3);
50+
pub const kOfxStatErrMissingHostFeature: OfxStatus = OfxStatus(4);
51+
pub const kOfxStatErrUnsupported: OfxStatus = OfxStatus(5);
52+
pub const kOfxStatErrExists: OfxStatus = OfxStatus(6);
53+
pub const kOfxStatErrFormat: OfxStatus = OfxStatus(7);
54+
pub const kOfxStatErrMemory: OfxStatus = OfxStatus(8);
55+
pub const kOfxStatErrBadHandle: OfxStatus = OfxStatus(9);
56+
pub const kOfxStatErrBadIndex: OfxStatus = OfxStatus(10);
57+
pub const kOfxStatErrValue: OfxStatus = OfxStatus(11);
58+
pub const kOfxStatReplyYes: OfxStatus = OfxStatus(12);
59+
pub const kOfxStatReplyNo: OfxStatus = OfxStatus(13);
60+
pub const kOfxStatReplyDefault: OfxStatus = OfxStatus(14);
61+
}
62+
763
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));

0 commit comments

Comments
 (0)