Explorar el Código

Initialize wrapper message during parsing (#6974)

* Initialize wrapper message during parsing
In case the internal value is default

* Fix zts build
Paul Yang hace 5 años
padre
commit
2929bb3736
Se han modificado 2 ficheros con 24 adiciones y 0 borrados
  1. 12 0
      php/ext/google/protobuf/encode_decode.c
  2. 12 0
      php/tests/encode_decode_test.php

+ 12 - 0
php/ext/google/protobuf/encode_decode.c

@@ -999,6 +999,12 @@ static void* wrapper_submsg_handler(void* closure, const void* hd) {
     frame->submsg = submsg;
     frame->is_msg = true;
   } else {
+    if (Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(cached)) == IS_NULL) {
+      // Needs to initiate the wrapper message
+      const upb_msgdef* msgdef = subdesc->msgdef;
+      const upb_fielddef* f = upb_msgdef_itof(msgdef, 1);
+      native_slot_get_default(upb_fielddef_type(f), cached TSRMLS_CC);
+    }
     // In this case, wrapper message hasn't been created and value will be
     // stored in cache directly.
     frame->submsg = cached;
@@ -1024,6 +1030,12 @@ static void* wrapper_oneofsubmsg_handler(void* closure, const void* hd) {
 
   if (oldcase != oneofdata->oneof_case_num) {
     oneof_cleanup(msg, oneofdata);
+    if (Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(cached)) == IS_NULL) {
+      // Needs to initiate the wrapper message
+      const upb_msgdef* msgdef = subdesc->msgdef;
+      const upb_fielddef* f = upb_msgdef_itof(msgdef, 1);
+      native_slot_get_default(upb_fielddef_type(f), cached TSRMLS_CC);
+    }
     frame->submsg = cached;
     frame->is_msg = false;
   } else if (Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(cached)) == IS_OBJECT) {

+ 12 - 0
php/tests/encode_decode_test.php

@@ -1164,6 +1164,18 @@ class EncodeDecodeTest extends TestBase
             $m->serializeToJsonString());
     }
 
+    public function testEncodeAnyWithDefaultWrapperMessagePacked()
+    {
+        $any = new Any();
+        $any->pack(new TestInt32Value([
+            'field' => new Int32Value(['value' => 0]),
+        ]));
+        $this->assertSame(
+            "{\"@type\":\"type.googleapis.com/foo.TestInt32Value\"," .
+            "\"field\":0}",
+            $any->serializeToJsonString());
+    }
+
     public function testDecodeTopLevelFieldMask()
     {
         $m = new TestMessage();