The story of how I goofed up and nobody noticed for years.
7 May 1997
In the spring and summer of 1991, my friend Linus was playing
around with this OS-like program, which later became Linux. He
printf like service inside the kernel,
but didn't know how to implement it, though (he didn't know C
thoroughly back then). So I wrote him an
and he used that, after some modifications.
In September of 1994, Friedemann Baitinger at IBM, who was
developing a device driver for another operating system, used
sprintf clone as a debugging aid (but not in the
final product). The bug lived for three or three and a half
years before anyone found it. Worse, the bug was immediately
obvious as soon as one tried to use the function in a certain,
common way. No-one had done that, ever, not even I when I wrote
it. Don't ever hire me to write code that is expected to work.
The bug was in the handling of a field width given via the argument
sprintf, to print a string, for example,
you would write
sprintf(buf, "%s", str);
This would put the
str' string intobuf'.
allows formatting of the output:
sprintf(buf, "%10s", str);
This would make the output string at least 10 characters wide (wider, if `str' is wider). The field width can be a constant, or it can be given as a separate argument:
sprintf(buf, "%*s", 10, str);
This gives the same output as before, but triggered my bug.
sprintf was implemented with a loop that walked
through the format string and incremented an index when it
processed various parts of the format string. Except that when
it processed the `*', it didn't increment. Oops.
So why do I explain this so thoroughly? My weird sense of humor made me put ``Author of the longest-living Linux bug'' in the CREDITS file in the kernel sources, and people sometimes ask me about it. I figured I'd answer it once, and point people at this web page.