Skip to content

Commit 5c15a49

Browse files
committed
Merge #524: Document unsafe code
6d74730 secp256k1: Document safety constraints (Tobin C. Harding) 85681ce secp256k1-sys: Document safety constraints (Tobin C. Harding) Pull request description: Functions that are `unsafe` should include a `# Safety` section. - Patch 1: Documents `unsafe` methods in `secp256k1-sys`. Please not this includes a minor refactor. - Patch 2: Documents the `unsafe` `Context` trait Together these two patches remove `#![allow(clippy::missing_safety_doc)]` from the repo. Fix: #447 ## Note to reviewers The only function that was curly to understand the safety of was `secp256k1_context_create`, all the other stuff should be trivial to review. ACKs for top commit: apoelstra: ACK 6d74730 Tree-SHA512: 247216c3f9e655fe8c2854b71613b31b6241318e877e83a1e4873ce84e481975a832d05cd748577f437f88b166ff287a537d26c012568e7378caed458ec55867
2 parents fb45ae4 + 6d74730 commit 5c15a49

File tree

3 files changed

+49
-16
lines changed

3 files changed

+49
-16
lines changed

secp256k1-sys/src/lib.rs

+41-15
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919
// Coding conventions
2020
#![deny(non_upper_case_globals, non_camel_case_types, non_snake_case, unused_mut)]
2121

22-
#![allow(clippy::missing_safety_doc)]
23-
2422
#![cfg_attr(all(not(test), not(feature = "std")), no_std)]
2523
#![cfg_attr(docsrs, feature(doc_cfg))]
2624

