From cfa5e722fb5b00598a73b988ae4b6ccd428193dc Mon Sep 17 00:00:00 2001 From: Christiano Becker Date: Mon, 20 Feb 2023 12:47:20 -0300 Subject: [PATCH 1/2] * Propagate exception when zend_read_property reads __get and throws an exception --- v8js_object_export.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/v8js_object_export.cc b/v8js_object_export.cc index ea1a0f25..7b287a1f 100644 --- a/v8js_object_export.cc +++ b/v8js_object_export.cc @@ -765,10 +765,12 @@ v8::Local v8js_named_property_callback(v8::Local property_n (property_info != ZEND_WRONG_PROPERTY_INFO && property_info->flags & ZEND_ACC_PUBLIC)) { zval *property_val = zend_read_property(NULL, &zobject, name, name_len, true, &php_value); - // special case uninitialized_zval_ptr and return an empty value - // (indicating that we don't intercept this property) if the - // property doesn't exist. - if (property_val == &EG(uninitialized_zval)) { + if(EG(exception)) { + ret_value = v8js_propagate_exception(ctx); + } else if (property_val == &EG(uninitialized_zval)) { + // special case uninitialized_zval_ptr and return an empty value + // (indicating that we don't intercept this property) if the + // property doesn't exist. ret_value = v8::Local(); } else { // wrap it From 35b5bff97702ba2aca44b0c9541c15e2eefabd1e Mon Sep 17 00:00:00 2001 From: Christiano Becker Date: Mon, 20 Feb 2023 14:59:41 -0300 Subject: [PATCH 2/2] * Added test tests/php_exceptions_007.phpt --- tests/php_exceptions_007.phpt | 54 +++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 tests/php_exceptions_007.phpt diff --git a/tests/php_exceptions_007.phpt b/tests/php_exceptions_007.phpt new file mode 100644 index 00000000..a02c69ec --- /dev/null +++ b/tests/php_exceptions_007.phpt @@ -0,0 +1,54 @@ +--TEST-- +Test V8::executeString() : PHP Exception handling (throwed inside magic method) +--SKIPIF-- + +--FILE-- +triggerException(); + } +} + +function execute($code, $flags = V8Js::FLAG_NONE) { + $js = new V8Js(); + $js->output = new stdClass(); + $js->SomeClassInstance = new SomeClass(); + try { + $js->executeString(" + try { + $code + } catch(e) { + PHP.output.result = 'Caught exception at javascript level : ' + e.getMessage(); + } + ", '', $flags); + print($js->output->result.PHP_EOL); + } catch (Exception $e) { + print( "Caught exception at php level : ".$e->getMessage().PHP_EOL); + } +} + +execute("PHP.SomeClassInstance.triggerException();"); +execute("PHP.SomeClassInstance.someMethod(PHP.SomeClassInstance.TriggerMagicMethod);"); +execute("PHP.SomeClassInstance.TriggerMagicMethod;"); +execute("PHP.SomeClassInstance.triggerException();", V8Js::FLAG_PROPAGATE_PHP_EXCEPTIONS); +execute("PHP.SomeClassInstance.someMethod(PHP.SomeClassInstance.TriggerMagicMethod);", V8Js::FLAG_PROPAGATE_PHP_EXCEPTIONS); +execute("PHP.SomeClassInstance.TriggerMagicMethod;", V8Js::FLAG_PROPAGATE_PHP_EXCEPTIONS); +?> +===EOF=== +--EXPECTF-- +Caught exception at php level : Some exception +Caught exception at php level : Some exception +Caught exception at php level : Some exception +Caught exception at javascript level : Some exception +Caught exception at javascript level : Some exception +Caught exception at javascript level : Some exception +===EOF===