diff options
author | Stanislav Malyshev <stas@php.net> | 2015-08-04 14:10:57 -0700 |
---|---|---|
committer | Stanislav Malyshev <stas@php.net> | 2015-08-04 14:10:57 -0700 |
commit | 69ed3969dd3b00feaa62f611c5095e27ba96274d (patch) | |
tree | 0eaaac44be832888b856808ec83153f42ccc577c /Zend/zend_exceptions.c | |
parent | 66edc158755a8e960499913f16f6455797bb5803 (diff) | |
parent | 51f9a00b47159ed13dfe5bd5af7e98986aa1a6fa (diff) | |
download | php-git-69ed3969dd3b00feaa62f611c5095e27ba96274d.tar.gz |
Merge branch 'PHP-5.4' into PHP-5.5
* PHP-5.4:
Fix bug #70019 - limit extracted files to given directory
Do not do convert_to_* on unserialize, it messes up references
Fix #69793 - limit what we accept when unserializing exception
Fixed bug #70169 (Use After Free Vulnerability in unserialize() with SplDoublyLinkedList)
Fixed bug #70166 - Use After Free Vulnerability in unserialize() with SPLArrayObject
ignore signatures for packages too
Fix bug #70168 - Use After Free Vulnerability in unserialize() with SplObjectStorage
Fixed bug #69892
Fix bug #70014 - use RAND_bytes instead of deprecated RAND_pseudo_bytes
Improved fix for Bug #69441
Fix bug #70068 (Dangling pointer in the unserialization of ArrayObject items)
Fix bug #70121 (unserialize() could lead to unexpected methods execution / NULL pointer deref)
Fix bug #70081: check types for SOAP variables
Conflicts:
.gitignore
ext/date/php_date.c
ext/spl/spl_array.c
ext/spl/spl_observer.c
Diffstat (limited to 'Zend/zend_exceptions.c')
-rw-r--r-- | Zend/zend_exceptions.c | 45 |
1 files changed, 37 insertions, 8 deletions
diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index f7eac9212c..806c2ef9e3 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -41,7 +41,7 @@ void zend_exception_set_previous(zval *exception, zval *add_previous TSRMLS_DC) if (exception == add_previous || !add_previous || !exception) { return; } - if (Z_TYPE_P(add_previous) != IS_OBJECT && !instanceof_function(Z_OBJCE_P(add_previous), default_exception_ce TSRMLS_CC)) { + if (Z_TYPE_P(add_previous) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(add_previous), default_exception_ce TSRMLS_CC)) { zend_error(E_ERROR, "Cannot set non exception as previous exception"); return; } @@ -218,6 +218,33 @@ ZEND_METHOD(exception, __construct) } /* }}} */ +/* {{{ proto Exception::__wakeup() + Exception unserialize checks */ +#define CHECK_EXC_TYPE(name, type) \ + value = zend_read_property(default_exception_ce, object, name, sizeof(name)-1, 0 TSRMLS_CC); \ + if(value && Z_TYPE_P(value) != type) { \ + zval *tmp; \ + MAKE_STD_ZVAL(tmp); \ + ZVAL_STRINGL(tmp, name, sizeof(name)-1, 1); \ + Z_OBJ_HANDLER_P(object, unset_property)(object, tmp, 0 TSRMLS_CC); \ + zval_ptr_dtor(&tmp); \ + } + +ZEND_METHOD(exception, __wakeup) +{ + zval *value; + zval *object = getThis(); + HashTable *intern_ht = zend_std_get_properties(getThis() TSRMLS_CC); + CHECK_EXC_TYPE("message", IS_STRING); + CHECK_EXC_TYPE("string", IS_STRING); + CHECK_EXC_TYPE("code", IS_LONG); + CHECK_EXC_TYPE("file", IS_STRING); + CHECK_EXC_TYPE("line", IS_LONG); + CHECK_EXC_TYPE("trace", IS_ARRAY); + CHECK_EXC_TYPE("previous", IS_OBJECT); +} +/* }}} */ + /* {{{ proto ErrorException::__construct(string message, int code, int severity [, string filename [, int lineno [, Exception previous]]]) ErrorException constructor */ ZEND_METHOD(error_exception, __construct) @@ -586,7 +613,7 @@ ZEND_METHOD(exception, getTraceAsString) int res_len = 0, *len = &res_len, num = 0; DEFAULT_0_PARAMS; - + trace = zend_read_property(default_exception_ce, getThis(), "trace", sizeof("trace")-1, 1 TSRMLS_CC); if (Z_TYPE_P(trace) != IS_ARRAY) { RETURN_FALSE; @@ -602,8 +629,8 @@ ZEND_METHOD(exception, getTraceAsString) TRACE_APPEND_STRL(s_tmp, strlen(s_tmp)); efree(s_tmp); - res[res_len] = '\0'; - RETURN_STRINGL(res, res_len, 0); + res[res_len] = '\0'; + RETURN_STRINGL(res, res_len, 0); } /* }}} */ @@ -640,15 +667,15 @@ ZEND_METHOD(exception, __toString) int len = 0; zend_fcall_info fci; zval fname; - + DEFAULT_0_PARAMS; - + str = estrndup("", 0); exception = getThis(); ZVAL_STRINGL(&fname, "gettraceasstring", sizeof("gettraceasstring")-1, 1); - while (exception && Z_TYPE_P(exception) == IS_OBJECT) { + while (exception && Z_TYPE_P(exception) == IS_OBJECT && instanceof_function(Z_OBJCE_P(exception), default_exception_ce TSRMLS_CC)) { prev_str = str; _default_exception_get_entry(exception, "message", sizeof("message")-1, &message TSRMLS_CC); _default_exception_get_entry(exception, "file", sizeof("file")-1, &file TSRMLS_CC); @@ -658,6 +685,7 @@ ZEND_METHOD(exception, __toString) convert_to_string(&file); convert_to_long(&line); + trace = NULL; fci.size = sizeof(fci); fci.function_table = &Z_OBJCE_P(exception)->function_table; fci.function_name = &fname; @@ -670,7 +698,7 @@ ZEND_METHOD(exception, __toString) zend_call_function(&fci, NULL TSRMLS_CC); - if (Z_TYPE_P(trace) != IS_STRING) { + if (trace && Z_TYPE_P(trace) != IS_STRING) { zval_ptr_dtor(&trace); trace = NULL; } @@ -727,6 +755,7 @@ ZEND_END_ARG_INFO() const static zend_function_entry default_exception_functions[] = { ZEND_ME(exception, __clone, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL) ZEND_ME(exception, __construct, arginfo_exception___construct, ZEND_ACC_PUBLIC) + ZEND_ME(exception, __wakeup, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_ME(exception, getMessage, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_ME(exception, getCode, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_ME(exception, getFile, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) |