]> granicus.if.org Git - php/commitdiff
Fix bug #70121 (unserialize() could lead to unexpected methods execution / NULL point...
authorStanislav Malyshev <stas@php.net>
Mon, 27 Jul 2015 00:09:34 +0000 (17:09 -0700)
committerStanislav Malyshev <stas@php.net>
Mon, 27 Jul 2015 00:10:24 +0000 (17:10 -0700)
Zend/tests/bug70121.phpt [new file with mode: 0644]
Zend/zend_exceptions.c

diff --git a/Zend/tests/bug70121.phpt b/Zend/tests/bug70121.phpt
new file mode 100644 (file)
index 0000000..9f8b7d6
--- /dev/null
@@ -0,0 +1,9 @@
+--TEST--
+Bug #70121 (unserialize() could lead to unexpected methods execution / NULL pointer deref)
+--FILE--
+<?php
+unserialize('O:12:"DateInterval":1:{s:4:"days";O:9:"Exception":7:{s:10:"'."\0".'*'."\0".'message";s:1:"x";s:17:"'."\0".'Exception'."\0".'string";s:1:"A";s:7:"'."\0".'*'."\0".'code";i:0;s:7:"'."\0".'*'."\0".'file";s:1:"a";s:7:"'."\0".'*'."\0".'line";i:1337;s:16:"'."\0".'Exception'."\0".'trace";a:0:{}s:19:"'."\0".'Exception'."\0".'previous";O:8:"stdClass":0:{}}}');
+?>
+OK
+--EXPECT--
+OK
index 06be9885d5aafdfc0eb0e15d9ed14553e27ed27d..1a3ee8f434e4870677333aeb268503f2e0b20642 100644 (file)
@@ -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;
        }
@@ -586,7 +586,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 +602,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 +640,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 +658,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 +671,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;
                }