-
Notifications
You must be signed in to change notification settings - Fork 16k
Description
We are trying to migrate an application from the PHP Protobuf implementation to the C extension.
A few tests are using the prophecy to mock objects during tests.
and prophecy ends up creating a proxy that looks something like this :
class P5
extends \UserProfile\V1alpha\Account
implements \Prophecy\Doubler\DoubleInterface, \Prophecy\Prophecy\ProphecySubjectInterface, \Prophecy\Doubler\Generator\ReflectionInterface
{
private $objectProphecyClosure;
public function __construct( $data = NULL) {
if (0 < func_num_args()) {
call_user_func_array(array('parent', '__construct'), func_get_args());
}
}
public function setProphecy(\Prophecy\Prophecy\ProphecyInterface $prophecy) {
if (null === $this->objectProphecyClosure) {
$this->objectProphecyClosure = static function () use ($prophecy) {
return $prophecy;
};
}
}
public function getProphecy() {
return \call_user_func($this->objectProphecyClosure);
}
}Since the parent constructor is not always called it seems the message never properly initialized and the field lookup fails when get_field is called.
NOTE: This is a common pattern in many php frameworks.
And it is debatable weather or not this should be mocked/proxied but the behaviour is inconsistent between the two implementations and I believe no condition should trigger a seg fault.
What version of protobuf and what language are you using?
Version: main
Language: php
OS: Linux
What did you do?
<?php
# proxy_test.php
require_once('../vendor/autoload.php');
require_once('test_util.php');
use Foo\TestMessage;
class TestMessageProxy extends TestMessage
{
private $foo;
public function __construct($data = NULL) {
if (0 < func_num_args()) {
parent::__construct($data);
}
}
public function setFoo($foo) {
$this->foo = $foo;
}
public function getFoo() {
return $this->foo;
}
}
$p = new TestMessageProxy();
$p->setFoo('bar');
assert('bar' === $p->getFoo());# Compile the extension
./php/tests/compile_extension.sh
# Run script
php -d display_errors=on -dextension=../ext/google/protobuf/modules/protobuf.so proxy_test.phpWhat did you expect to see
No error
What did you see instead?
Segmentation fault (core dumped)
gdb
in get_field (msg=0x7ffff2bfb6c0, msg=0x7ffff2bfb6c0, member=<optimized out>)
at /tmp/pear/temp/protobuf/message.c:92
bt
#0 0x00007ffff3fb7836 in get_field (msg=0x7ffff280cd20, msg=0x7ffff280cd20, member=<optimized out>)
at /tmp/pear/temp/protobuf/message.c:92
#1 Message_read_property (obj=0x7ffff280cd20, member=0x7ffff3705a80, type=<optimized out>, cache_slot=0x7fffec4e8e98,
rv=0x7ffff4817c80) at /tmp/pear/temp/protobuf/message.c:312
#2 0x00005555559dc082 in execute_ex ()
#3 0x000055555563c839 in ?? ()