php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #67249
Patch fix-printf revision 2014-05-12 01:47 UTC by stas@php.net

Patch fix-printf for *General Issues Bug #67249

Patch version 2014-05-12 01:47 UTC

Return to Bug #67249 | Download this patch
Patch Revisions:

Developer: stas@php.net

diff --git a/NEWS b/NEWS
index 03f8b87..ea22ddc 100644
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,7 @@ PHP                                                                        NEWS
   . Fixed bug #67245 (usage of memcpy() with overlapping src and dst in
     zend_exceptions.c). (Bob)
   . Fixed bug #67247 (spl_fixedarray_resize integer overflow). (Stas)
+  . Fixed bug #67249 (printf out-of-bounds read). (Stas)
 
 - Date:
   . Fixed bug #67118 (DateTime constructor crash with invalid data). (Anatol)
diff --git a/ext/standard/formatted_print.c b/ext/standard/formatted_print.c
index 3cd5839..2592b16 100644
--- a/ext/standard/formatted_print.c
+++ b/ext/standard/formatted_print.c
@@ -376,6 +376,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;
@@ -414,11 +415,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;
 
@@ -473,7 +475,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
index 0000000..6ea7528
--- /dev/null
+++ b/ext/standard/tests/strings/bug67249.phpt
@@ -0,0 +1,8 @@
+--TEST--
+Bug #67249 (printf out-of-bounds read)
+--FILE--
+<?php
+var_dump(sprintf("%'", "foo"));
+?>
+--EXPECT--
+string(0) ""
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Sun Sep 19 06:03:36 2021 UTC