Merge branch 'PHP-5.6'

* PHP-5.6: (21 commits)
  fix unit tests
  update NEWS
  add NEWS for fixes
  Improve fix for #70172
  Fix bug #70312 - HAVAL gives wrong hashes in specific cases
  fix test
  add test
  Fix bug #70366 - use-after-free vulnerability in unserialize() with SplDoublyLinkedList
  Fix bug #70365 - use-after-free vulnerability in unserialize() with SplObjectStorage
  Fix bug #70172 - Use After Free Vulnerability in unserialize()
  Fix bug #70388 - SOAP serialize_function_call() type confusion
  Fixed bug #70350: ZipArchive::extractTo allows for directory traversal when creating directories
  Improve fix for #70385
  Fix bug #70345 (Multiple vulnerabilities related to PCRE functions)
  Fix bug #70385 (Buffer over-read in exif_read_data with TIFF IFD tag byte value of 32 bytes)
  Fix bug #70219 (Use after free vulnerability in session deserializer)
  Fix bug ##70284 (Use after free vulnerability in unserialize() with GMP)
  Fix for bug #69782
  Add CVE IDs asigned (post release) to PHP 5.4.43
  Add CVE IDs asigned to #69085 (PHP 5.4.39)
  ...

Conflicts:
	ext/exif/exif.c
	ext/gmp/gmp.c
	ext/pcre/php_pcre.c
	ext/session/session.c
	ext/session/tests/session_decode_variation3.phpt
	ext/soap/soap.c
	ext/spl/spl_observer.c
	ext/standard/var.c
	ext/standard/var_unserializer.c
	ext/standard/var_unserializer.re
	ext/xsl/xsltprocessor.c
This commit is contained in:
Stanislav Malyshev 2015-09-01 12:40:10 -07:00
commit 9b1a224d4e
28 changed files with 749 additions and 348 deletions

View File

