CopernicaMarketingSoftware / PHP-CPP

Library to build PHP extensions with C++
http://www.php-cpp.com/
Apache License 2.0
1.42k stars 333 forks source link

Segfault when calling non existing static function on method #309

Open zordtk opened 7 years ago

zordtk commented 7 years ago

Sorry for the title, didn't know how to really phrase this crash. If I take the CppClassesInPhp example and compile it with the latest PHP-CPP commit and PHP 7.1.0 then call a non existent static function on the MyClass object that is created in C++:

$foo = MyClass::bar()

It results in a Segfault with the following backtrace:

`Program received signal SIGSEGV, Segmentation fault. 0x0000555555b80b73 in ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER () at /home/droz/php-7.1.0/Zend/zend_vm_execute.h:5580 5580 ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name)); (gdb) bt

0 0x0000555555b80b73 in ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER () at /home/droz/php-7.1.0/Zend/zend_vm_execute.h:5580

1 0x0000555555b73358 in execute_ex (ex=0x7ffff4214030) at /home/droz/php-7.1.0/Zend/zend_vm_execute.h:429

2 0x0000555555b73559 in zend_execute (op_array=0x7ffff4282000, return_value=0x0) at /home/droz/php-7.1.0/Zend/zend_vm_execute.h:474

3 0x0000555555b05afb in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /home/droz/php-7.1.0/Zend/zend.c:1474

4 0x0000555555a3c70c in php_execute_script (primary_file=0x7fffffffcd30) at /home/droz/php-7.1.0/main/main.c:2533

5 0x0000555555c02ff9 in do_cli (argc=2, argv=0x5555563c2e80) at /home/droz/php-7.1.0/sapi/cli/php_cli.c:990

6 0x0000555555c044a1 in main (argc=2, argv=0x5555563c2e80) at /home/droz/php-7.1.0/sapi/cli/php_cli.c:1378

`

sjinks commented 7 years ago
#0  0x0000555555e17cf2 in ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER () at /tmp/php-build/source/7.1.0/Zend/zend_vm_execute.h:5580
#1  0x0000555555e0a4d7 in execute_ex (ex=0x7fffee014030) at /tmp/php-build/source/7.1.0/Zend/zend_vm_execute.h:429
#2  0x0000555555e0a6d8 in zend_execute (op_array=0x7fffee088000, return_value=0x0) at /tmp/php-build/source/7.1.0/Zend/zend_vm_execute.h:474
#3  0x0000555555d9cc7a in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /tmp/php-build/source/7.1.0/Zend/zend.c:1474
#4  0x0000555555cd388b in php_execute_script (primary_file=0x7fffffffc8c0) at /tmp/php-build/source/7.1.0/main/main.c:2533
#5  0x0000555555e9a220 in do_cli (argc=7, argv=0x555556831ca0) at /tmp/php-build/source/7.1.0/sapi/cli/php_cli.c:990
#6  0x0000555555e9b6c8 in main (argc=7, argv=0x555556831ca0) at /tmp/php-build/source/7.1.0/sapi/cli/php_cli.c:1378
sjinks commented 7 years ago

MyClass as seen by PHP 7.1:

Class [ <internal:Cpp_classes_in_php> class MyClass ] {

  - Constants [0] {
  }

  - Static properties [0] {
  }

  - Static methods [0] {
  }

  - Properties [2] {
    Property [ <default> public $property1 ]
    Property [ <default> protected $property2 ]
  }

  - Methods [4] {
    Method [ <internal:Cpp_classes_in_php> final public method myMethod ] {

      - Parameters [0] {
      }
    }

    Method [ <internal:Cpp_classes_in_php> public method myMethod2 ] {

      - Parameters [0] {
      }
    }

    Method [ <internal:Cpp_classes_in_php> public method loopArray ] {

      - Parameters [1] {
        Parameter #0 [ <required> array $arr ]
      }
    }

    Method [ <internal:Cpp_classes_in_php> public method loopObject ] {

      - Parameters [1] {
        Parameter #0 [ <required> object $obj ]
      }
    }
  }
}
sjinks commented 7 years ago

PHP 7.0.9 crashes as well with the same backtrace

sjinks commented 7 years ago

Quick fix:

diff --git a/zend/classimpl.cpp b/zend/classimpl.cpp
index 48543b9..0fc742d 100644
--- a/zend/classimpl.cpp
+++ b/zend/classimpl.cpp
@@ -260,7 +260,7 @@ zend_function *ClassImpl::getStaticMethod(zend_class_entry *entry, zend_string *
     function->num_args = 0;
     function->required_num_args = 0;
     function->scope = nullptr;
-    function->fn_flags = ZEND_ACC_CALL_VIA_HANDLER;
+    function->fn_flags = ZEND_ACC_CALL_VIA_HANDLER | ZEND_ACC_STATIC;
     function->function_name = method;

     // store pointer to ourselves
zordtk commented 7 years ago

Thanks this fix works.