upstream commit

Fix two rare edge cases: 1. If vasprintf() returns < 0,
 do not access a NULL pointer in snmprintf(), and do not free() the pointer
 returned from vasprintf() because on some systems other than OpenBSD, it
 might be a bogus pointer. 2. If vasprintf() returns == 0, return 0 and ""
 rather than -1 and NULL.

Besides, free(dst) is pointless after failure (not a bug).

One half OK martijn@, the other half OK deraadt@;
committing quickly before people get hurt.

Upstream-ID: b7bcd2e82fc168a8eff94e41f5db336ed986fed0
This commit is contained in:
schwarze@openbsd.org 2016-05-30 12:05:56 +00:00 committed by Darren Tucker
parent 0e059cdf5f
commit ac284a355f
1 changed files with 18 additions and 10 deletions

28
utf8.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: utf8.c,v 1.1 2016/05/25 23:48:45 schwarze Exp $ */
/* $OpenBSD: utf8.c,v 1.2 2016/05/30 12:05:56 schwarze Exp $ */
/*
* Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
*
@ -81,13 +81,15 @@ vasnmprintf(char **str, size_t maxsz, int *wp, const char *fmt, va_list ap)
int width; /* Display width of the character wc. */
int total_width, max_width, print;
src = dst = NULL;
if (vasprintf(&src, fmt, ap) <= 0)
src = NULL;
if ((ret = vasprintf(&src, fmt, ap)) <= 0)
goto fail;
sz = strlen(src);
if ((dst = malloc(sz)) == NULL)
if ((dst = malloc(sz)) == NULL) {
free(src);
goto fail;
}
if (maxsz > INT_MAX)
maxsz = INT_MAX;
@ -191,12 +193,15 @@ vasnmprintf(char **str, size_t maxsz, int *wp, const char *fmt, va_list ap)
return ret;
fail:
free(src);
free(dst);
*str = NULL;
if (wp != NULL)
*wp = 0;
return -1;
if (ret == 0) {
*str = src;
return 0;
} else {
*str = NULL;
return -1;
}
}
int
@ -209,8 +214,11 @@ snmprintf(char *str, size_t sz, int *wp, const char *fmt, ...)
va_start(ap, fmt);
ret = vasnmprintf(&cp, sz, wp, fmt, ap);
va_end(ap);
(void)strlcpy(str, cp, sz);
free(cp);
if (cp != NULL) {
(void)strlcpy(str, cp, sz);
free(cp);
} else
*str = '\0';
return ret;
}