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") Powell
chris@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@maryland
padpowell@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