Browse Source

Don't restore original error handler when exiting inner frame, refs #94

Stefan Siegl 11 năm trước cách đây
mục cha
commit
1fc79f8223
2 tập tin đã thay đổi với 33 bổ sung1 xóa
  1. 30 0
      tests/fatal_error_no_uninstall_inner_frame.phpt
  2. 3 1
      v8js_convert.cc

+ 30 - 0
tests/fatal_error_no_uninstall_inner_frame.phpt

@@ -0,0 +1,30 @@
+--TEST--
+Test V8::executeString() : Fatal Error handler not to uninstall on inner frames
+--SKIPIF--
+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
+--FILE--
+<?php
+
+$js = new V8Js();
+
+$js->bar = function() {
+	echo "nothing.\n";
+};
+
+$js->foo = function() {
+	global $js;
+	// call to JS context, this must not touch the error handling context
+	$js->executeString("PHP.bar();");
+
+	$bar = null;
+	$bar->foo();
+};
+
+$js->executeString("PHP.foo();");
+
+?>
+===EOF===
+--EXPECTF--
+nothing.
+
+Fatal error: Call to a member function foo() on a non-object in %s/fatal_error_no_uninstall_inner_frame.php on line 15

+ 3 - 1
v8js_convert.cc

@@ -167,11 +167,13 @@ static void php_v8js_call_php_func(zval *value, zend_class_entry *ce, zend_funct
 
 		jmp_buf env;
 		int val = 0;
+		bool installed_handler = false;
 
 		/* If this is the first level call from V8 back to PHP, install a
 		 * handler for fatal errors; we must fall back through V8 to keep
 		 * it from crashing. */
 		if (V8JSG(unwind_env) == NULL) {
+			installed_handler = true;
 			V8JSG(old_error_handler) = zend_error_cb;
 			zend_error_cb = php_v8js_error_handler;
 
@@ -184,7 +186,7 @@ static void php_v8js_call_php_func(zval *value, zend_class_entry *ce, zend_funct
 			zend_call_function(&fci, &fcc TSRMLS_CC);
 		}
 
-		if (V8JSG(old_error_handler) != NULL) {
+		if (installed_handler) {
 			zend_error_cb = V8JSG(old_error_handler);
 			V8JSG(unwind_env) = NULL;
 		}