A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/protocolbuffers/protobuf/commit/f9863dfd3c98278e703be0e3c19ded2d09e60fde below:

[php][ext] Prevent Seg fault if constructor is not called (#21240) · protocolbuffers/protobuf@f9863df · GitHub

File tree Expand file treeCollapse file tree 2 files changed

+59

-2

lines changed

Filter options

Expand file treeCollapse file tree 2 files changed

+59

-2

lines changed Original file line number Diff line number Diff line change

@@ -65,6 +65,7 @@ static zend_object* Message_create(zend_class_entry* class_type) {

65 65

Message_SuppressDefaultProperties(class_type);

66 66

zend_object_std_init(&intern->std, class_type);

67 67

intern->std.handlers = &message_object_handlers;

68 +

intern->desc = NULL;

68 69

Arena_Init(&intern->arena);

69 70

return &intern->std;

70 71

}

@@ -89,6 +90,15 @@ static void Message_dtor(zend_object* obj) {

89 90

* Helper function to look up a field given a member name (as a string).

90 91

*/

91 92

static const upb_FieldDef* get_field(Message* msg, zend_string* member) {

93 +

if (!msg || !msg->desc || !msg->desc->msgdef) {

94 +

zend_throw_exception_ex(NULL, 0,

95 +

"Couldn't find descriptor. "

96 +

"The message constructor was likely bypassed, "

97 +

"resulting in an uninitialized descriptor.");

98 + 99 +

return NULL;

100 +

}

101 + 92 102

const upb_MessageDef* m = msg->desc->msgdef;

93 103

const upb_FieldDef* f = upb_MessageDef_FindFieldByNameWithSize(

94 104

m, ZSTR_VAL(member), ZSTR_LEN(member));

Original file line number Diff line number Diff line change

@@ -21,12 +21,27 @@

21 21

use Php\Test\TestNamespace;

22 22 23 23

# This is not allowed, but we at least shouldn't crash.

24 -

class C extends \Google\Protobuf\Internal\Message {

25 -

public function __construct($data = null) {

24 +

class C extends \Google\Protobuf\Internal\Message

25 +

{

26 +

public function __construct($data = null)

27 +

{

26 28

parent::__construct($data);

27 29

}

28 30

}

29 31 32 +

# This is not allowed, but we at least shouldn't crash.

33 +

class TestMessageMockProxy extends TestMessage

34 +

{

35 +

public $_proxy_data = null;

36 + 37 +

public function __construct($data = null)

38 +

{

39 +

$this->_proxy_data = $data;

40 +

// bypass parent constructor

41 +

// This is common behavior by phpunit ond other mock/proxy libraries

42 +

}

43 +

}

44 + 30 45

class GeneratedClassTest extends TestBase

31 46

{

32 47

@@ -1902,6 +1917,38 @@ public function testNoSegfaultWithError()

1902 1917

new TestMessage(['optional_int32' => $this->throwIntendedException()]);

1903 1918

}

1904 1919 1920 +

public function testNoSegfaultWithContructorBypass()

1921 +

{

1922 +

if (!extension_loaded('protobuf')) {

1923 +

$this->markTestSkipped('PHP Protobuf extension is not loaded');

1924 +

}

1925 + 1926 +

$this->expectException(Exception::class);

1927 +

$this->expectExceptionMessage(

1928 +

"Couldn't find descriptor. " .

1929 +

"The message constructor was likely bypassed, resulting in an uninitialized descriptor."

1930 +

);

1931 + 1932 +

$m = new TestMessageMockProxy(['optional_int32' => 123]);

1933 + 1934 +

/**

1935 +

* At this point the message constructor was bypassed and the descriptor is not initialized.

1936 +

* This is a common PHP pattern where a proxy/mock class extends a concrete class,

1937 +

* frequently used in frameworks like PHPUnit, phpspec, and Mockery.

1938 +

*

1939 +

* When this happens, the message's internal descriptor is never initialized.

1940 +

*

1941 +

* Without proper handling, accessing properties via getters (like $this->getOptionalInt32())

1942 +

* would cause the C extension to segfault when trying to access the uninitialized descriptor.

1943 +

*

1944 +

* Instead of segfaulting, we now detect this uninitialized state and throw an exception.

1945 +

*

1946 +

* See: https://github.com/protocolbuffers/protobuf/issues/19978

1947 +

*/

1948 + 1949 +

$m->getOptionalInt32();

1950 +

}

1951 + 1905 1952

public function testNoExceptionWithVarDump()

1906 1953

{

1907 1954

$m = new Sub(['a' => 1]);

You can’t perform that action at this time.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4