Unverified Commit 1069565a authored by Paul Yang's avatar Paul Yang Committed by GitHub

Fix c extension doesn' allow message reference in array (#5599)

* Fix c extension doesn' allow message reference in array

* Fix array constructor handling reference of array.

* Change test name
parent a4c09f3e
...@@ -319,6 +319,11 @@ void Message_construct(zval* msg, zval* array_wrapper) { ...@@ -319,6 +319,11 @@ void Message_construct(zval* msg, zval* array_wrapper) {
zend_hash_move_forward_ex(array, &pointer)) { zend_hash_move_forward_ex(array, &pointer)) {
zend_hash_get_current_key_zval_ex(array, &key, &pointer); zend_hash_get_current_key_zval_ex(array, &key, &pointer);
field = upb_msgdef_ntofz(intern->descriptor->msgdef, Z_STRVAL_P(&key)); field = upb_msgdef_ntofz(intern->descriptor->msgdef, Z_STRVAL_P(&key));
#if PHP_MAJOR_VERSION >= 7
if (Z_ISREF_P((CACHED_VALUE*)value)) {
value = Z_REFVAL_P((CACHED_VALUE*)value);
}
#endif
if (field == NULL) { if (field == NULL) {
zend_error(E_USER_ERROR, "Unknown field: %s", Z_STRVAL_P(&key)); zend_error(E_USER_ERROR, "Unknown field: %s", Z_STRVAL_P(&key));
} }
......
...@@ -186,6 +186,12 @@ bool native_slot_set_by_array(upb_fieldtype_t type, ...@@ -186,6 +186,12 @@ bool native_slot_set_by_array(upb_fieldtype_t type,
break; break;
} }
case UPB_TYPE_MESSAGE: { case UPB_TYPE_MESSAGE: {
#if PHP_MAJOR_VERSION >= 7
if (Z_ISREF_P(value)) {
ZVAL_DEREF(value);
}
#endif
if (Z_TYPE_P(value) != IS_OBJECT) { if (Z_TYPE_P(value) != IS_OBJECT) {
zend_error(E_USER_ERROR, "Given value is not message."); zend_error(E_USER_ERROR, "Given value is not message.");
return false; return false;
......
...@@ -529,6 +529,37 @@ class RepeatedFieldTest extends \PHPUnit\Framework\TestCase ...@@ -529,6 +529,37 @@ class RepeatedFieldTest extends \PHPUnit\Framework\TestCase
$this->assertSame(3, $arr[2]); $this->assertSame(3, $arr[2]);
} }
#########################################################
# Test reference in array
#########################################################
public function testArrayElementIsReference()
{
$m = new TestMessage();
$subs = [1, 2];
foreach ($subs as &$sub) {
$sub = new Sub(['a' => $sub]);
}
$m->setRepeatedMessage($subs);
}
public function testArrayIsReference()
{
$keys = [['repeated_message' => [['a' => 1]]]];
foreach ($keys as &$key) {
foreach ($key['repeated_message'] as &$element) {
$element = new Sub($element);
}
$key = new TestMessage($key);
}
$m = new TestMessage();
$m->setRepeatedDeep($keys);
}
######################################################### #########################################################
# Test memory leak # Test memory leak
######################################################### #########################################################
......
...@@ -31,6 +31,7 @@ message TestMessage { ...@@ -31,6 +31,7 @@ message TestMessage {
Sub optional_message = 17; Sub optional_message = 17;
bar.TestInclude optional_included_message = 18; bar.TestInclude optional_included_message = 18;
TestMessage recursive = 19; TestMessage recursive = 19;
repeated TestMessage repeated_deep = 20;
// Repeated // Repeated
repeated int32 repeated_int32 = 31; repeated int32 repeated_int32 = 31;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment