diff options
-rw-r--r-- | php/ext/google/protobuf/protobuf.h | 2 | ||||
-rw-r--r-- | php/ext/google/protobuf/storage.c | 20 | ||||
-rw-r--r-- | php/tests/encode_decode_test.php | 8 | ||||
-rw-r--r-- | php/tests/memory_leak_test.php | 1 | ||||
-rw-r--r-- | php/tests/proto/test.proto | 6 |
5 files changed, 35 insertions, 2 deletions
diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h index 684a9c50..eecae136 100644 --- a/php/ext/google/protobuf/protobuf.h +++ b/php/ext/google/protobuf/protobuf.h @@ -640,7 +640,7 @@ bool native_slot_set(upb_fieldtype_t type, const zend_class_entry* klass, bool native_slot_set_by_array(upb_fieldtype_t type, const zend_class_entry* klass, void* memory, zval* value TSRMLS_DC); -void native_slot_init(upb_fieldtype_t type, void* memory, void* cache); +void native_slot_init(upb_fieldtype_t type, void* memory, CACHED_VALUE* cache); // For each property, in order to avoid conversion between the zval object and // the actual data type during parsing/serialization, the containing message // object use the custom memory layout to store the actual data type for each diff --git a/php/ext/google/protobuf/storage.c b/php/ext/google/protobuf/storage.c index 29a3db86..c0e4da3e 100644 --- a/php/ext/google/protobuf/storage.c +++ b/php/ext/google/protobuf/storage.c @@ -210,7 +210,7 @@ bool native_slot_set_by_array(upb_fieldtype_t type, return true; } -void native_slot_init(upb_fieldtype_t type, void* memory, void* cache) { +void native_slot_init(upb_fieldtype_t type, void* memory, CACHED_VALUE* cache) { zval* tmp = NULL; switch (type) { case UPB_TYPE_FLOAT: @@ -224,6 +224,9 @@ void native_slot_init(upb_fieldtype_t type, void* memory, void* cache) { break; case UPB_TYPE_STRING: case UPB_TYPE_BYTES: + DEREF(memory, CACHED_VALUE*) = cache; + ZVAL_EMPTY_STRING(CACHED_PTR_TO_ZVAL_PTR(cache)); + break; case UPB_TYPE_MESSAGE: DEREF(memory, CACHED_VALUE*) = cache; break; @@ -621,6 +624,21 @@ void layout_init(MessageLayout* layout, void* storage, int cache_index = slot_property_cache(layout, storage, field); CACHED_VALUE* property_ptr = &properties_table[cache_index]; + // Clean up initial value by generated code. In the generated code of + // previous versions, each php field is given an initial value. However, the + // order to initialize these fields may not be consistent with the order of + // upb fields. + if (Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(property_ptr)) == IS_STRING) { +#if PHP_MAJOR_VERSION < 7 + if (!IS_INTERNED(Z_STRVAL_PP(property_ptr))) { + FREE(Z_STRVAL_PP(property_ptr)); + } +#else + zend_string_release(Z_STR_P(property_ptr)); +#endif + } + ZVAL_NULL(CACHED_PTR_TO_ZVAL_PTR(property_ptr)); + if (upb_fielddef_containingoneof(field)) { memset(memory, 0, NATIVE_SLOT_MAX_SIZE); *oneof_case = ONEOF_CASE_NONE; diff --git a/php/tests/encode_decode_test.php b/php/tests/encode_decode_test.php index 2ea360b2..b43dffb4 100644 --- a/php/tests/encode_decode_test.php +++ b/php/tests/encode_decode_test.php @@ -9,6 +9,7 @@ use Foo\TestEnum; use Foo\TestMessage; use Foo\TestMessage_Sub; use Foo\TestPackedMessage; +use Foo\TestRandomFieldOrder; use Foo\TestUnpackedMessage; class EncodeDecodeTest extends TestBase @@ -235,6 +236,13 @@ class EncodeDecodeTest extends TestBase $this->assertEquals(-1, $m->getOptionalInt32()); } + public function testRandomFieldOrder() + { + $m = new TestRandomFieldOrder(); + $data = $m->serializeToString(); + $this->assertSame("", $data); + } + /** * @expectedException Exception */ diff --git a/php/tests/memory_leak_test.php b/php/tests/memory_leak_test.php index 6572fdd0..faa1833d 100644 --- a/php/tests/memory_leak_test.php +++ b/php/tests/memory_leak_test.php @@ -20,6 +20,7 @@ require_once('generated/Foo/TestMessage_NestedEnum.php'); require_once('generated/Foo/TestMessage_Sub.php'); require_once('generated/Foo/TestPackedMessage.php'); require_once('generated/Foo/TestPhpDoc.php'); +require_once('generated/Foo/TestRandomFieldOrder.php'); require_once('generated/Foo/TestUnpackedMessage.php'); require_once('generated/GPBMetadata/Proto/Test.php'); require_once('generated/GPBMetadata/Proto/TestEmptyPhpNamespace.php'); diff --git a/php/tests/proto/test.proto b/php/tests/proto/test.proto index dada8b48..d81f66f5 100644 --- a/php/tests/proto/test.proto +++ b/php/tests/proto/test.proto @@ -181,3 +181,9 @@ message TestIncludeNamespaceMessage { TestNamespace namespace_message = 1; TestEmptyNamespace empty_namespace_message = 2; } + +// This will cause upb fields not ordered by the order in the generated code. +message TestRandomFieldOrder { + int64 tag13 = 150; + string tag14 = 160; +} |