--- pserror.c +++ pserror.c 2005-04-04 18:02:22.000000000 +0200 @@ -17,16 +17,17 @@ warnings, and errors sent to stderr. If called with the flags MESSAGE_EXIT set, the routine does not return */ -#define MAX_MESSAGE 256 /* maximum formatted message length */ +#define MAX_MESSAGE 1024 /* maximum formatted message length */ #define MAX_FORMAT 16 /* maximum format length */ #define MAX_COLUMN 78 /* maximum column to print upto */ void message(int flags, char *format, ...) { va_list args ; - static column = 0 ; /* current screen column for message wrap */ - char msgbuf[MAX_MESSAGE] ; /* buffer in which to put the message */ - char *bufptr = msgbuf ; /* message buffer pointer */ + static int column = 0 ; /* current screen column for message wrap */ + char msgbuf[MAX_MESSAGE]; /* buffer in which to put the message */ + char *bufptr = msgbuf; /* message buffer pointer */ + char *tail = bufptr + MAX_MESSAGE; if ( (flags & MESSAGE_NL) && column != 0 ) { /* new line if not already */ putc('\n', stderr) ; @@ -34,8 +35,11 @@ } if ( flags & MESSAGE_PROGRAM ) { + const size_t len = strlen(program); + if (len + 2 >= tail - bufptr) + goto out; strcpy(bufptr, program) ; - bufptr += strlen(program) ; + bufptr += len; *bufptr++ = ':' ; *bufptr++ = ' ' ; } @@ -55,13 +59,15 @@ fmtbuf[index] = '\0' ; switch (c) { case '%': + if (bufptr >= tail) + goto out; *bufptr++ = '%' ; case '\0': break ; case 'e': case 'E': case 'f': case 'g': case 'G': { double d = va_arg(args, double) ; - sprintf(bufptr, fmtbuf, d) ; + snprintf(bufptr, tail - bufptr, fmtbuf, d); bufptr += strlen(bufptr) ; } break ; @@ -69,17 +75,17 @@ case 'p': case 'u': case 'x': case 'X': if ( longform ) { long l = va_arg(args, long) ; - sprintf(bufptr, fmtbuf, l) ; + snprintf(bufptr, tail - bufptr, fmtbuf, l); } else { int i = va_arg(args, int) ; - sprintf(bufptr, fmtbuf, i) ; + snprintf(bufptr, tail - bufptr, fmtbuf, i); } bufptr += strlen(bufptr) ; break ; case 's': { char *s = va_arg(args, char *) ; - sprintf(bufptr, fmtbuf, s) ; + snprintf(bufptr, tail - bufptr, fmtbuf, s); bufptr += strlen(bufptr) ; } break ; @@ -92,6 +98,8 @@ } while ( !done ) ; } else if ( c == '\n' ) { /* write out message so far and reset column */ int len = bufptr - msgbuf ; /* length of current message */ + if (bufptr >= tail) + goto out; *bufptr++ = '\n' ; *bufptr = '\0' ; if ( column + len > MAX_COLUMN && column > 0 ) { @@ -100,8 +108,11 @@ } fputs(bufptr = msgbuf, stderr) ; column = 0 ; - } else + } else { + if (bufptr >= tail) + goto out; *bufptr++ = c ; + } } *bufptr = '\0' ; { @@ -117,6 +128,7 @@ } va_end(args) ; - if ( flags & MESSAGE_EXIT ) /* don't return to program */ +out: + if (flags & MESSAGE_EXIT) /* don't return to program */ exit(1) ; }