padpowell@wateng.UUCP (PAD Powell) (08/19/84)
Once again I have been stung with by sprintf(). Why was sprintf() not
provided with a "bounds" check version, like
sprintf( target, count, format, args )
char *target, *format;
int count;
void args;
I am seriously considering adding this functionailt, and calling it
snprintf(), A LA strcmp(), strncmp().
Problems caused by overflowing the allocated string took two days
to track down, as sprintf was corrupting some MALLOC headers...
If anybody has comments or suggestions, I would be more than happy to hear them.
Patrick ("And don't even mention Garbage Collection") Powellchris@umcp-cs.UUCP (Chris Torek) (08/20/84)
I've already complained about that one here. Here's an ``sprintfl''
that does a counted sprintf and works on BSD Vaxen:
#include <stdio.h>
char *sprintfl (buf, len, fmt, arg)
register char *buf;
register int len;
char *fmt;
{
struct _iobuf s;
if (len <= 0)
return;
if (--len <= 0) { /* use sobgtr */
*buf = 0;
return;
}
s._ptr = buf;
s._cnt = len;
s._flag = _IOSTRG; /* leave out _IOWRT! */
_doprnt (fmt, &arg, &s);
buf[len] = 0;
return buf;
}
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci (301) 454-7690
UUCP: {seismo,allegra,brl-bmd}!umcp-cs!chris
CSNet: chris@umcp-cs ARPA: chris@marylandpadpowell@wateng.UUCP (PAD Powell) (08/22/84)
INTRODUCTION
Having been burned several times by the behaviour of sprintf,
I have just finished testing a new version, called snprintf,
and sxprintf, which have the exact functionality of sprintf,
but do bound checking.
In doing this, I discovered a couple of minor coding glitches in the
_doprnt() routine. It was written in assembler, and the authors
have my sympathy. I have the funniest feeling that many of the
sections of the conversion routines were DEC VMS sources.
It uses some of the very baroque VAX instructions...
I was going to post the changes to doprnt(), but discovered that the
diffs were longer than the source. I wonder if there is any problems
in posting the entire source to doprnt.s?
Patrick Powell,
U. Waterloo, VLSI Design Group,
Waterloo Ont.
SUMMARY
snprintf( count, str, format, args )
int count; char *str, *format, ...;
Exact functionality of sprintf, but will only generate count characters,
including trailing 0. If it fails, it returns a NULL, otherwise it
returns s.
sxprintf( count, str, format, args )
int count; char *str, *format, ...;
This has the exact functionality of snprintf, in that it does bound checking.
It does not append a trailing 0, and allows very nice reformatting of
fixed field items.
INSTALLATION
1. copy the snprintf.c,sxprintf.c,sprintf.c to /usr/src/lib/libc/stdio
NOTE: save the old versions, you might want them.
2. copy doprnt.s to /usr/src/lib/libc/vax/stdio
3. update the lint library, by copying the llib-lc to
/usr/src/usr.lib/lint/llib-lc, and then making the new lint libs
5. compile the lc library (moan).
Actually, you can shorten this by using the make file,
which has a quick "update" entry. This does an "ar u *.o"
on the object files and the /usr/lib/llibc
What are the benefits?
1. A bombproof version of the stdio library routines that does bounds
checking.
2. A COMMENTED version of _doprnt.c, which also has some added error checking.
Patrick ("I hate sprintf") Powell