summaryrefslogtreecommitdiff
path: root/utf8.c
diff options
context:
space:
mode:
authorschwarze@openbsd.org <schwarze@openbsd.org>2016-05-30 12:05:56 +0000
committerDarren Tucker <dtucker@zip.com.au>2016-06-06 11:27:38 +1000
commitac284a355f8065eaef2a16f446f3c44cdd17371d (patch)
treede00e4236e35e385771974e7daedec02a4064f0f /utf8.c
parent0e059cdf5fd86297546c63fa8607c24059118832 (diff)
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
Diffstat (limited to 'utf8.c')
-rw-r--r--utf8.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/utf8.c b/utf8.c
index d6089bdec..caf789cee 100644
--- a/utf8.c
+++ b/utf8.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: utf8.c,v 1.1 2016/05/25 23:48:45 schwarze Exp $ */ 1/* $OpenBSD: utf8.c,v 1.2 2016/05/30 12:05:56 schwarze Exp $ */
2/* 2/*
3 * Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org> 3 * Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
4 * 4 *
@@ -81,13 +81,15 @@ vasnmprintf(char **str, size_t maxsz, int *wp, const char *fmt, va_list ap)
81 int width; /* Display width of the character wc. */ 81 int width; /* Display width of the character wc. */
82 int total_width, max_width, print; 82 int total_width, max_width, print;
83 83
84 src = dst = NULL; 84 src = NULL;
85 if (vasprintf(&src, fmt, ap) <= 0) 85 if ((ret = vasprintf(&src, fmt, ap)) <= 0)
86 goto fail; 86 goto fail;
87 87
88 sz = strlen(src); 88 sz = strlen(src);
89 if ((dst = malloc(sz)) == NULL) 89 if ((dst = malloc(sz)) == NULL) {
90 free(src);
90 goto fail; 91 goto fail;
92 }
91 93
92 if (maxsz > INT_MAX) 94 if (maxsz > INT_MAX)
93 maxsz = INT_MAX; 95 maxsz = INT_MAX;
@@ -191,12 +193,15 @@ vasnmprintf(char **str, size_t maxsz, int *wp, const char *fmt, va_list ap)
191 return ret; 193 return ret;
192 194
193fail: 195fail:
194 free(src);
195 free(dst);
196 *str = NULL;
197 if (wp != NULL) 196 if (wp != NULL)
198 *wp = 0; 197 *wp = 0;
199 return -1; 198 if (ret == 0) {
199 *str = src;
200 return 0;
201 } else {
202 *str = NULL;
203 return -1;
204 }
200} 205}
201 206
202int 207int
@@ -209,8 +214,11 @@ snmprintf(char *str, size_t sz, int *wp, const char *fmt, ...)
209 va_start(ap, fmt); 214 va_start(ap, fmt);
210 ret = vasnmprintf(&cp, sz, wp, fmt, ap); 215 ret = vasnmprintf(&cp, sz, wp, fmt, ap);
211 va_end(ap); 216 va_end(ap);
212 (void)strlcpy(str, cp, sz); 217 if (cp != NULL) {
213 free(cp); 218 (void)strlcpy(str, cp, sz);
219 free(cp);
220 } else
221 *str = '\0';
214 return ret; 222 return ret;
215} 223}
216 224