Commit:    a11606b18fd20be1048a858eb5011fb7117855a9
Author:    Johannes Schlüter <johan...@php.net>         Thu, 13 Dec 2012 
22:39:35 +0100
Parents:   39a3007ab2f88d860beb524024ab97fb13110561
Branches:  PHP-5.3 PHP-5.4 PHP-5.5 master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=a11606b18fd20be1048a858eb5011fb7117855a9

Log:
Fix Bug #63762 Sigsegv when Exception::$trace is changed by user

Bugs:
https://bugs.php.net/63762

Changed paths:
  M  NEWS
  A  Zend/tests/bug63762.phpt
  M  Zend/zend_exceptions.c


Diff:
diff --git a/NEWS b/NEWS
index 52b1b82..78c4b7c 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,10 @@ PHP                                                            
            NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? 2013, PHP 5.3.21
 
+- Zend Engine:
+  . Fixed bug #63762 (Sigsegv when Exception::$trace is changed by user).
+    (Johannes)
+
 ?? ??? 2012, PHP 5.3.20
 
 #### ADD NEWS TO 5.3.21 ONLY ####
diff --git a/Zend/tests/bug63762.phpt b/Zend/tests/bug63762.phpt
new file mode 100644
index 0000000..8de177d
--- /dev/null
+++ b/Zend/tests/bug63762.phpt
@@ -0,0 +1,53 @@
+--TEST--
+Bug #63762 - Sigsegv when Exception::$trace is changed by user
+--FILE--
+<?php
+$e = new Exception();
+
+$ref = new ReflectionProperty($e, 'trace');
+$ref->setAccessible(TRUE);
+
+echo "Array of NULL:\n";
+$ref->setValue($e, array(NULL));
+
+var_dump($e->getTraceAsString());
+
+echo "\nArray of empty array:\n";
+$ref->setValue($e, array(array()));
+var_dump($e->getTraceAsString());
+
+echo "\nArray of array of NULL values:\n";
+$ref->setValue($e, array(array(
+    'file'  => NULL,
+    'line'  => NULL,
+    'class' => NULL,
+    'type'  => NULL,
+    'function' => NULL,
+    'args'  => NULL
+)));
+var_dump($e->getTraceAsString());
+?>
+--EXPECTF--
+Array of NULL:
+
+Warning: Expected array for frame 0 in %s on line %d
+string(9) "#0 {main}"
+
+Array of empty array:
+string(36) "#0 [internal function]: ()
+#1 {main}"
+
+Array of array of NULL values:
+
+Warning: Function name is no string in %s on line %d
+
+Warning: Value for class is no string in %s on line %d
+
+Warning: Value for type is no string in %s on line %d
+
+Warning: Value for function is no string in %s on line %d
+
+Warning: args element is no array in %s on line %d
+string(60) "#0 [unknown function][unknown][unknown][unknown]()
+#1 {main}"
+
diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c
index a83053e..e947a97 100644
--- a/Zend/zend_exceptions.c
+++ b/Zend/zend_exceptions.c
@@ -337,9 +337,14 @@ ZEND_METHOD(error_exception, getSeverity)
 #define TRACE_APPEND_STR(val)                                            \
        TRACE_APPEND_STRL(val, sizeof(val)-1)
 
-#define TRACE_APPEND_KEY(key)                                            \
-       if (zend_hash_find(ht, key, sizeof(key), (void**)&tmp) == SUCCESS) { \
-           TRACE_APPEND_STRL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));           \
+#define TRACE_APPEND_KEY(key)                                                  
 \
+       if (zend_hash_find(ht, key, sizeof(key), (void**)&tmp) == SUCCESS) {    
\
+               if (Z_TYPE_PP(tmp) != IS_STRING) {                              
\
+                       zend_error(E_WARNING, "Value for %s is no string", 
key); \
+                       TRACE_APPEND_STR("[unknown]");                          
\
+               } else {                                                        
\
+                       TRACE_APPEND_STRL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));  
\
+               }                                                               
\
        }
 
 /* }}} */
