rust-lang / rust-lang/rust-clippy

checking for short writes (programmer uses write instead of write_all)

Open
#8,362 0 comments 5 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

In Rust, the write method of the Write trait is a best effort - it may write only some bytes. A subtle mistake is to forget and code like so:

fn main() -> io::Result<()> {
    let mut reader = io::stdin();
    let mut buffer = [0u8; 65536];
    while {
        let size = reader.read(&mut buffer)?;
        io::stdout().write(&buffer[..size])? > 0
    } {}
    Ok(())
}
use std::io::{self, Read, Write};

which leads to hard to detect failures.

The error is where the check io::stdout().write(&buffer[..size])? > 0 is located. Comparing the result of a write to zero is wrong/insufficient.

Perhaps clippy should look for a code path where the return value is compared for equality or an upper bound.

Lint Name

short-write-checker

Category

suspicious

Advantage

Clippy should explain that read may not write all data.

Drawbacks

If size is equal to 1, or if the programmer doesn't care about short writes, it may be a false positive.

Example
fn main() -> io::Result<()> {
    let mut reader = io::stdin();
    let mut buffer = [0u8; 65536];
    while {
        let size = reader.read(&mut buffer)?;
        io::stdout().write(&buffer[..size])? > 0
    } {}
    Ok(())
}
use std::io::{self, Read, Write};

Could be written as:

fn main() -> io::Result<()> {
    let mut reader = io::stdin();
    let mut buffer = [0u8; 65536];
    while {
        let size = reader.read(&mut buffer)?;
        io::stdout().write_all(&buffer[..size])?;
        size > 0
    } {}
    Ok(())
}
use std::io::{self, Read, Write};

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 with the Rust Write trait and the supplied short-write example, then inspect Clippy's existing suspicious lints to determine where this lint and its tests belong. Done means the lint reliably identifies the described comparison pattern, explains the short-write risk, and avoids the false-positive cases noted in the issue.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.