-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Description
What it does
This lint catches reads into a zero-length Vec
. For instance, it should flag code like this:
let mut data = Vec::with_capacity(len);
r.read_exact(&mut data)?;
In general, it should flag any code that constructs a Vec
(whether using new
or vec![]
or especially with_capacity
) and then reads into it (using read
or read_exact
, whether sync or async versions) without changing the size of the Vec
. The lint should warn that the number of bytes read depends on the size of the buffer read into, so this pattern will read 0 bytes. And in the specific case of a call to with_capacity
, the lint should warn that read gets the number of bytes from the Vec
's length, not its capacity.
In the with_capacity
case, the lint should suggest adding something like data.resize(len, 0);
; in other cases the lint can more generally suggest resizing before reading, or calling read_to_end
.
Lint Name
read_zero_byte_vec
Category
correctness
Advantage
Correctness: reading zero bytes is almost certainly not the intended behavior of this code. This lint would catch a bug.
I've seen multiple instances of this bug, and I just wrote one myself.
Drawbacks
In theory, a very unusual read implementation could assign some semantic meaning to zero-byte reads. But it seems exceptionally unlikely that code intending to do a zero-byte read would allocate a Vec
for it.
Example
let mut data = Vec::with_capacity(len);
r.read_exact(&mut data)?;
Could be written as:
let mut data = Vec::with_capacity(len);
data.resize(len, 0);
r.read_exact(&mut data)?;
let mut data = Vec::with_capacity(len);
r.read_exact(&mut data).await?;
Could be written as:
let mut data = Vec::with_capacity(len);
data.resize(len, 0);
r.read_exact(&mut data).await?;