@ -1243,26 +1243,35 @@ ZEND_API void object_properties_load(zend_object *object, HashTable *properties)
{
zval *prop, tmp;
zend_string *key;
zend_long h;
zend_property_info *property_info;
ZEND_HASH_FOREACH_STR_KEY_VAL(properties, key, prop) {
property_info = zend_get_property_info(object->ce, key, 1);
if (property_info != ZEND_WRONG_PROPERTY_INFO &&
property_info &&
(property_info->flags & ZEND_ACC_STATIC) == 0) {
zval *slot = OBJ_PROP(object, property_info->offset);
zval_ptr_dtor(slot);
ZVAL_COPY_VALUE(slot, prop);
zval_add_ref(slot);
if (object->properties) {
ZVAL_INDIRECT(&tmp, slot);
zend_hash_update(object->properties, key, &tmp);
ZEND_HASH_FOREACH_KEY_VAL(properties, h, key, prop) {
if(key) {
property_info = zend_get_property_info(object->ce, key, 1);
if (property_info != ZEND_WRONG_PROPERTY_INFO &&
property_info &&
(property_info->flags & ZEND_ACC_STATIC) == 0) {
zval *slot = OBJ_PROP(object, property_info->offset);
zval_ptr_dtor(slot);
ZVAL_COPY_VALUE(slot, prop);
zval_add_ref(slot);
if (object->properties) {
ZVAL_INDIRECT(&tmp, slot);
zend_hash_update(object->properties, key, &tmp);
}
} else {
if (!object->properties) {
rebuild_object_properties(object);
}
prop = zend_hash_update(object->properties, key, prop);
zval_add_ref(prop);
}
} else {
if (!object->properties) {
rebuild_object_properties(object);
}
prop = zend_hash_update(object->properties, key, prop);
prop = zend_hash_index_update(object->properties, h, prop);
zval_add_ref(prop);
}
} ZEND_HASH_FOREACH_END();

View File

@ -2945,13 +2945,13 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
if (length<byte_count-1) {
/* When there are any characters after the first NUL */
ImageInfo->CopyrightPhotographer = estrdup(value_ptr);
ImageInfo->CopyrightEditor = estrdup(value_ptr+length+1);
ImageInfo->CopyrightEditor = estrndup(value_ptr+length+1, byte_count-length-1);
spprintf(&ImageInfo->Copyright, 0, "%s, %s", value_ptr, value_ptr+length+1);
/* format = TAG_FMT_UNDEFINED; this musn't be ASCII */
/* but we are not supposed to change this */
/* keep in mind that image_info does not store editor value */
} else {
ImageInfo->Copyright = estrdup(value_ptr);
ImageInfo->Copyright = estrndup(value_ptr, byte_count);
}
}
break;
@ -3042,10 +3042,10 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
break;
case TAG_MAKE:
ImageInfo->make = estrdup(value_ptr);
ImageInfo->make = estrndup(value_ptr, byte_count);
break;
case TAG_MODEL:
ImageInfo->model = estrdup(value_ptr);
ImageInfo->model = estrndup(value_ptr, byte_count);
break;
case TAG_MAKER_NOTE:

View File

@ -585,44 +585,42 @@ static int gmp_unserialize(zval *object, zend_class_entry *ce, const unsigned ch
{
mpz_ptr gmpnum;
const unsigned char *p, *max;
zval zv;
zval *zv;
int retval = FAILURE;
php_unserialize_data_t unserialize_data = (php_unserialize_data_t) data;
ZVAL_UNDEF(&zv);
PHP_VAR_UNSERIALIZE_INIT(unserialize_data);
gmp_create(object, &gmpnum);
p = buf;
max = buf + buf_len;
if (!php_var_unserialize(&zv, &p, max, &unserialize_data)
|| Z_TYPE(zv) != IS_STRING
|| convert_to_gmp(gmpnum, &zv, 10) == FAILURE
zv = var_tmp_var(&unserialize_data);
if (!php_var_unserialize(zv, &p, max, &unserialize_data)
|| Z_TYPE_P(zv) != IS_STRING
|| convert_to_gmp(gmpnum, zv, 10) == FAILURE
) {
zend_throw_exception(NULL, "Could not unserialize number", 0);
goto exit;
}
zval_dtor(&zv);
ZVAL_UNDEF(&zv);
if (!php_var_unserialize(&zv, &p, max, &unserialize_data)
|| Z_TYPE(zv) != IS_ARRAY
zv = var_tmp_var(&unserialize_data);
if (!php_var_unserialize(zv, &p, max, &unserialize_data)
|| Z_TYPE_P(zv) != IS_ARRAY
) {
zend_throw_exception(NULL, "Could not unserialize properties", 0);
goto exit;
}
if (zend_hash_num_elements(Z_ARRVAL(zv)) != 0) {
if (zend_hash_num_elements(Z_ARRVAL_P(zv)) != 0) {
zend_hash_copy(
zend_std_get_properties(object), Z_ARRVAL(zv),
zend_std_get_properties(object), Z_ARRVAL_P(zv),
(copy_ctor_func_t) zval_add_ref
);
}
retval = SUCCESS;
exit:
zval_dtor(&zv);
PHP_VAR_UNSERIALIZE_DESTROY(unserialize_data);
return retval;
}

View File

@ -0,0 +1,50 @@
--TEST--
Bug #70284 (Use after free vulnerability in unserialize() with GMP)
--SKIPIF--
<?php if (!extension_loaded("gmp")) print "skip"; ?>
--FILE--
<?php
$inner = 'r:2;a:1:{i:0;a:1:{i:0;r:4;}}';
$exploit = 'a:2:{i:0;s:1:"1";i:1;C:3:"GMP":'.strlen($inner).':{'.$inner.'}}';
$data = unserialize($exploit);
$fakezval = ptr2str(1122334455);
$fakezval .= ptr2str(0);
$fakezval .= "\x00\x00\x00\x00";
$fakezval .= "\x01";
$fakezval .= "\x00";
$fakezval .= "\x00\x00";
for ($i = 0; $i < 5; $i++) {
$v[$i] = $fakezval.$i;
}
var_dump($data);
function ptr2str($ptr)
{
$out = '';
for ($i = 0; $i < 8; $i++) {
$out .= chr($ptr & 0xff);
$ptr >>= 8;
}
return $out;
}
?>
--EXPECTF--
array(2) {
[0]=>
string(1) "1"
[1]=>
object(GMP)#%d (2) {
[0]=>
array(1) {
[0]=>
string(1) "1"
}
["num"]=>
string(1) "1"
}
}

View File

@ -336,7 +336,7 @@ PHP_HASH_API void PHP_HAVAL128Final(unsigned char *digest, PHP_HAVAL_CTX * conte
/* Pad out to 118 mod 128.
*/
index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
index = (unsigned int) ((context->count[0] >> 3) & 0x7f);
padLen = (index < 118) ? (118 - index) : (246 - index);
PHP_HAVALUpdate(context, PADDING, padLen);
@ -390,7 +390,7 @@ PHP_HASH_API void PHP_HAVAL160Final(unsigned char *digest, PHP_HAVAL_CTX * conte
/* Pad out to 118 mod 128.
*/
index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
index = (unsigned int) ((context->count[0] >> 3) & 0x7f);
padLen = (index < 118) ? (118 - index) : (246 - index);
PHP_HAVALUpdate(context, PADDING, padLen);
@ -444,7 +444,7 @@ PHP_HASH_API void PHP_HAVAL192Final(unsigned char *digest, PHP_HAVAL_CTX * conte
/* Pad out to 118 mod 128.
*/
index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
index = (unsigned int) ((context->count[0] >> 3) & 0x7f);
padLen = (index < 118) ? (118 - index) : (246 - index);
PHP_HAVALUpdate(context, PADDING, padLen);
@ -484,7 +484,7 @@ PHP_HASH_API void PHP_HAVAL224Final(unsigned char *digest, PHP_HAVAL_CTX * conte
/* Pad out to 118 mod 128.
*/
index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
index = (unsigned int) ((context->count[0] >> 3) & 0x7f);
padLen = (index < 118) ? (118 - index) : (246 - index);
PHP_HAVALUpdate(context, PADDING, padLen);
@ -525,7 +525,7 @@ PHP_HASH_API void PHP_HAVAL256Final(unsigned char *digest, PHP_HAVAL_CTX * conte
/* Pad out to 118 mod 128.
*/
index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
index = (unsigned int) ((context->count[0] >> 3) & 0x7f);
padLen = (index < 118) ? (118 - index) : (246 - index);
PHP_HAVALUpdate(context, PADDING, padLen);

View File

@ -0,0 +1,18 @@
--TEST--
Bug #70312 HAVAL gives wrong hashes in specific cases
--SKIPIF--
<?php if(!extension_loaded("hash")) print "skip"; ?>
--FILE--
<?php
var_dump(hash('haval128,5', '1234567890123456789012345678901234567890123456789012345678901234'));
var_dump(hash('haval160,5', '1234567890123456789012345678901234567890123456789012345678901234'));
var_dump(hash('haval192,5', '1234567890123456789012345678901234567890123456789012345678901234'));
var_dump(hash('haval224,5', '1234567890123456789012345678901234567890123456789012345678901234'));
var_dump(hash('haval256,5', '1234567890123456789012345678901234567890123456789012345678901234'));
?>
--EXPECTF--
string(32) "f3f0d23819b87228b4b70ee350afaa9d"
string(40) "aded6485e137f11d7292212ba3fa961714df0564"
string(48) "e53da2b16269fe732e9a898a96707a9f28404d7333b02286"
string(56) "c574fb307f0817b514b9bb2e7c4bfaffb7ad667aca3c8b523fefcf10"
string(64) "fb73c19300b14d5cb393d929bf005e6c2d459a4c9c009e9813af1d2d3637ee8f"

View File

@ -64,7 +64,7 @@ unlink($file);
adler32: ff87222e
crc32: 61664d33
gost: d9e65f0c0c2ef944e4f8a01f4a46365c4f33a2853756878182a7f03e1490a4cd
haval128,3: 8bb81269aca8b7f87829020d76a4e841
haval128,3: c25962b13383c3ed9f13817c8f2ae7d6
md2: 70f791c0d8fa9edd7d08e32fcba8c354
md4: a9d034b16bb290c57a645afd6f14cd3b
md5: 704bf818448f5bbb94061332d2c889aa

View File

@ -45,7 +45,7 @@ echo "sha256(raw): " . bin2hex(hash_hmac('sha256', $content, $key, TRUE)) . "\n"
adler32: 12c803f7
crc32: 96859101
gost: a4a3c80bdf3f8665bf07376a34dc9c1b11af7c813f4928f62e39f0c0dc564dad
haval128,3: 82cd0f4bd36729b5c80c33efa8c13ac5
haval128,3: 4d1318607f0406bd1b7bd50907772672
md2: 6d111dab563025e4cb5f4425c991fa12
md4: 10cdbfe843000c623f8b8da0d5d20b0b
md5: 2a632783e2812cf23de100d7d6a463ae

View File

@ -73,7 +73,7 @@ unlink($file);
adler32: 0f8c02f9
crc32: f2a60b9c
gost: 94c39a40d5db852a8dc3d24e37eebf2d53e3d711457c59cd02b614f792a9d918
haval128,3: e8fcff647f1a675acb429130fb94a17e
haval128,3: f1cea637451097d790354a86de3f54a3
md2: a685475e600314bb549ab4f33c3b27cb
md4: cbc6bff781f48f57378d3effa27553e4
md5: 8bddf39dd1c566c27acc7fa85ec36acf

View File

@ -758,7 +758,7 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subjec
/* If subpatterns array has been passed, fill it in with values. */
if (subpats != NULL) {
/* Try to get the list of substrings and display a warning if failed. */
if (pcre_get_substring_list(subject, offsets, count, &stringlist) < 0) {
if ((offsets[1] - offsets[0] < 0) || pcre_get_substring_list(subject, offsets, count, &stringlist) < 0) {
if (subpat_names) {
efree(subpat_names);
}
@ -1177,7 +1177,7 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *su
piece = subject + start_offset;
/* if (EXPECTED(count > 0 && (limit == -1 || limit > 0))) */
if (EXPECTED(count > 0 && limit)) {
if (EXPECTED(count > 0 && (offsets[1] - offsets[0] >= 0) && limit)) {
if (UNEXPECTED(replace_count)) {
++*replace_count;
}
@ -1799,7 +1799,7 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, char *subject, int subjec
}
/* If something matched */
if (count > 0) {
if (count > 0 && (offsets[1] - offsets[0] >= 0)) {
if (!no_empty || &subject[offsets[0]] != last_match) {
if (offset_capture) {

View File

@ -0,0 +1,24 @@
--TEST--
Bug #70345 (Multiple vulnerabilities related to PCRE functions)
--FILE--
<?php
$regex = '/(?=xyz\K)/';
$subject = "aaaaxyzaaaa";
$v = preg_split($regex, $subject);
print_r($v);
$regex = '/(a(?=xyz\K))/';
$subject = "aaaaxyzaaaa";
preg_match($regex, $subject, $matches);
var_dump($matches);
--EXPECTF--
Array
(
[0] => aaaaxyzaaaa
)
Warning: preg_match(): Get subpatterns list failed in %s on line %d
array(0) {
}

View File

@ -64,6 +64,7 @@ PHPAPI ZEND_DECLARE_MODULE_GLOBALS(ps)
static int php_session_rfc1867_callback(unsigned int event, void *event_data, void **extra);
static int (*php_session_rfc1867_orig_callback)(unsigned int event, void *event_data, void **extra);
static void php_session_track_init(void);
/* SessionHandler class */
zend_class_entry *php_session_class_entry;
@ -138,6 +139,7 @@ static inline void php_rshutdown_session_globals(void) /* {{{ */
static int php_session_destroy(void) /* {{{ */
{
int retval = SUCCESS;
zend_string *var_name;
if (PS(session_status) != php_session_active) {
php_error_docref(NULL, E_WARNING, "Trying to destroy uninitialized session");
@ -235,6 +237,7 @@ static int php_session_decode(zend_string *data) /* {{{ */
}
if (PS(serializer)->decode(ZSTR_VAL(data), ZSTR_LEN(data)) == FAILURE) {
php_session_destroy();
php_session_track_init();
php_error_docref(NULL, E_WARNING, "Failed to decode session object. Session has been destroyed");
return FAILURE;
}
@ -952,6 +955,8 @@ PS_SERIALIZER_DECODE_FUNC(php_binary) /* {{{ */
var_replace(&var_hash, &current, zv);
} else {
zval_ptr_dtor(&current);
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
return FAILURE;
}
}
PS_ADD_VARL(name);
@ -1042,6 +1047,8 @@ PS_SERIALIZER_DECODE_FUNC(php) /* {{{ */
var_replace(&var_hash, &current, zv);
} else {
zval_ptr_dtor(&current);
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
return FAILURE;
}
}
PS_ADD_VARL(name);
@ -2169,8 +2176,7 @@ static PHP_FUNCTION(session_decode)
}
if (php_session_decode(str) == FAILURE) {
/* FIXME: session_decode() should return FALSE */
/* RETURN_FALSE; */
RETURN_FALSE;
}
RETURN_TRUE;
}

View File

@ -18,6 +18,7 @@ $data = "foo|a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}guff|R:1;blah|R:1;";
var_dump(session_start());
for($index = 0; $index < strlen($data); $index++) {
if(session_status() != PHP_SESSION_ACTIVE) { session_start(); }
echo "\n-- Iteration $index --\n";
$encoded = substr($data, 0, $index);
var_dump(session_decode($encoded));
@ -53,213 +54,213 @@ array(0) {
}
-- Iteration 4 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 5 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 6 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 7 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 8 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 9 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 10 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 11 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 12 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 13 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 14 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 15 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 16 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 17 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 18 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 19 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 20 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 21 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 22 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 23 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 24 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 25 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 26 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 27 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 28 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 29 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 30 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 31 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 32 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 33 --
bool(true)
array(1) {
["foo"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 34 --
@ -333,67 +334,31 @@ array(1) {
}
-- Iteration 39 --
bool(true)
array(2) {
["foo"]=>
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
["guff"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 40 --
bool(true)
array(2) {
["foo"]=>
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
["guff"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 41 --
bool(true)
array(2) {
["foo"]=>
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
["guff"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 42 --
bool(true)
array(2) {
["foo"]=>
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
["guff"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 43 --
@ -512,104 +477,33 @@ array(2) {
}
-- Iteration 48 --
bool(true)
array(3) {
["foo"]=>
&array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
["guff"]=>
&array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
["blah"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 49 --
bool(true)
array(3) {
["foo"]=>
&array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
["guff"]=>
&array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
["blah"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 50 --
bool(true)
array(3) {
["foo"]=>
&array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
["guff"]=>
&array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
["blah"]=>
NULL
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
-- Iteration 51 --
bool(true)
array(3) {
["foo"]=>
&array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
["guff"]=>
&array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
["blah"]=>
NULL
}
bool(true)
Done
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/session_decode_error2.php on line %d
bool(false)
array(0) {
}
Warning: session_destroy(): Trying to destroy uninitialized session in %s/session_decode_error2.php on line %d
bool(false)
Done

View File

@ -1505,7 +1505,7 @@ static void _soap_server_exception(soapServicePtr service, sdlFunctionPtr functi
add_soap_fault_ex(&exception_object, this_ptr, "Server", "Internal Error", NULL, NULL);
}
soap_server_fault_ex(function, &exception_object, NULL);
}
}
}
/* }}} */
@ -2924,8 +2924,10 @@ PHP_METHOD(SoapClient, __call)
free_soap_headers = 1;
}
ZEND_HASH_FOREACH_VAL(default_headers, tmp) {
Z_ADDREF_P(tmp);
zend_hash_next_index_insert(soap_headers, tmp);
if(Z_TYPE_P(tmp) == IS_OBJECT) {
Z_ADDREF_P(tmp);
zend_hash_next_index_insert(soap_headers, tmp);
}
} ZEND_HASH_FOREACH_END();
} else {
soap_headers = Z_ARRVAL_P(tmp);
@ -4332,9 +4334,14 @@ static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function
zval* header;
ZEND_HASH_FOREACH_VAL(soap_headers, header) {
HashTable *ht = Z_OBJPROP_P(header);
HashTable *ht;
zval *name, *ns, *tmp;
if (Z_TYPE_P(header) != IS_OBJECT) {
continue;
}
ht = Z_OBJPROP_P(header);
if ((name = zend_hash_str_find(ht, "name", sizeof("name")-1)) != NULL &&
Z_TYPE_P(name) == IS_STRING &&
(ns = zend_hash_str_find(ht, "namespace", sizeof("namespace")-1)) != NULL &&

View File

@ -0,0 +1,17 @@
--TEST--
Bug #70388 (SOAP serialize_function_call() type confusion / RCE)
--SKIPIF--
<?php require_once('skipif.inc'); ?>
--FILE--
<?php
$dummy = unserialize('O:10:"SoapClient":3:{s:3:"uri";s:1:"X";s:8:"location";s:22:"http://localhost/a.xml";s:17:"__default_headers";a:1:{i:1;s:1337:"'.str_repeat("X", 1337).'";}}');
try {
var_dump($dummy->notexisting());
} catch(Exception $e) {
var_dump($e->getMessage());
var_dump(get_class($e));
}
?>
--EXPECTF--
string(%d) "%s"
string(9) "SoapFault"

View File

@ -1210,6 +1210,7 @@ SPL_METHOD(SplDoublyLinkedList, unserialize)
if (!php_var_unserialize(elem, &p, s + buf_len, &var_hash)) {
goto error;
}
var_push_dtor(&var_hash, elem);
spl_ptr_llist_push(intern->llist, elem);
}

View File

@ -0,0 +1,50 @@
--TEST--
SPL: Bug #70155 Use After Free Vulnerability in unserialize() with SPLArrayObject
--FILE--
<?php
$inner = 'x:i:0;O:12:"DateInterval":1:{s:1:"y";i:3;};m:a:1:{i:0;R:2;}';
$exploit = 'C:11:"ArrayObject":'.strlen($inner).':{'.$inner.'}';
$data = unserialize($exploit);
var_dump($data);
?>
===DONE===
--EXPECTF--
object(ArrayObject)#1 (2) {
[0]=>
int(0)
["storage":"ArrayObject":private]=>
object(DateInterval)#2 (15) {
["y"]=>
int(3)
["m"]=>
int(-1)
["d"]=>
int(-1)
["h"]=>
int(-1)
["i"]=>
int(-1)
["s"]=>
int(-1)
["weekday"]=>
int(-1)
["weekday_behavior"]=>
int(-1)
["first_last_day_of"]=>
int(-1)
["invert"]=>
int(0)
["days"]=>
int(-1)
["special_type"]=>
int(0)
["special_amount"]=>
int(-1)
["have_weekday_relative"]=>
int(0)
["have_special_relative"]=>
int(0)
}
}
===DONE===

View File

@ -0,0 +1,50 @@
--TEST--
SPL: Bug #70365 use-after-free vulnerability in unserialize() with SplObjectStorage
--FILE--
<?php
class obj {
var $ryat;
function __wakeup() {
$this->ryat = 1;
}
}
$fakezval = ptr2str(1122334455);
$fakezval .= ptr2str(0);
$fakezval .= "\x00\x00\x00\x00";
$fakezval .= "\x01";
$fakezval .= "\x00";
$fakezval .= "\x00\x00";
$inner = 'x:i:1;O:8:"stdClass":0:{},i:1;;m:a:0:{}';
$exploit = 'a:5:{i:0;i:1;i:1;C:16:"SplObjectStorage":'.strlen($inner).':{'.$inner.'}i:2;O:3:"obj":1:{s:4:"ryat";R:3;}i:3;R:6;i:4;s:'.strlen($fakezval).':"'.$fakezval.'";}';
$data = unserialize($exploit);
var_dump($data);
function ptr2str($ptr)
{
$out = '';
for ($i = 0; $i < 8; $i++) {
$out .= chr($ptr & 0xff);
$ptr >>= 8;
}
return $out;
}
--EXPECTF--
array(5) {
[0]=>
int(1)
[1]=>
&int(1)
[2]=>
object(obj)#%d (1) {
["ryat"]=>
&int(1)
}
[3]=>
int(1)
[4]=>
string(24) "%s"
}

View File

@ -0,0 +1,54 @@
--TEST--
SPL: Bug #70366 use-after-free vulnerability in unserialize() with SplDoublyLinkedList
--FILE--
<?php
class obj {
var $ryat;
function __wakeup() {
$this->ryat = 1;
}
}
$fakezval = ptr2str(1122334455);
$fakezval .= ptr2str(0);
$fakezval .= "\x00\x00\x00\x00";
$fakezval .= "\x01";
$fakezval .= "\x00";
$fakezval .= "\x00\x00";
$inner = 'i:1234;:i:1;';
$exploit = 'a:5:{i:0;i:1;i:1;C:19:"SplDoublyLinkedList":'.strlen($inner).':{'.$inner.'}i:2;O:3:"obj":1:{s:4:"ryat";R:3;}i:3;a:1:{i:0;R:5;}i:4;s:'.strlen($fakezval).':"'.$fakezval.'";}';
$data = unserialize($exploit);
var_dump($data);
function ptr2str($ptr)
{
$out = '';
for ($i = 0; $i < 8; $i++) {
$out .= chr($ptr & 0xff);
$ptr >>= 8;
}
return $out;
}
?>
--EXPECTF--
array(5) {
[0]=>
int(1)
[1]=>
&int(1)
[2]=>
object(obj)#%d (1) {
["ryat"]=>
&int(1)
}
[3]=>
array(1) {
[0]=>
int(1)
}
[4]=>
string(24) "%s"
}

View File

@ -0,0 +1,54 @@
--TEST--
Bug #70172 - Use After Free Vulnerability in unserialize()
--XFAIL--
Memory leak on debug build, needs fix.
--FILE--
<?php
class obj implements Serializable {
var $data;
function serialize() {
return serialize($this->data);
}
function unserialize($data) {
$this->data = unserialize($data);
}
}
$fakezval = ptr2str(1122334455);
$fakezval .= ptr2str(0);
$fakezval .= "\x00\x00\x00\x00";
$fakezval .= "\x01";
$fakezval .= "\x00";
$fakezval .= "\x00\x00";
$inner = 'r:2;';
$exploit = 'a:2:{i:0;i:1;i:1;C:3:"obj":'.strlen($inner).':{'.$inner.'}}';
$data = unserialize($exploit);
for ($i = 0; $i < 5; $i++) {
$v[$i] = $fakezval.$i;
}
var_dump($data);
function ptr2str($ptr)
{
$out = '';
for ($i = 0; $i < 8; $i++) {
$out .= chr($ptr & 0xff);
$ptr >>= 8;
}
return $out;
}
?>
--EXPECTF--
array(2) {
[0]=>
int(1)
[1]=>
object(obj)#%d (1) {
["data"]=>
int(1)
}
}

View File

@ -0,0 +1,68 @@
--TEST--
Bug #70172 - Use After Free Vulnerability in unserialize()
--FILE--
<?php
class obj implements Serializable {
var $data;
function serialize() {
return serialize($this->data);
}
function unserialize($data) {
$this->data = unserialize($data);
}
}
class obj2 {
var $ryat;
function __wakeup() {
$this->ryat = 1;
}
}
$fakezval = ptr2str(1122334455);
$fakezval .= ptr2str(0);
$fakezval .= "\x00\x00\x00\x00";
$fakezval .= "\x01";
$fakezval .= "\x00";
$fakezval .= "\x00\x00";
$inner = 'r:2;';
$exploit = 'a:2:{i:0;O:4:"obj2":1:{s:4:"ryat";C:3:"obj":'.strlen($inner).':{'.$inner.'}}i:1;a:1:{i:0;a:1:{i:0;R:4;}}}';
$data = unserialize($exploit);
for ($i = 0; $i < 5; $i++) {
$v[$i] = $fakezval.$i;
}
var_dump($data);
function ptr2str($ptr)
{
$out = '';
for ($i = 0; $i < 8; $i++) {
$out .= chr($ptr & 0xff);
$ptr >>= 8;
}
return $out;
}
?>
--EXPECTF--
array(2) {
[0]=>
object(obj2)#%d (1) {
["ryat"]=>
int(1)
}
[1]=>
array(1) {
[0]=>
array(1) {
[0]=>
&object(obj2)#%d (1) {
["ryat"]=>
int(1)
}
}
}
}

View File

@ -0,0 +1,40 @@
--TEST--
Bug #70219 Use after free vulnerability in session deserializer
--FILE--
<?php
class obj implements Serializable {
var $data;
function serialize() {
return serialize($this->data);
}
function unserialize($data) {
session_start();
session_decode($data);
}
}
$inner = 'ryat|a:1:{i:0;a:1:{i:1;';
$exploit = 'a:2:{i:0;C:3:"obj":'.strlen($inner).':{'.$inner.'}i:1;R:4;}';
$data = unserialize($exploit);
for ($i = 0; $i < 5; $i++) {
$v[$i] = 'hi'.$i;
}
var_dump($data);
?>
--EXPECTF--
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s on line %d
array(2) {
[0]=>
object(obj)#%d (1) {
["data"]=>
NULL
}
[1]=>
&array(1) {
["data"]=>
NULL
}
}

View File

@ -1045,6 +1045,7 @@ PHP_FUNCTION(unserialize)
php_unserialize_data_t var_hash;
zval *options = NULL, *classes = NULL;
HashTable *class_hash = NULL;
zval *old_rval = return_value;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|a", &buf, &buf_len, &options) == FAILURE) {
RETURN_FALSE;

View File

@ -1,4 +1,4 @@
/* Generated by re2c 0.13.5 */
/* Generated by re2c 0.13.7.5 */
#line 1 "ext/standard/var_unserializer.re"
/*
+----------------------------------------------------------------------+
@ -103,9 +103,15 @@ PHPAPI zval *var_tmp_var(php_unserialize_data_t *var_hashx)
#if 0
PHPAPI void var_push_dtor_no_addref(php_unserialize_data_t *var_hashx, zval *rval)
{
var_dtor_entries *var_hash = (*var_hashx)->last_dtor;
var_entries *var_hash;
if (!var_hashx || !*var_hashx) {
return;
}
var_hash = (*var_hashx)->last_dtor;
#if VAR_ENTRIES_DBG
fprintf(stderr, "var_push_dtor_no_addref(%ld): %d (%d)\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval), Z_REFCOUNT_PP(rval));
fprintf(stderr, "var_push_dtor_no_addref(%p, %ld): %d (%d)\n", *rval, var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval), Z_REFCOUNT_PP(rval));
#endif
if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) {
@ -183,6 +189,9 @@ PHPAPI void var_destroy(php_unserialize_data_t *var_hashx)
while (var_dtor_hash) {
for (i = 0; i < var_dtor_hash->used_slots; i++) {
#if VAR_ENTRIES_DBG
fprintf(stderr, "var_destroy dtor(%p, %ld)\n", var_dtor_hash->data[i], Z_REFCOUNT_P(var_dtor_hash->data[i]));
#endif
zval_ptr_dtor(&var_dtor_hash->data[i]);
}
next = var_dtor_hash->next;
@ -263,7 +272,7 @@ static inline int unserialize_allowed_class(zend_string *class_name, HashTable *
#define YYMARKER marker
#line 271 "ext/standard/var_unserializer.re"
#line 280 "ext/standard/var_unserializer.re"
@ -530,7 +539,7 @@ PHPAPI int php_var_unserialize_ex(UNSERIALIZE_PARAMETER)
start = cursor;
#line 534 "ext/standard/var_unserializer.c"
#line 543 "ext/standard/var_unserializer.c"
{
YYCTYPE yych;
static const unsigned char yybm[] = {
@ -590,9 +599,9 @@ yy2:
yych = *(YYMARKER = ++YYCURSOR);
if (yych == ':') goto yy95;
yy3:
#line 881 "ext/standard/var_unserializer.re"
#line 893 "ext/standard/var_unserializer.re"
{ return 0; }
#line 596 "ext/standard/var_unserializer.c"
#line 605 "ext/standard/var_unserializer.c"
yy4:
yych = *(YYMARKER = ++YYCURSOR);
if (yych == ':') goto yy89;
@ -635,13 +644,13 @@ yy13:
goto yy3;
yy14:
++YYCURSOR;
#line 875 "ext/standard/var_unserializer.re"
#line 887 "ext/standard/var_unserializer.re"
{
/* this is the case where we have less data than planned */
php_error_docref(NULL, E_NOTICE, "Unexpected end of serialized data");
return 0; /* not sure if it should be 0 or 1 here? */
}
#line 645 "ext/standard/var_unserializer.c"
#line 654 "ext/standard/var_unserializer.c"
yy16:
yych = *++YYCURSOR;
goto yy3;
@ -667,11 +676,12 @@ yy20:
if (yybm[0+yych] & 128) {
goto yy20;
}
if (yych != ':') goto yy18;
if (yych <= '/') goto yy18;
if (yych >= ';') goto yy18;
yych = *++YYCURSOR;
if (yych != '"') goto yy18;
++YYCURSOR;
#line 730 "ext/standard/var_unserializer.re"
#line 741 "ext/standard/var_unserializer.re"
{
size_t len, len2, len3, maxlen;
zend_long elements;
@ -686,6 +696,7 @@ yy20:
zval retval;
zval args[1];
if (!var_hash) return 0;
if (*start == 'C') {
custom_object = 1;
}
@ -816,7 +827,7 @@ yy20:
return object_common2(UNSERIALIZE_PASSTHRU, elements);
}
#line 820 "ext/standard/var_unserializer.c"
#line 831 "ext/standard/var_unserializer.c"
yy25:
yych = *++YYCURSOR;
if (yych <= ',') {
@ -841,15 +852,16 @@ yy27:
yych = *++YYCURSOR;
if (yych != '"') goto yy18;
++YYCURSOR;
#line 722 "ext/standard/var_unserializer.re"
#line 732 "ext/standard/var_unserializer.re"
{
if (!var_hash) return 0;
//??? INIT_PZVAL(rval);
return object_common2(UNSERIALIZE_PASSTHRU,
object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR));
}
#line 853 "ext/standard/var_unserializer.c"
#line 865 "ext/standard/var_unserializer.c"
yy32:
yych = *++YYCURSOR;
if (yych == '+') goto yy33;
@ -870,11 +882,12 @@ yy34:
yych = *++YYCURSOR;
if (yych != '{') goto yy18;
++YYCURSOR;
#line 701 "ext/standard/var_unserializer.re"
#line 710 "ext/standard/var_unserializer.re"
{
zend_long elements = parse_iv(start + 2);
/* use iv() not uiv() in order to check data range */
*p = YYCURSOR;
if (!var_hash) return 0;
if (elements < 0) {
return 0;
@ -891,7 +904,7 @@ yy34:
return finish_nested_data(UNSERIALIZE_PASSTHRU);
}
#line 895 "ext/standard/var_unserializer.c"
#line 908 "ext/standard/var_unserializer.c"
yy39:
yych = *++YYCURSOR;
if (yych == '+') goto yy40;
@ -912,7 +925,7 @@ yy41:
yych = *++YYCURSOR;
if (yych != '"') goto yy18;
++YYCURSOR;
#line 673 "ext/standard/var_unserializer.re"
#line 682 "ext/standard/var_unserializer.re"
{
size_t len, maxlen;
zend_string *str;
@ -940,7 +953,7 @@ yy41:
ZVAL_STR(rval, str);
return 1;
}
#line 944 "ext/standard/var_unserializer.c"
#line 957 "ext/standard/var_unserializer.c"
yy46:
yych = *++YYCURSOR;
if (yych == '+') goto yy47;
@ -961,7 +974,7 @@ yy48:
yych = *++YYCURSOR;
if (yych != '"') goto yy18;
++YYCURSOR;
#line 646 "ext/standard/var_unserializer.re"
#line 655 "ext/standard/var_unserializer.re"
{
size_t len, maxlen;
char *str;
@ -988,7 +1001,7 @@ yy48:
ZVAL_STRINGL(rval, str, len);
return 1;
}
#line 992 "ext/standard/var_unserializer.c"
#line 1005 "ext/standard/var_unserializer.c"
yy53:
yych = *++YYCURSOR;
if (yych <= '/') {
@ -1076,7 +1089,7 @@ yy61:
}
yy63:
++YYCURSOR;
#line 637 "ext/standard/var_unserializer.re"
#line 646 "ext/standard/var_unserializer.re"
{
#if SIZEOF_ZEND_LONG == 4
use_double:
@ -1085,7 +1098,7 @@ use_double:
ZVAL_DOUBLE(rval, zend_strtod((const char *)start + 2, NULL));
return 1;
}
#line 1089 "ext/standard/var_unserializer.c"
#line 1102 "ext/standard/var_unserializer.c"
yy65:
yych = *++YYCURSOR;
if (yych <= ',') {
@ -1144,7 +1157,7 @@ yy73:
yych = *++YYCURSOR;
if (yych != ';') goto yy18;
++YYCURSOR;
#line 621 "ext/standard/var_unserializer.re"
#line 630 "ext/standard/var_unserializer.re"
{
*p = YYCURSOR;
@ -1160,7 +1173,7 @@ yy73:
return 1;
}
#line 1164 "ext/standard/var_unserializer.c"
#line 1177 "ext/standard/var_unserializer.c"
yy76:
yych = *++YYCURSOR;
if (yych == 'N') goto yy73;
@ -1187,7 +1200,7 @@ yy79:
if (yych <= '9') goto yy79;
if (yych != ';') goto yy18;
++YYCURSOR;
#line 595 "ext/standard/var_unserializer.re"
#line 604 "ext/standard/var_unserializer.re"
{
#if SIZEOF_ZEND_LONG == 4
int digits = YYCURSOR - start - 3;
@ -1213,7 +1226,7 @@ yy79:
ZVAL_LONG(rval, parse_iv(start + 2));
return 1;
}
#line 1217 "ext/standard/var_unserializer.c"
#line 1230 "ext/standard/var_unserializer.c"
yy83:
yych = *++YYCURSOR;
if (yych <= '/') goto yy18;
@ -1221,22 +1234,22 @@ yy83:
yych = *++YYCURSOR;
if (yych != ';') goto yy18;
++YYCURSOR;
#line 589 "ext/standard/var_unserializer.re"
#line 598 "ext/standard/var_unserializer.re"
{
*p = YYCURSOR;
ZVAL_BOOL(rval, parse_iv(start + 2));
return 1;
}
#line 1231 "ext/standard/var_unserializer.c"
#line 1244 "ext/standard/var_unserializer.c"
yy87:
++YYCURSOR;
#line 583 "ext/standard/var_unserializer.re"
#line 592 "ext/standard/var_unserializer.re"
{
*p = YYCURSOR;
ZVAL_NULL(rval);
return 1;
}
#line 1240 "ext/standard/var_unserializer.c"
#line 1253 "ext/standard/var_unserializer.c"
yy89:
yych = *++YYCURSOR;
if (yych <= ',') {
@ -1259,7 +1272,7 @@ yy91:
if (yych <= '9') goto yy91;
if (yych != ';') goto yy18;
++YYCURSOR;
#line 560 "ext/standard/var_unserializer.re"
#line 569 "ext/standard/var_unserializer.re"
{
zend_long id;
@ -1282,7 +1295,7 @@ yy91:
return 1;
}
#line 1286 "ext/standard/var_unserializer.c"
#line 1299 "ext/standard/var_unserializer.c"
yy95:
yych = *++YYCURSOR;
if (yych <= ',') {
@ -1305,7 +1318,7 @@ yy97:
if (yych <= '9') goto yy97;
if (yych != ';') goto yy18;
++YYCURSOR;
#line 538 "ext/standard/var_unserializer.re"
#line 547 "ext/standard/var_unserializer.re"
{
zend_long id;
@ -1327,9 +1340,9 @@ yy97:
return 1;
}
#line 1331 "ext/standard/var_unserializer.c"
#line 1344 "ext/standard/var_unserializer.c"
}
#line 883 "ext/standard/var_unserializer.re"
#line 895 "ext/standard/var_unserializer.re"
return 0;

View File

@ -101,9 +101,15 @@ PHPAPI zval *var_tmp_var(php_unserialize_data_t *var_hashx)
#if 0
PHPAPI void var_push_dtor_no_addref(php_unserialize_data_t *var_hashx, zval *rval)
{
var_dtor_entries *var_hash = (*var_hashx)->last_dtor;
var_entries *var_hash;
if (!var_hashx || !*var_hashx) {
return;
}
var_hash = (*var_hashx)->last_dtor;
#if VAR_ENTRIES_DBG
fprintf(stderr, "var_push_dtor_no_addref(%ld): %d (%d)\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval), Z_REFCOUNT_PP(rval));
fprintf(stderr, "var_push_dtor_no_addref(%p, %ld): %d (%d)\n", *rval, var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval), Z_REFCOUNT_PP(rval));
#endif
if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) {
@ -181,6 +187,9 @@ PHPAPI void var_destroy(php_unserialize_data_t *var_hashx)
while (var_dtor_hash) {
for (i = 0; i < var_dtor_hash->used_slots; i++) {
#if VAR_ENTRIES_DBG
fprintf(stderr, "var_destroy dtor(%p, %ld)\n", var_dtor_hash->data[i], Z_REFCOUNT_P(var_dtor_hash->data[i]));
#endif
zval_ptr_dtor(&var_dtor_hash->data[i]);
}
next = var_dtor_hash->next;
@ -702,6 +711,7 @@ use_double:
zend_long elements = parse_iv(start + 2);
/* use iv() not uiv() in order to check data range */
*p = YYCURSOR;
if (!var_hash) return 0;
if (elements < 0) {
return 0;
@ -720,6 +730,7 @@ use_double:
}
"o:" iv ":" ["] {
if (!var_hash) return 0;
//??? INIT_PZVAL(rval);
@ -741,6 +752,7 @@ object ":" uiv ":" ["] {
zval retval;
zval args[1];
if (!var_hash) return 0;
if (*start == 'C') {
custom_object = 1;
}

View File

@ -218,7 +218,9 @@ static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int t
if (error == 1) {
for (i = nargs - 1; i >= 0; i--) {
obj = valuePop(ctxt);
xmlXPathFreeObject(obj);
if (obj) {
xmlXPathFreeObject(obj);
}
}
return;
}

View File

@ -171,7 +171,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil
/* it is a directory only, see #40228 */
if (path_cleaned_len > 1 && IS_SLASH(path_cleaned[path_cleaned_len - 1])) {
len = spprintf(&file_dirname_fullpath, 0, "%s/%s", dest, file);
len = spprintf(&file_dirname_fullpath, 0, "%s/%s", dest, path_cleaned);
is_dir_only = 1;
} else {
memcpy(file_dirname, path_cleaned, path_cleaned_len);

View File

@ -0,0 +1,33 @@
--TEST--
Bug #70350 (ZipArchive::extractTo allows for directory traversal when creating directories)
--SKIPIF--
<?php
if(!extension_loaded('zip')) die('skip');
?>
--FILE--
<?php
$dir = dirname(__FILE__)."/bug70350";
mkdir($dir);
$archive = new ZipArchive();
$archive->open("$dir/a.zip",ZipArchive::CREATE);
$archive->addEmptyDir("../down2/");
$archive->close();
$archive2 = new ZipArchive();
$archive2->open("$dir/a.zip");
$archive2->extractTo($dir);
$archive2->close();
var_dump(file_exists("$dir/down2/"));
var_dump(file_exists("../down2/"));
?>
--CLEAN--
<?php
$dir = dirname(__FILE__)."/bug70350";
rmdir("$dir/down2");
unlink("$dir/a.zip");
rmdir($dir);
?>
--EXPECT--
bool(true)
bool(false)