]> granicus.if.org Git - php/commitdiff
Fix bug #67249: printf out-of-bounds read
authorStanislav Malyshev <stas@php.net>
Mon, 12 May 2014 01:44:14 +0000 (18:44 -0700)
committerStanislav Malyshev <stas@php.net>
Fri, 13 Jun 2014 23:43:56 +0000 (16:43 -0700)
ext/standard/formatted_print.c
ext/standard/tests/strings/bug67249.phpt [new file with mode: 0644]

index d69b79bf3d25c1717fded9c4a47200a02142cefd..383ca1a5bb39ec35d57582fe6c2be424ca620887 100644 (file)
@@ -379,6 +379,7 @@ php_formatted_print(int ht, int *len, int use_array, int format_offset TSRMLS_DC
        int alignment, currarg, adjusting, argnum, width, precision;
        char *format, *result, padding;
        int always_sign;
+       int format_len;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argc) == FAILURE) {
                return NULL;
@@ -417,11 +418,12 @@ php_formatted_print(int ht, int *len, int use_array, int format_offset TSRMLS_DC
        
        convert_to_string_ex(args[format_offset]);
        format = Z_STRVAL_PP(args[format_offset]);
+       format_len = Z_STRLEN_PP(args[format_offset]);
        result = emalloc(size);
 
        currarg = 1;
 
-       while (inpos<Z_STRLEN_PP(args[format_offset])) {
+       while (inpos<format_len) {
                int expprec = 0, multiuse = 0;
                zval *tmp;
 
@@ -476,7 +478,7 @@ php_formatted_print(int ht, int *len, int use_array, int format_offset TSRMLS_DC
                                                /* space padding, the default */
                                        } else if (format[inpos] == '+') {
                                                always_sign = 1;
-                                       } else if (format[inpos] == '\'') {
+                                       } else if (format[inpos] == '\'' && inpos+1<format_len) {
                                                padding = format[++inpos];
                                        } else {
                                                PRINTF_DEBUG(("sprintf: end of modifiers\n"));
diff --git a/ext/standard/tests/strings/bug67249.phpt b/ext/standard/tests/strings/bug67249.phpt
new file mode 100644 (file)
index 0000000..6ea7528
--- /dev/null
@@ -0,0 +1,8 @@
+--TEST--
+Bug #67249 (printf out-of-bounds read)
+--FILE--
+<?php
+var_dump(sprintf("%'", "foo"));
+?>
+--EXPECT--
+string(0) ""