Handle vsnprintf corner cases.

The function vsnprintf returns a negative value on error, e.g. on
an invalid format. It's best to return NULL in such a case.

Also avoid a signed integer overflow if vsnprintf returns INT_MAX.
This is undefined behaviour in C and has to be avoided.

A negative value is returned with a call like:
json_sprintf("%111111111111111s", "", "");

INT_MAX is returned with a call like:
json_sprintf("%647s%2147483000s", "", "");
This commit is contained in:
Tobias Stoeckmann 2020-05-23 12:34:40 +02:00
parent e9ebfa7e77
commit 38b001edbd

View File

@ -797,16 +797,18 @@ json_t *json_vsprintf(const char *fmt, va_list ap) {
va_copy(aq, ap); va_copy(aq, ap);
length = vsnprintf(NULL, 0, fmt, ap); length = vsnprintf(NULL, 0, fmt, ap);
if (length < 0)
goto out;
if (length == 0) { if (length == 0) {
json = json_string(""); json = json_string("");
goto out; goto out;
} }
buf = jsonp_malloc(length + 1); buf = jsonp_malloc((size_t)length + 1);
if (!buf) if (!buf)
goto out; goto out;
vsnprintf(buf, length + 1, fmt, aq); vsnprintf(buf, (size_t)length + 1, fmt, aq);
if (!utf8_check_string(buf, length)) { if (!utf8_check_string(buf, length)) {
jsonp_free(buf); jsonp_free(buf);
goto out; goto out;