rust-lang / rust-lang/rust

`io::stdin().read_to_end()` drops a byte on certain Unicode input (Windows only)

Open
#142,847 7 comments 0 reactions 1 assignee View on GitHub

@Joel-Wwalker is already working on this.

Since Jul 17, 2026.

A-io A-Unicode C-bug O-windows T-libs
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

Description

The method io::stdin().read_to_end() appears to drop a byte when reading certain Unicode input on Windows. The issue occurs when using Vec::new(), and affects only certain input strings.

use std::io::{self, Read, Write};
use std::str;

fn main() -> io::Result<()> {
    let mut stdout = io::stdout();

    write!(stdout, "Enter content : ")?;
    stdout.flush()?;

    // let mut buffer = Vec::with_capacity(1024);  // Reads correctly
    let mut buffer = Vec::new();  // Fails to read correctly
    
    // Paste the provided input and press Ctrl+Z (or Ctrl+D on Linux)
    io::stdin().read_to_end(&mut buffer)?;

    println!("\nBytes read : {:?}", buffer);

    match str::from_utf8(&buffer) {
        Ok(s) => println!("UTF-8 - OK: {}", s),
        Err(e) => println!("UTF-8 - ERROR: {}", e),
    }

    Ok(())
}

With the input:

8216]:есть какое нибудь бюджетное

The resulting read contains the sequence of bytes:

... 208, 208, 181 ... 0
Bytes read : [56, 50, 49, 54, 93, 58, 208, 181, 209, 129, 209, 130, 209, 140, 32, 208, 186, 208, 176, 208, 186, 208, 190, 208, 181, 32, 208, 189, 208, 184, 208, 177, 209, 131, 208, 180, 209, 140, 32, 208, 177, 209, 142, 208, 180, 208, 208, 181, 209, 130, 208, 189, 208, 190, 208, 181, 0]

instead of the expected:

... 208, 182, 208, 181 ...
Bytes read : [56, 50, 49, 54, 93, 58, 208, 181, 209, 129, 209, 130, 209, 140, 32, 208, 186, 208, 176, 208, 186, 208, 190, 208, 181, 32, 208, 189, 208, 184, 208, 177, 209, 131, 208, 180, 209, 140, 32, 208, 177, 209, 142, 208, 180, 208, 182, 208, 181, 209, 130, 208, 189, 208, 190, 208, 181, 10]

As correctly returned by io::stdin().read_line() or io::stdin().read_to_end() on Linux.

Symptoms
  • The issue occurs only with specific Unicode inputs (such as the example above).
  • Removing a character (the first one for example) from the input causes the issue to disappear.
  • When the character loss occurs, read_to_end() appends a null byte at the end of the buffer.
  • The issue only occurs when using:
let mut buffer = Vec::new();
std::io::stdin().read_to_end(&mut buffer)?;
  • The issueis NOT observed when using:
let mut buffer = Vec::with_capacity(1024);
std::io::stdin().read_to_end(&mut buffer)?;
Notes
  • The behavior only appears when using read_to_end() with Vec::new().
  • The behavior is not present when using a preallocated buffer (Vec::with_capacity(1024)), nor when using read_line().
Meta

rustc --version --verbose:

rustc 1.87.0 (17067e9ac 2025-05-09)
binary: rustc
commit-hash: 17067e9ac6d7ecb70e50f92c1944e545188d2359
commit-date: 2025-05-09
host: x86_64-pc-windows-msvc
release: 1.87.0
LLVM version: 20.1.1

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.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.