AmendHub

Download:

jcs

/

wallops

/

amendments

/

50

util: Fix truncated termination in snprintf, handle 0 length


jcs made amendment 50 8 months ago
--- util.c Wed Nov 30 23:07:36 2022 +++ util.c Thu Feb 1 21:34:37 2024 @@ -1762,10 +1762,10 @@ static struct format { int precision; } default_format; -int bounded_vfprintf(FILE *fp, const char *fmt, va_list arg); +short bounded_vfprintf(FILE *fp, const char *fmt, va_list arg); static int nullio(FILE *fp, int i); -int +short bounded_vfprintf(FILE *fp, const char *fmt, va_list arg) { register int c, i, j, nwritten = 0; @@ -1773,7 +1773,7 @@ bounded_vfprintf(FILE *fp, const char *fmt, va_list ar long double x; register char *s; #define VFPRINTF_BUFLEN 512 - char buf[VFPRINTF_BUFLEN], *digits, *t; + static char buf[VFPRINTF_BUFLEN], *digits, *t; struct format F; for (c = *fmt; c; c = *++fmt) { @@ -2049,7 +2049,7 @@ done: return(nwritten); } -int +short snprintf(char *s, size_t size, const char *fmt, ...) { return(vsnprintf(s, size, fmt, __va(fmt))); @@ -2061,20 +2061,32 @@ nullio(FILE *fp, int i) return(EOF); } -int +short vsnprintf(char *s, size_t size, const char *fmt, void *p) { FILE f; int n; + unsigned char zb; memset(&f, 0, sizeof(f)); f.refnum = -1; - f.ptr = (unsigned char *) s; + f.ptr = (unsigned char *)s; f.cnt = size; f.proc = nullio; f.dirty = 1; - if ((n = bounded_vfprintf(&f, fmt, p)) >= 0) - s[n] = 0; + if (size == 0) + zb = s[0]; + + if ((n = bounded_vfprintf(&f, fmt, p)) >= 0) { + if (n < size) + s[n] = 0; + else + s[size - 1] = 0; + } + + if (size == 0) + s[0] = zb; + return(n); } --- util.h Mon Jan 9 15:46:52 2023 +++ util.h Thu Feb 1 21:34:50 2024 @@ -227,8 +227,8 @@ size_t strlcat(char *dst, const char *src, size_t dsiz size_t strlcpy(char *dst, const char *src, size_t dsize); char * strndup(const char *str, size_t maxlen); char * strsep(char **stringp, const char *delim); -int snprintf(char *s, size_t size, const char *fmt, ...); -int vsnprintf(char *s, size_t size, const char *fmt, void *p); +short snprintf(char *s, size_t size, const char *fmt, ...); +short vsnprintf(char *s, size_t size, const char *fmt, void *p); short strcasecmp(const char *s1, const char *s2); short strncasecmp(const char *s1, const char *s2, size_t n);