From 14a10f441de70c79ef4a3915fd4f26f8b1e4c2d6 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 10 Jul 2006 14:02:54 +0000 Subject: [PATCH] Fixed bug #37947 (zend_ptr_stack reallocation problem) --- ext/standard/tests/serialize/bug37947.phpt | 21 ++++++++ ext/standard/var.c | 56 +++++++++++----------- 2 files changed, 48 insertions(+), 29 deletions(-) create mode 100755 ext/standard/tests/serialize/bug37947.phpt diff --git a/ext/standard/tests/serialize/bug37947.phpt b/ext/standard/tests/serialize/bug37947.phpt new file mode 100755 index 0000000000..7b106cbb85 --- /dev/null +++ b/ext/standard/tests/serialize/bug37947.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #37947 (zend_ptr_stack reallocation problem) +--INI-- +error_reporting=0 +--FILE-- +0) $this->extend_zend_ptr_stack($count - +1,$a,$b,$c,$d,$e); + } + + function __wakeup() { + $this->extend_zend_ptr_stack(10,'a','b','c','d','e'); + } +} + +$str='a:2:{i:0;O:4:"test":0:{}junk'; +var_dump(unserialize($str)); +--EXPECT-- +bool(false) diff --git a/ext/standard/var.c b/ext/standard/var.c index 39581a6f8e..a72dbe3aaf 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -1100,49 +1100,47 @@ PHP_FUNCTION(serialize) PHP_FUNCTION(unserialize) { - zval **buf; + unsigned char *buf; + char *str = NULL; + int buf_len; + zend_uchar buf_type; + const unsigned char *p; + php_unserialize_data_t var_hash; - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &buf) == FAILURE) { - WRONG_PARAM_COUNT; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "T", + &buf, &buf_len, &buf_type) == FAILURE) { + RETURN_FALSE; } - if (Z_TYPE_PP(buf) == IS_UNICODE) { + if (buf_len == 0) { + RETURN_FALSE; + } + + if (buf_type == IS_UNICODE) { /* ASCII unicode string to binary string conversion */ - char *str = emalloc(Z_USTRLEN_PP(buf)+1); int i; - for (i = 0; i < Z_UNILEN_PP(buf); i++) { - if (Z_USTRVAL_PP(buf)[i] > 128) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Error at offset %d of %d bytes", i, Z_USTRLEN_PP(buf)); + str = emalloc(buf_len+1); + for (i = 0; i < buf_len; i++) { + if (buf[i] > 128) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Error at offset %d of %d bytes", i, buf_len); } - str[i] = Z_USTRVAL_PP(buf)[i]; + str[i] = buf[i]; } str[i] = '\0'; - efree(Z_USTRVAL_PP(buf)); - Z_STRVAL_PP(buf) = str; - Z_TYPE_PP(buf) = IS_STRING; + buf = str; } - - if (Z_TYPE_PP(buf) == IS_STRING) { - const unsigned char *p = (unsigned char*)Z_STRVAL_PP(buf); - - if (Z_STRLEN_PP(buf) == 0) { - RETURN_FALSE; - } - - PHP_VAR_UNSERIALIZE_INIT(var_hash); - if (!php_var_unserialize(&return_value, &p, p + Z_STRLEN_PP(buf), &var_hash TSRMLS_CC)) { - PHP_VAR_UNSERIALIZE_DESTROY(var_hash); - zval_dtor(return_value); - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Error at offset %ld of %d bytes", (long)((char*)p - Z_STRVAL_PP(buf)), Z_STRLEN_PP(buf)); - RETURN_FALSE; - } + + p = (const unsigned char*)buf; + PHP_VAR_UNSERIALIZE_INIT(var_hash); + if (!php_var_unserialize(&return_value, &p, p + buf_len, &var_hash TSRMLS_CC)) { PHP_VAR_UNSERIALIZE_DESTROY(var_hash); - } else { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Argument is not a string"); + zval_dtor(return_value); + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Error at offset %ld of %d bytes", (long)((unsigned char*)p - buf), buf_len); RETURN_FALSE; } + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); } /* }}} */ -- 2.40.0