Nearly every FFI function in provekit-ffi wraps its body in catch_panic(), which:
- Calls
clear_last_error() at entry
- Catches any Rust panic before it unwinds across the
extern "C" boundary
But pk_init is the only function that skips this:
pub extern "C" fn pk_init() -> c_int {
provekit_common::register_ntt(); // no catch_panic
PKStatus::Success.into()
}
This has two major consequences:
-
Undefined behaviour on panic:
- If
register_ntt() panics, the panic may unwind through the extern "C" boundary, causing undefined behaviour in C, which can result in app (iOS/Android) crashes or silent memory corruptions with no recoverable error code.
-
Stale error state after successful init:
- Since
clear_last_error() is never called, any error set by a previous failing FFI call persists after pk_init() returns success. So, pk_get_last_error() after successful pk_init() may show a stale error message from an unrelated failure.
Nearly every FFI function in
provekit-ffiwraps its body incatch_panic(), which:clear_last_error()at entryextern "C"boundaryBut
pk_initis the only function that skips this:This has two major consequences:
Undefined behaviour on panic:
register_ntt()panics, the panic may unwind through the extern "C" boundary, causing undefined behaviour in C, which can result in app (iOS/Android) crashes or silent memory corruptions with no recoverable error code.Stale error state after successful init:
clear_last_error()is never called, any error set by a previous failing FFI call persists afterpk_init()returns success. So,pk_get_last_error()after successfulpk_init()may show a stale error message from an unrelated failure.