Skip to content

Conversation

@tcharding
Copy link
Member

@tcharding tcharding commented Nov 21, 2022

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.

@tcharding tcharding force-pushed the 11-22-document-unsafe branch from a53b59c to 7e00f4b Compare November 21, 2022 21:38
///
/// # Safety
///
/// For safety constraints see [`std::slice::from_raw_parts`] and [`std::str::from_utf8_unchecked`].
Copy link
Member

@apoelstra apoelstra Nov 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In 6e19635:

I don't understand what std::str::from_utf8_unchecked has to do with anything here. slice::from_raw_parts is sorta relevant but it's really overkill because it's talking in terms of an anbitrary T but we're using C characters, which are one byte in size, have one-byte alignment, and have no trap representatons.

It would be clearer I think to just say that message must be a valid pointer to an initialized null-terminated C string.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see, the reason you're citing these is because in our default callback function we call from_utf8_unchecked after using strlen to compute a bound on the string in order to convert it to a u8 slice.

So we should add the additional requirement then that the string, up to the first null byte, must be valid UTF8.

Alternately we could call CStr::from_ptr (and copy its safety bounds which are sensible for this funciton) and then CStr::to_str which is safe but returns a Result, which we could just .unwrap_or("<invalid UTF8>" or something.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interestingly, doing this would eliminate our strlen funciton entirely, which is nice.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, that turned out nice. Pushed as a separate patch.

@tcharding
Copy link
Member Author

The docs say that CStr::from_ptr takes a *const c_char [0] and that a c_char is type aliased to i8 [1]. I'm confused by the CI fails, we have a function that takes a *const c_char and passes it to CStr::from_ptr but on some architectures there is some sort of mix up between u8 and i8?

[0] https://doc.rust-lang.org/stable/core/ffi/struct.CStr.html#method.from_ptr
[1] https://doc.rust-lang.org/stable/core/ffi/type.c_char.html

@apoelstra
Copy link
Member

[1] is not the right reference. Our actual code uses https://github.com/rust-bitcoin/rust-secp256k1/blob/master/secp256k1-sys/src/types.rs#L8-L10 because, as your docs show, the official c_char has only been stable since 1.64.

I think we should just add a comment and do a cast/transmute here.

@tcharding
Copy link
Member Author

tcharding commented Nov 23, 2022

Ah of course, masked behind us always importing types::*. Thanks for the answer.

@tcharding
Copy link
Member Author

Oh bother, the CStr type is also only available in Rust 1.64

Functions that are `unsafe` should include a `# Safety` section. Because
we have wrapper functions to handle symbol renaming we essentially have
duplicate functions i.e., they require the same docs, instead of
duplicating the docs put the symbol renamed function below the
non-renamed function and add a docs linking to the non-renamed function.
Also add attribute to stop the linter warning about the missing safety
docs section.

Remove the clippy attribute for `missing_safety_doc`.
Add a `# Safety` section to all unsafe traits, methods, and functions.

Remove the clippy attribute for `missing_safety_doc`.
@tcharding tcharding force-pushed the 11-22-document-unsafe branch from 4b1e8c3 to 6d74730 Compare November 23, 2022 22:17
@tcharding
Copy link
Member Author

I've removed the CStr usage and attempted to improve the docs in patch 1.

@apoelstra
Copy link
Member

Oh bother, the CStr type is also only available in Rust 1.64

Oh, derp.

I feel like all this C interop stuff showed up 8 years later than I would've expected it to.

@apoelstra
Copy link
Member

Looks good now!

Copy link
Member

@apoelstra apoelstra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 6d74730

@elichai
Copy link
Member

elichai commented Nov 24, 2022

Oh bother, the CStr type is also only available in Rust 1.64

Yeah it wasn't available in core at the time that I've wrote this code, and it's still higher than our MSRV

Copy link
Member

@apoelstra apoelstra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 6d74730

@apoelstra apoelstra merged commit 5c15a49 into rust-bitcoin:master Nov 24, 2022
@tcharding tcharding deleted the 11-22-document-unsafe branch November 30, 2022 01:23
chain-forgexcr45 added a commit to chain-forgexcr45/rust-secp256k1 that referenced this pull request Sep 28, 2025
6d747301e8dcdf5744ced973d2e2c36cdce21be4 secp256k1: Document safety constraints (Tobin C. Harding)
85681cece7e5b66a6e72abece678b9f0ae65a782 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 6d747301e8dcdf5744ced973d2e2c36cdce21be4

Tree-SHA512: 247216c3f9e655fe8c2854b71613b31b6241318e877e83a1e4873ce84e481975a832d05cd748577f437f88b166ff287a537d26c012568e7378caed458ec55867
william2332-limf added a commit to william2332-limf/rust-secp256k1 that referenced this pull request Oct 2, 2025
6d747301e8dcdf5744ced973d2e2c36cdce21be4 secp256k1: Document safety constraints (Tobin C. Harding)
85681cece7e5b66a6e72abece678b9f0ae65a782 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 6d747301e8dcdf5744ced973d2e2c36cdce21be4

Tree-SHA512: 247216c3f9e655fe8c2854b71613b31b6241318e877e83a1e4873ce84e481975a832d05cd748577f437f88b166ff287a537d26c012568e7378caed458ec55867
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Document unsafe code

3 participants