Reading 0 symbols is pointless
| Vulnerability potential | None |
| DDoS potential | None |
Read size is 0 symbol long
Impact
A read operation is issued with a length of zero — fread(buf, 1, 0, f),
fread(buf, 0, n, f), or read(fd, buf, 0). The call transfers no data and has no
useful effect. By itself it is harmless, but it almost always signals a logic
mistake: a size computed as 0 where a real length was intended (an off-by-one,
an n - n, a forgotten sizeof, or an uninitialized length variable). Code that
then assumes the buffer was populated will act on stale or uninitialized contents.
So the defect matters less for what the zero-length read does and more for what it reveals about a broken size calculation upstream.
Vulnerability potential
A zero-length read has no security impact on its own: it moves no bytes, cannot
overflow a buffer, and cannot leak data. The ratings are None/None. The only
indirect concern is that the underlying size bug — if the same miscomputed length
feeds a write or a copy elsewhere — could be dangerous, but that would be a
different defect at that site, not this read.
Technical details
fread semantics
fread(ptr, size, nmemb, stream) reads size * nmemb bytes. If either size or
nmemb is 0, it reads nothing and returns 0, leaving the file position
unchanged and not touching the buffer. A caller that checks fread(...) == nmemb
will see 0 == 0 succeed and wrongly conclude a full read happened.
read(2) semantics
read(fd, buf, 0) returns 0 and has no other effect. Critically, a return of
0 from read normally means end-of-file; a zero-length request also returns
0, so a loop using “read returned 0 ⇒ EOF” may terminate prematurely or
misbehave when the count was accidentally zero.
Where the zero comes from
Typical sources: sizeof(ptr) vs sizeof(*ptr) confusion collapsing to a small
or zero value, a length parsed from input that defaulted to 0, or arithmetic
like end - start where the bounds are equal.
Catching the issue
Compiler warnings
GCC/Clang with -Wall -Wextra warn on some constant zero-size allocations and
suspicious sizeof usage. Review any “argument is zero” notes.
Static analysis
The analyzer emitting this diagnostic, plus Cppcheck/clang-tidy, can constant-fold
the size argument and report when it is provably 0. They also flag the common
sizeof mistakes that produce it.
Runtime asserts and review
Assert that computed I/O sizes are non-zero where a non-empty transfer is
expected, and always compare fread/read return values against the requested
count and against 0-means-EOF semantics, rather than assuming success.
How to reproduce
Run this: fread is asked for 0 bytes, returns 0, leaves buf uninitialized,
yet the success check passes — observe that the printed data is garbage.
#include <stdio.h>
int main(void)
{
FILE *f = fopen("/etc/hostname", "r");
if (!f) return 1;
char buf[64] = {0};
size_t want = 0; /* miscomputed length: should be > 0 */
size_t got = fread(buf, 1, want, f); /* reads nothing */
if (got == want) /* 0 == 0: looks like success */
printf("read ok: '%s'\n", buf); /* but buf was never filled */
fclose(f);
return 0;
}