Skip to content

Exception not thrown in Javascript despite FLAG_PROPAGATE_PHP_EXCEPTIONS being set #437

Closed
@sajkog

Description

@sajkog

I managed to come across a weird scenario where javascript code executes PHP that throws exception and this exception is not caught within javascript despite try/catch blocks and FLAG_PROPAGATE_PHP_EXCEPTIONS being set.

My current understanding is that it happens when exception is thrown in PHP magic methods.

Below is the code reproducing the issue (+Dockerfile if of any use)

Code:

<?php
class SomeClass {
    function someMethod($someVariable) { return $someVariable; }
    public function triggerException() { throw new Exception("Some exception");}
    public function __get($key) { $this->triggerException(); }
}

function execute($code) {
    $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();}", '', V8Js::FLAG_PROPAGATE_PHP_EXCEPTIONS);
        print($js->output->result.PHP_EOL);
    } catch (Exception $e) {
        print( "Caught exception at php level : ".$e->getMessage().PHP_EOL);
    }
}

execute("PHP.SomeClassInstance.triggerException();"); //caught in js
execute("PHP.SomeClassInstance.someMethod(PHP.SomeClassInstance.TriggerMagicMethod);");//caught in js
execute("PHP.SomeClassInstance.TriggerMagicMethod;");//caught in PHP !

Dockerfile:

FROM stesie/v8js
RUN echo "<?php\n" \
          "class SomeClass {\n" \
          "    function someMethod(\$someVariable) { return \$someVariable; }\n" \
          "    public function triggerException() { throw new Exception('Some exception');}\n" \
          "    public function __get(\$key) { \$this->triggerException(); }\n" \
          "}\n" \
          "\n" \
          "function execute(\$code) {\n" \
          "    \$js = new V8Js();\n" \
          "    \$js->output = new stdClass();\n" \
          "    \$js->SomeClassInstance = new SomeClass();\n" \
          "    try {\n" \
          "        \$js->executeString(\"try{ \$code } catch(e) {PHP.output.result = 'Caught exception at javascript level : ' + e.getMessage();}\", '', V8Js::FLAG_PROPAGATE_PHP_EXCEPTIONS);\n" \
          "        print(\$js->output->result.PHP_EOL);\n" \
          "    } catch (Exception \$e) {\n" \
          "        print( 'Caught exception at php level : '.\$e->getMessage().PHP_EOL);\n" \
          "    }\n" \
          "}\n" \
          "" \
          "execute('PHP.SomeClassInstance.triggerException();'); //caught in js\n" \
          "execute('PHP.SomeClassInstance.someMethod(PHP.SomeClassInstance.TriggerMagicMethod);');//caught in js\n" \
          "execute('PHP.SomeClassInstance.TriggerMagicMethod;');//caught in PHP !" > /test.php
CMD php /test.php

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions