rust-lang / rust-lang/rust-clippy

Lint against `String::from_raw_parts`

Open
#14,293 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-lint
Dominant language
Rust
Stars
13.5k
Forks
2.2k
Avg merge
2d 10h
Merged PRs (30d)
32

Description

What it does

Lints against usages of String::from_raw_parts. This should be done in two steps, Vec::from_raw_parts and String::from_utf8_unchecked.

https://github.com/rust-lang/rust/pull/136775 updated String::from_raw_parts's docs to delegate the safety requirements to Vec::from_raw_parts's and String::from_utf8_unchecked's docs anyway.

Advantage
  • String::from_raw_parts has conflated safety requirements that should be justified in two steps:
    • Vec::from_raw_parts has complicated language-level safety requirements that have to be manually justified and are insta-UB (?) if violated
    • String::from_utf8_unchecked has a relatively trivial library-level safety requirement, that could be checked by using String::from_utf8 instead
Drawbacks

No response

Example
// SAFETY: 
// * `ptr` was allocated using the global allocator
// * `T` (= `u8`) has the same alignment as what `ptr` was allocated with
// * The size of T (= u8) times the capacity is the same size as `ptr` was allocated with
// * `len` is use for both `len` and `capacity`
// * The first `len` values are properly initialized values of type `T` (= `u8`).
// * `capacity` (= `len`) is the capacity that `ptr` was allocated with.
// * The allocated size in bytes is no larger than `isize::MAX`
// * The bytes contain valid UTF-8
let string = unsafe { String::from_raw_parts(pointer, len) };

Could be written as:

// SAFETY: 
// * `ptr` was allocated using the global allocator
// * `T` (= `u8`) has the same alignment as what `ptr` was allocated with
// * The size of T (= u8) times the capacity is the same size as `ptr` was allocated with
// * `len` is use for both `len` and `capacity`
// * The first `len` values are properly initialized values of type `T` (= `u8`).
// * `capacity` (= `len`) is the capacity that `ptr` was allocated with.
// * The allocated size in bytes is no larger than `isize::MAX`
let bytes = unsafe { Vec::from_raw_parts(ptr, len, len) };
// SAFETY: 
// * The bytes contain valid UTF-8
let string = unsafe { String::from_utf8_unchecked(bytes) };

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the issue's examples alongside the safety documentation for Vec::from_raw_parts and String::from_utf8_unchecked, and inspect existing Rust Clippy lint patterns. Done means usages of String::from_raw_parts are diagnosed with guidance to split the operation into those two steps, with coverage for the shown example.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.