summaryrefslogtreecommitdiff
path: root/main/spprintf.c
diff options
context:
space:
mode:
authorNikita Popov <nikic@php.net>2015-07-16 23:17:29 +0200
committerNikita Popov <nikic@php.net>2015-07-17 16:53:06 +0200
commit75dc4486b2b95989f62717da4feca8ebe4bbb528 (patch)
treeb7a995001e733ba2c9947b891ba1d19d180cb0ff /main/spprintf.c
parentdaba578dbe056260c748f01739d0dd5cfbc5aecd (diff)
downloadphp-git-75dc4486b2b95989f62717da4feca8ebe4bbb528.tar.gz
Make s(tr)pprintf infallible
spprintf now always creates a buffer and strpprintf always returns a zend_string. Previously, if the result of the format happened to be empty, the spprintf buffer would be set to NULL and strpprintf would return NULL.
Diffstat (limited to 'main/spprintf.c')
-rw-r--r--main/spprintf.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/main/spprintf.c b/main/spprintf.c
index 759372b370..4594fb7605 100644
--- a/main/spprintf.c
+++ b/main/spprintf.c
@@ -838,7 +838,6 @@ skip_output:
PHPAPI size_t vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap) /* {{{ */
{
smart_string buf = {0};
- size_t result;
/* since there are places where (v)spprintf called without checking for null,
a bit of defensive coding here */
@@ -855,13 +854,11 @@ PHPAPI size_t vspprintf(char **pbuf, size_t max_len, const char *format, va_list
if (buf.c) {
*pbuf = buf.c;
- result = buf.len;
+ return buf.len;
} else {
- *pbuf = NULL;
- result = 0;
+ *pbuf = estrndup("", 0);
+ return 0;
}
-
- return result;
}
/* }}} */
@@ -883,11 +880,15 @@ PHPAPI zend_string *vstrpprintf(size_t max_len, const char *format, va_list ap)
xbuf_format_converter(&buf, 0, format, ap);
- if (max_len && buf.s && ZSTR_LEN(buf.s) > max_len) {
+ if (!buf.s) {
+ return ZSTR_EMPTY_ALLOC();
+ }
+
+ if (max_len && ZSTR_LEN(buf.s) > max_len) {
ZSTR_LEN(buf.s) = max_len;
}
- smart_str_0(&buf);
+ smart_str_0(&buf);
return buf.s;
}
/* }}} */