]> granicus.if.org Git - php/commitdiff
Fix segmentation fault in debug_backtrace()
authorTimm Friebe <thekid@thekid.de>
Sat, 27 Sep 2014 19:24:19 +0000 (19:24 +0000)
committerNikita Popov <nikic@php.net>
Sun, 28 Sep 2014 18:58:55 +0000 (20:58 +0200)
Zend/tests/debug_backtrace_with_include_and_this.phpt [new file with mode: 0644]
Zend/zend_builtin_functions.c

diff --git a/Zend/tests/debug_backtrace_with_include_and_this.phpt b/Zend/tests/debug_backtrace_with_include_and_this.phpt
new file mode 100644 (file)
index 0000000..171ad9f
--- /dev/null
@@ -0,0 +1,39 @@
+--TEST--
+debug_backtrace segmentation fault with include and error handler 
+--FILE--
+<?php
+class CLWrapper {
+  function stream_open($path, $mode, $options, $opened_path) {
+    return false;
+  }
+}
+
+class CL {
+  public function load($class) {
+    if (!include($class)) {
+      throw new Exception('Failed loading '.$class);
+    }
+  }
+}
+
+stream_wrapper_register('class', 'CLWrapper');
+set_error_handler(function($code, $msg, $file, $line) {
+  $bt= debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
+  echo "ERR#$code: $msg @ ", $bt[1]['function'], "\n";
+});
+
+try {
+  (new CL())->load('class://non.existant.Class');
+} catch (CLException $e) {
+  echo $e."\n";
+}
+--EXPECTF--
+ERR#2: include(class://non.existant.Class): failed to open stream: "CLWrapper::stream_open" call failed @ include
+ERR#2: include(): Failed opening 'class://non.existant.Class' for inclusion (include_path='%s') @ include
+
+Fatal error: Uncaught exception 'Exception' with message 'Failed loading class://non.existant.Class' in %s
+Stack trace:
+#0 %s(%d): CL->load('class://non.exi...')
+#1 {main}
+  thrown in %s on line %d
+
index 0cbe50bc0f7596162cb96160e37f262568f695d6..9d8cda84d68e5f92ad3821a221f2d1287f9841e1 100644 (file)
@@ -2396,6 +2396,7 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
                /* $this may be passed into regular internal functions */
                object = call ? call->object : NULL;
                if (object &&
+                   call->func &&
                    call->func->type == ZEND_INTERNAL_FUNCTION &&
                    !call->func->common.scope) {
                        object = NULL;