summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS6
-rw-r--r--ext/fileinfo/libmagic.patch68
-rw-r--r--ext/spl/spl_array.c9
-rw-r--r--ext/spl/spl_directory.c2
-rw-r--r--ext/spl/spl_iterators.c2
-rw-r--r--ext/spl/tests/bug67359.phpt28
-rw-r--r--ext/spl/tests/bug67360.phpt34
-rw-r--r--ext/standard/formatted_print.c6
-rw-r--r--ext/standard/tests/strings/bug67249.phpt8
9 files changed, 154 insertions, 9 deletions
diff --git a/NEWS b/NEWS
index 080e9c65b6..a266968271 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,9 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? 2014, PHP 5.6.0 Beta 4
+- Core:
+ . Fixed bug #67249 (printf out-of-bounds read). (Stas)
+
- Date:
. Fixed bug #67308 (Serialize of DateTime truncates fractions of second).
(Adam)
@@ -11,6 +14,9 @@ PHP NEWS
. Fixed bug #67328 (fileinfo: fileinfo: numerous file_printf calls resulting in
performance degradation).
+- SPL:
+ . Fixed bug #67359 (Segfault in recursiveDirectoryIterator). (Laruence)
+
15 May 2014, PHP 5.6.0 Beta 3
- Core:
diff --git a/ext/fileinfo/libmagic.patch b/ext/fileinfo/libmagic.patch
index 662537bf7f..bb9a0dafae 100644
--- a/ext/fileinfo/libmagic.patch
+++ b/ext/fileinfo/libmagic.patch
@@ -822,7 +822,7 @@ diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c
}
diff -u libmagic.orig/cdf.c libmagic/cdf.c
--- libmagic.orig/cdf.c Tue Feb 26 17:20:42 2013
-+++ libmagic/cdf.c Fri Feb 21 00:21:27 2014
++++ libmagic/cdf.c Tue May 27 22:28:51 2014
@@ -43,7 +43,17 @@
#include <err.h>
#endif
@@ -853,7 +853,63 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c
return -1;
return (ssize_t)len;
-@@ -1132,7 +1145,7 @@
+@@ -810,6 +823,10 @@
+ i, inp[i].pi_id, inp[i].pi_type, q - p, offs));
+ if (inp[i].pi_type & CDF_VECTOR) {
+ nelements = CDF_GETUINT32(q, 1);
++ if (nelements == 0) {
++ DPRINTF(("CDF_VECTOR with nelements == 0\n"));
++ goto out;
++ }
+ o = 2;
+ } else {
+ nelements = 1;
+@@ -884,7 +901,9 @@
+ }
+ DPRINTF(("nelements = %" SIZE_T_FORMAT "u\n",
+ nelements));
+- for (j = 0; j < nelements; j++, i++) {
++ for (j = 0; j < nelements && i < sh.sh_properties;
++ j++, i++)
++ {
+ uint32_t l = CDF_GETUINT32(q, o);
+ inp[i].pi_str.s_len = l;
+ inp[i].pi_str.s_buf = (const char *)
+@@ -929,7 +948,7 @@
+ cdf_unpack_summary_info(const cdf_stream_t *sst, const cdf_header_t *h,
+ cdf_summary_info_header_t *ssi, cdf_property_info_t **info, size_t *count)
+ {
+- size_t i, maxcount;
++ size_t maxcount;
+ const cdf_summary_info_header_t *si =
+ CAST(const cdf_summary_info_header_t *, sst->sst_tab);
+ const cdf_section_declaration_t *sd =
+@@ -944,21 +963,13 @@
+ ssi->si_os = CDF_TOLE2(si->si_os);
+ ssi->si_class = si->si_class;
+ cdf_swap_class(&ssi->si_class);
+- ssi->si_count = CDF_TOLE2(si->si_count);
++ ssi->si_count = CDF_TOLE4(si->si_count);
+ *count = 0;
+ maxcount = 0;
+ *info = NULL;
+- for (i = 0; i < CDF_TOLE4(si->si_count); i++) {
+- if (i >= CDF_LOOP_LIMIT) {
+- DPRINTF(("Unpack summary info loop limit"));
+- errno = EFTYPE;
+- return -1;
+- }
+- if (cdf_read_property_info(sst, h, CDF_TOLE4(sd->sd_offset),
+- info, count, &maxcount) == -1) {
++ if (cdf_read_property_info(sst, h, CDF_TOLE4(sd->sd_offset), info,
++ count, &maxcount) == -1)
+ return -1;
+- }
+- }
+ return 0;
+ }
+
+@@ -1132,7 +1143,7 @@
cdf_directory_t *d;
char name[__arraycount(d->d_name)];
cdf_stream_t scn;
@@ -862,7 +918,7 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c
static const char *types[] = { "empty", "user storage",
"user stream", "lockbytes", "property", "root storage" };
-@@ -1185,7 +1198,7 @@
+@@ -1185,7 +1196,7 @@
cdf_dump_property_info(const cdf_property_info_t *info, size_t count)
{
cdf_timestamp_t tp;
@@ -871,7 +927,7 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c
char buf[64];
size_t i, j;
-@@ -1229,7 +1242,11 @@
+@@ -1229,7 +1240,11 @@
break;
case CDF_FILETIME:
tp = info[i].pi_tp;
@@ -885,7 +941,7 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c
} else {
diff -u libmagic.orig/cdf.h libmagic/cdf.h
--- libmagic.orig/cdf.h Thu Jun 21 00:19:55 2012
-+++ libmagic/cdf.h Fri Feb 21 00:21:27 2014
++++ libmagic/cdf.h Tue May 27 22:28:51 2014
@@ -35,10 +35,12 @@
#ifndef _H_CDF_
#define _H_CDF_
@@ -2543,7 +2599,7 @@ diff -u libmagic.orig/print.c libmagic/print.c
}
diff -u libmagic.orig/readcdf.c libmagic/readcdf.c
--- libmagic.orig/readcdf.c Tue Jan 7 04:13:42 2014
-+++ libmagic/readcdf.c Thu Apr 24 20:07:51 2014
++++ libmagic/readcdf.c Tue May 27 22:28:51 2014
@@ -30,7 +30,11 @@
#endif
diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c
index 01ee1e2d01..899516eca8 100644
--- a/ext/spl/spl_array.c
+++ b/ext/spl/spl_array.c
@@ -931,7 +931,14 @@ static int spl_array_skip_protected(spl_array_object *intern, HashTable *aht TSR
if (Z_TYPE_P(intern->array) == IS_OBJECT) {
do {
if (zend_hash_get_current_key_ex(aht, &string_key, &string_length, &num_key, 0, &intern->pos) == HASH_KEY_IS_STRING) {
- if (!string_length || string_key[0]) {
+ /* zend_hash_get_current_key_ex() should never set
+ * string_length to 0 when returning HASH_KEY_IS_STRING, but we
+ * may as well be defensive and consider that successful.
+ * Beyond that, we're looking for protected keys (which will
+ * have a null byte at string_key[0]), but want to avoid
+ * skipping completely empty keys (which will also have the
+ * null byte, but a string_length of 1). */
+ if (!string_length || string_key[0] || string_length == 1) {
return SUCCESS;
}
} else {
diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c
index 1033d48aa7..151da4b724 100644
--- a/ext/spl/spl_directory.c
+++ b/ext/spl/spl_directory.c
@@ -830,6 +830,7 @@ SPL_METHOD(DirectoryIterator, seek)
zend_call_method_with_0_params(&this_ptr, Z_OBJCE_P(getThis()), &intern->u.dir.func_rewind, "rewind", &retval);
if (retval) {
zval_ptr_dtor(&retval);
+ retval = NULL;
}
}
@@ -839,6 +840,7 @@ SPL_METHOD(DirectoryIterator, seek)
if (retval) {
valid = zend_is_true(retval);
zval_ptr_dtor(&retval);
+ retval = NULL;
}
if (!valid) {
break;
diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c
index 4be7631205..9437ac7707 100644
--- a/ext/spl/spl_iterators.c
+++ b/ext/spl/spl_iterators.c
@@ -848,6 +848,8 @@ static union _zend_function *spl_recursive_it_get_method(zval **object_ptr, char
*object_ptr = zobj;
function_handler = Z_OBJ_HT_P(*object_ptr)->get_method(object_ptr, method, method_len, key TSRMLS_CC);
}
+ } else {
+ *object_ptr = zobj;
}
}
return function_handler;
diff --git a/ext/spl/tests/bug67359.phpt b/ext/spl/tests/bug67359.phpt
new file mode 100644
index 0000000000..e2e61133f3
--- /dev/null
+++ b/ext/spl/tests/bug67359.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Bug #67359 (Segfault in recursiveDirectoryIterator)
+--FILE--
+<?php
+try
+{
+ $rdi = new recursiveDirectoryIterator(dirname(__FILE__), FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS);
+ $it = new recursiveIteratorIterator( $rdi );
+ $it->seek(1);
+ while( $it->valid())
+ {
+ if( $it->isFile() )
+ {
+ $it->current();
+ }
+
+ $it->next();
+ }
+
+ $it->current();
+}
+catch(Exception $e)
+{
+}
+echo "okey"
+?>
+--EXPECTF--
+okey
diff --git a/ext/spl/tests/bug67360.phpt b/ext/spl/tests/bug67360.phpt
new file mode 100644
index 0000000000..552c02ad74
--- /dev/null
+++ b/ext/spl/tests/bug67360.phpt
@@ -0,0 +1,34 @@
+--TEST--
+Bug #67360 (Missing element after ArrayObject::getIterator)
+--FILE--
+<?php
+
+$array = array('' => 1, 1 => 2, 3 => 4);
+$ArrayObject = new ArrayObject($array);
+var_dump($ArrayObject);
+$Iterator = $ArrayObject->getIterator();
+var_dump(count($Iterator) === count($array));
+var_dump(iterator_to_array($Iterator));
+
+?>
+--EXPECTF--
+object(ArrayObject)#%d (1) {
+ ["storage":"ArrayObject":private]=>
+ array(3) {
+ [""]=>
+ int(1)
+ [1]=>
+ int(2)
+ [3]=>
+ int(4)
+ }
+}
+bool(true)
+array(3) {
+ [""]=>
+ int(1)
+ [1]=>
+ int(2)
+ [3]=>
+ int(4)
+}
diff --git a/ext/standard/formatted_print.c b/ext/standard/formatted_print.c
index 44ee9b61f8..727de705ff 100644
--- a/ext/standard/formatted_print.c
+++ b/ext/standard/formatted_print.c
@@ -374,6 +374,7 @@ php_formatted_print(int ht, php_size_t *len, int use_array, int format_offset TS
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;
@@ -412,11 +413,12 @@ php_formatted_print(int ht, php_size_t *len, int use_array, int format_offset TS
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_STRSIZE_PP(args[format_offset])) {
+ while (inpos<format_len) {
int expprec = 0, multiuse = 0;
zval *tmp;
@@ -471,7 +473,7 @@ php_formatted_print(int ht, php_size_t *len, int use_array, int format_offset TS
/* 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 0000000000..6ea75289e6
--- /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) ""