Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove unsafe from serde and add #![forbid(unsafe_code)] #2096

Closed
bkontur opened this issue Sep 27, 2021 · 5 comments
Closed

remove unsafe from serde and add #![forbid(unsafe_code)] #2096

bkontur opened this issue Sep 27, 2021 · 5 comments

Comments

@bkontur
Copy link

bkontur commented Sep 27, 2021

we are trying to use safe external dependencies as much as possible, means checked by cargo geiger,
and we found that, there is a only one unsafe usage in serde:
https://github.com/serde-rs/serde/blob/v1.0.130/serde/src/ser/impls.rs#L739

// We've only written ASCII bytes to the buffer, so it is valid UTF-8
serializer.serialize_str(unsafe { str::from_utf8_unchecked(&buf[..written]) })

do you think it is possible to rewrite this code without unsafe usage?
if yes, then you could add #![forbid(unsafe_code)] to the lib.rs and make it safe for cargo geiger

we made a temporary fork to support our needs here:
https://github.com/tezedge/serde/tree/cleanup-unsafe

@Lokathor
Copy link

Skipping the additional utf8 check when you know you've only written ascii is exactly the sort of speedup situation that having unsafe is supposed to enable.

@jonasbb
Copy link
Contributor

jonasbb commented Sep 30, 2021

It is worth noting that this unsafe code got introduced as part of #2001 to fix a performance issue. Any reversal of this should probably check that the performance loss is acceptable.

@danielhenrymantilla
Copy link

If it's just for one instance of unsafe, what about exposing an extra Cargo feature which would replace that unsafe usage with a checked body?

//! src/lib.rs
#![cfg_attr(feature = "forbid-unsafe", forbid(unsafe_code))]
let ascii_str = str::from_utf8(&buf[.. written]).unwrap_or_else(|_err| {
    #[cfg(feature = "forbid-unsafe")]
    unreachable!("Expected ASCII bytes only: {}", _err);

    #[cfg(not(feature = "forbid-unsafe"))]
    unsafe {
        ::core::hint::unreachable_unchecked();
    }
});
serializer.serialize_str(ascii_str)

That way the safety-(over-)zealous people would be able to ensure serde uses no unsafe, while the rest of the community can still be using the slightly more performant implementation that skips the unnecessary UTF-8 check.

@golddranks
Copy link

golddranks commented Sep 30, 2021

There is a draft RFC for Cargo applying patches, that makes it easier for downstream projects to customize their dependencies. This looks like a potential use case. Here's the draft: rust-lang/rfcs#3177

@dtolnay
Copy link
Member

dtolnay commented Sep 30, 2021

I would prefer not to make this change, but I do welcome scrutiny of whether any unsafe code in serde or its dependencies is correct. FWIW unsafe code in serde is probably scrutinized >10× more than the typical unsafe usage in the Rust standard library (but I still have never understood why people feel compelled to treat it so differently).

@dtolnay dtolnay closed this as completed Sep 30, 2021
@serde-rs serde-rs locked and limited conversation to collaborators Mar 7, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

No branches or pull requests

6 participants