@@ -448,6 +453,11 @@ static int _build_trace_string(zval **frame TSRMLS_DC, int 
num_args, va_list arg
        HashTable *ht = Z_ARRVAL_PP(frame);
        zval **file, **tmp;
 
+       if (Z_TYPE_PP(frame) != IS_ARRAY) {
+               zend_error(E_WARNING, "Expected array for frame %lu", 
hash_key->h);
+               return ZEND_HASH_APPLY_KEEP;
+       }
+
        str = va_arg(args, char**);
        len = va_arg(args, int*);
        num = va_arg(args, int*);
@@ -457,15 +467,25 @@ static int _build_trace_string(zval **frame TSRMLS_DC, 
int num_args, va_list arg
        TRACE_APPEND_STRL(s_tmp, strlen(s_tmp));
        efree(s_tmp);
        if (zend_hash_find(ht, "file", sizeof("file"), (void**)&file) == 
SUCCESS) {
-               if (zend_hash_find(ht, "line", sizeof("line"), (void**)&tmp) == 
SUCCESS) {
-                       line = Z_LVAL_PP(tmp);
-               } else {
-                       line = 0;
+               if (Z_TYPE_PP(file) != IS_STRING) {
+                       zend_error(E_WARNING, "Function name is no string");
+                       TRACE_APPEND_STR("[unknown function]");
+               } else{
+                       if (zend_hash_find(ht, "line", sizeof("line"), 
(void**)&tmp) == SUCCESS) {
+                               if (Z_TYPE_PP(tmp) == IS_LONG) {
+                                       line = Z_LVAL_PP(tmp);
+                               } else {
+                                       zend_error(E_WARNING, "Line is no 
long");
+                                       line = 0;
+                               }
+                       } else {
+                               line = 0;
+                       }
+                       s_tmp = emalloc(Z_STRLEN_PP(file) + MAX_LENGTH_OF_LONG 
+ 4 + 1);
+                       sprintf(s_tmp, "%s(%ld): ", Z_STRVAL_PP(file), line);
+                       TRACE_APPEND_STRL(s_tmp, strlen(s_tmp));
+                       efree(s_tmp);
                }
-               s_tmp = emalloc(Z_STRLEN_PP(file) + MAX_LENGTH_OF_LONG + 4 + 1);
-               sprintf(s_tmp, "%s(%ld): ", Z_STRVAL_PP(file), line);
-               TRACE_APPEND_STRL(s_tmp, strlen(s_tmp));
-               efree(s_tmp);
        } else {
                TRACE_APPEND_STR("[internal function]: ");
        }
@@ -474,10 +494,14 @@ static int _build_trace_string(zval **frame TSRMLS_DC, 
int num_args, va_list arg
        TRACE_APPEND_KEY("function");
        TRACE_APPEND_CHR('(');
        if (zend_hash_find(ht, "args", sizeof("args"), (void**)&tmp) == 
SUCCESS) {
-               int last_len = *len;
-               zend_hash_apply_with_arguments(Z_ARRVAL_PP(tmp) TSRMLS_CC, 
(apply_func_args_t)_build_trace_args, 2, str, len);
-               if (last_len != *len) {
-                       *len -= 2; /* remove last ', ' */
+               if (Z_TYPE_PP(tmp) == IS_ARRAY) {
+                       int last_len = *len;
+                       zend_hash_apply_with_arguments(Z_ARRVAL_PP(tmp) 
TSRMLS_CC, (apply_func_args_t)_build_trace_args, 2, str, len);
+                       if (last_len != *len) {
+                               *len -= 2; /* remove last ', ' */
+                       }
+               } else {
+                       zend_error(E_WARNING, "args element is no array");
                }
        }
        TRACE_APPEND_STR(")\n");


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to