瀏覽代碼

No free when construct was not done (#6483)

* No free when construct was not done

This fix the segfault when some other error happens

* Add more tests

* Use Sub to avoid printing too much
Paul Yang 6 年之前
父節點
當前提交
56988bee34
共有 2 個文件被更改,包括 29 次插入4 次删除
  1. 6 4
      php/ext/google/protobuf/message.c
  2. 23 0
      php/tests/generated_class_test.php

+ 6 - 4
php/ext/google/protobuf/message.c

@@ -89,11 +89,13 @@ static HashTable* message_get_properties(zval* object TSRMLS_DC);
 
 // Define object free method.
 PHP_PROTO_OBJECT_FREE_START(MessageHeader, message)
-  if (*(void**)intern->data != NULL) {
-    stringsink_uninit_opaque(*(void**)intern->data);
-    FREE(*(void**)intern->data);
+  if (intern->data) {
+    if (*(void**)intern->data != NULL) {
+      stringsink_uninit_opaque(*(void**)intern->data);
+      FREE(*(void**)intern->data);
+    }
+    FREE(intern->data);
   }
-  FREE(intern->data);
 PHP_PROTO_OBJECT_FREE_END
 
 PHP_PROTO_OBJECT_DTOR_START(MessageHeader, message)

+ 23 - 0
php/tests/generated_class_test.php

@@ -1504,4 +1504,27 @@ class GeneratedClassTest extends TestBase
         $m = new TestMessage();
         $m->setOptionalString($values[0]);
     }
+
+    #########################################################
+    # Test no segfault when error happens
+    #########################################################
+
+    function throwIntendedException()
+    {
+        throw new Exception('Intended');
+    }
+
+    /**
+     * @expectedException Exception
+     */
+    public function testNoSegfaultWithError()
+    {
+        new TestMessage(['optional_int32' => $this->throwIntendedException()]);
+    }
+
+    public function testNoExceptionWithVarDump()
+    {
+        $m = new Sub(['a' => 1]);
+        var_dump($m);
+    }
 }