set_len grows a Vec over capacity that was never written

ID

rust.correctness.set_len_called_uninitialized_vectors

Severity

low

Remediation Complexity

medium

Remediation Risk

medium

Remediation Effort

medium

Resource

Undefined Behaviour

Language

Rust

Description

Detects set_len(n) called on a vector immediately after Vec::with_capacity(n), with no statement in between that writes the elements. Sequences that initialise the buffer first — write_bytes, a copy_nonoverlapping through as_mut_ptr, or a safe fill — are not reported, and neither is set_len(0).

Rationale

with_capacity reserves memory without initialising it, so set_len hands out elements that were never written. Reading them is undefined behaviour for every type, and for a type with a destructor the eventual drop runs over garbage, which the optimiser is free to turn into anything at all.

The following code illustrates the pattern detected by this rule:

use std::io::Read;
pub fn read_block(len: usize, source: &mut dyn Read) -> std::io::Result<Vec<u8>> {
    // FLAGGED: set_len grows a Vec over capacity that was never written
    let mut buf = Vec::with_capacity(len);
    unsafe { buf.set_len(len); }
    source.read_exact(&mut buf)?;
    Ok(buf)
}

Remediation

Allocate initialised storage with vec![0; n] or resize, or fill the spare capacity before growing the length — spare_capacity_mut with MaybeUninit, or a write_bytes / copy_nonoverlapping through as_mut_ptr — and only then call set_len.

Configuration

This detector does not need any configuration.

© 2026 Xygeni. All rights reserved