@@ -781,10 +779,25 @@ extern "C" {
781779
///
782780
/// Input `flags` control which parts of the context to initialize.
783781
///
782+
/// # Safety
783+
///
784+
/// This function is unsafe because it calls unsafe functions however (assuming no bugs) no
785+
/// undefined behavior is possible.
786+
///
784787
/// # Returns
785788
///
786789
/// The newly created secp256k1 raw context.
790+
#[cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))]
791+
#[cfg_attr(docsrs, doc(cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))))]
792+
pub unsafe fn secp256k1_context_create(flags: c_uint) -> *mut Context {
793+
rustsecp256k1_v0_6_1_context_create(flags)
794+
}
795+
796+
/// A reimplementation of the C function `secp256k1_context_create` in rust.
797+
///
798+
/// See [`secp256k1_context_create`] for documentation and safety constraints.
787799
#[no_mangle]
800+
#[allow(clippy::missing_safety_doc)] // Documented above.
788801
#[cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))]
789802
#[cfg_attr(docsrs, doc(cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))))]
790803
pub unsafe extern "C" fn rustsecp256k1_v0_6_1_context_create(flags: c_uint) -> *mut Context {
@@ -805,19 +818,23 @@ pub unsafe extern "C" fn rustsecp256k1_v0_6_1_context_create(flags: c_uint) -> *
805818
secp256k1_context_preallocated_create(ptr, flags)
806819
}
807820

808-
#[cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))]
809-
#[cfg_attr(docsrs, doc(cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))))]
810-
pub unsafe fn secp256k1_context_create(flags: c_uint) -> *mut Context {
811-
rustsecp256k1_v0_6_1_context_create(flags)
812-
}
813-
814821
/// A reimplementation of the C function `secp256k1_context_destroy` in rust.
815822
///
816823
/// This function destroys and deallcates the context created by `secp256k1_context_create`.
817824
///
818825
/// The pointer shouldn't be used after passing to this function, consider it as passing it to `free()`.
819826
///
827+
/// # Safety
828+
///
829+
/// `ctx` must be a valid pointer to a block of memory created using [`secp256k1_context_create`].
830+
#[cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))]
831+
#[cfg_attr(docsrs, doc(cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))))]
832+
pub unsafe fn secp256k1_context_destroy(ctx: *mut Context) {
833+
rustsecp256k1_v0_6_1_context_destroy(ctx)
834+
}
835+
820836
#[no_mangle]
837+
#[allow(clippy::missing_safety_doc)] // Documented above.
821838
#[cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))]
822839
#[cfg_attr(docsrs, doc(cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))))]
823840
pub unsafe extern "C" fn rustsecp256k1_v0_6_1_context_destroy(ctx: *mut Context) {
@@ -829,13 +846,6 @@ pub unsafe extern "C" fn rustsecp256k1_v0_6_1_context_destroy(ctx: *mut Context)
829846
alloc::dealloc(ptr, layout);
830847
}
831848

832-
#[cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))]
833-
#[cfg_attr(docsrs, doc(cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))))]
834-
pub unsafe fn secp256k1_context_destroy(ctx: *mut Context) {
835-
rustsecp256k1_v0_6_1_context_destroy(ctx)
836-
}
837-
838-
839849
/// **This function is an override for the C function, this is the an edited version of the original description:**
840850
///
841851
/// A callback function to be called when an illegal argument is passed to
@@ -854,6 +864,12 @@ pub unsafe fn secp256k1_context_destroy(ctx: *mut Context) {
854864
///
855865
/// See also secp256k1_default_error_callback_fn.
856866
///
867+
///
868+
/// # Safety
869+
///
870+
/// `message` string should be a null terminated C string and, up to the first null byte, must be valid UTF8.
871+
///
872+
/// For exact safety constraints see [`std::slice::from_raw_parts`] and [`std::str::from_utf8_unchecked`].
857873
#[no_mangle]
858874
#[cfg(not(rust_secp_no_symbol_renaming))]
859875
pub unsafe extern "C" fn rustsecp256k1_v0_6_1_default_illegal_callback_fn(message: *const c_char, _data: *mut c_void) {
@@ -877,6 +893,11 @@ pub unsafe extern "C" fn rustsecp256k1_v0_6_1_default_illegal_callback_fn(messag
877893
///
878894
/// See also secp256k1_default_illegal_callback_fn.
879895
///
896+
/// # Safety
897+
///
898+
/// `message` string should be a null terminated C string and, up to the first null byte, must be valid UTF8.
899+
///
900+
/// For exact safety constraints see [`std::slice::from_raw_parts`] and [`std::str::from_utf8_unchecked`].
880901
#[no_mangle]
881902
#[cfg(not(rust_secp_no_symbol_renaming))]
882903
pub unsafe extern "C" fn rustsecp256k1_v0_6_1_default_error_callback_fn(message: *const c_char, _data: *mut c_void) {
@@ -886,6 +907,11 @@ pub unsafe extern "C" fn rustsecp256k1_v0_6_1_default_error_callback_fn(message:
886907
panic!("[libsecp256k1] internal consistency check failed {}", msg);
887908
}
888909

910+
/// Returns the length of the `str_ptr` string.
911+
///
912+
/// # Safety
913+
///
914+
/// `str_ptr` must be valid pointer and point to a valid null terminated C string.
889915
#[cfg(not(rust_secp_no_symbol_renaming))]
890916
unsafe fn strlen(mut str_ptr: *const c_char) -> usize {
891917
let mut ctr = 0;

src/context.rs

+8
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,20 @@ pub mod global {
6262

6363
/// A trait for all kinds of contexts that lets you define the exact flags and a function to
6464
/// deallocate memory. It isn't possible to implement this for types outside this crate.
65+
///
66+
/// # Safety
67+
///
68+
/// This trait is marked unsafe to allow unsafe implementations of `deallocate`.
6569
pub unsafe trait Context: private::Sealed {
6670
/// Flags for the ffi.
6771
const FLAGS: c_uint;
6872
/// A constant description of the context.
6973
const DESCRIPTION: &'static str;
7074
/// A function to deallocate the memory when the context is dropped.
75+
///
76+
/// # Safety
77+
///
78+
/// `ptr` must be valid. Further safety constraints may be imposed by [`std::alloc::dealloc`].
7179
unsafe fn deallocate(ptr: *mut u8, size: usize);
7280
}
7381

src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,6 @@
152152
// Coding conventions
153153
#![deny(non_upper_case_globals, non_camel_case_types, non_snake_case)]
154154
#![warn(missing_docs, missing_copy_implementations, missing_debug_implementations)]
155-
#![allow(clippy::missing_safety_doc)]
156155
#![cfg_attr(all(not(test), not(feature = "std")), no_std)]
157156
// Experimental features we need.
158157
#![cfg_attr(docsrs, feature(doc_cfg))]

0 commit comments

Comments
 (0)