aboutsummaryrefslogtreecommitdiffhomepage
path: root/php
diff options
context:
space:
mode:
Diffstat (limited to 'php')
-rw-r--r--php/ext/google/protobuf/encode_decode.c100
-rw-r--r--php/ext/google/protobuf/message.c1
-rw-r--r--php/ext/google/protobuf/package.xml38
-rw-r--r--php/ext/google/protobuf/protobuf.h3
-rw-r--r--php/src/Google/Protobuf/Any.php7
-rw-r--r--php/src/Google/Protobuf/Internal/Message.php37
-rw-r--r--php/tests/encode_decode_test.php47
7 files changed, 223 insertions, 10 deletions
diff --git a/php/ext/google/protobuf/encode_decode.c b/php/ext/google/protobuf/encode_decode.c
index 7e2b3ae6..b98121bb 100644
--- a/php/ext/google/protobuf/encode_decode.c
+++ b/php/ext/google/protobuf/encode_decode.c
@@ -1402,7 +1402,6 @@ static void putarray(zval* array, const upb_fielddef* f, upb_sink* sink,
RepeatedField* intern = UNBOX(RepeatedField, array);
HashTable *ht = PHP_PROTO_HASH_OF(intern->array);
size = zend_hash_num_elements(ht);
- // size = zend_hash_num_elements(PHP_PROTO_HASH_OF(intern->array));
if (size == 0) return;
upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);
@@ -1614,3 +1613,102 @@ PHP_METHOD(Message, mergeFromJsonString) {
stackenv_uninit(&se);
}
}
+
+// TODO(teboring): refactoring with putrawmsg
+static void discard_unknown_fields(MessageHeader* msg) {
+ upb_msg_field_iter it;
+
+ stringsink* unknown = DEREF(message_data(msg), 0, stringsink*);
+ if (unknown != NULL) {
+ stringsink_uninit(unknown);
+ DEREF(message_data(msg), 0, stringsink*) = NULL;
+ }
+
+ // Recursively discard unknown fields of submessages.
+ Descriptor* desc = msg->descriptor;
+ TSRMLS_FETCH();
+ for (upb_msg_field_begin(&it, desc->msgdef);
+ !upb_msg_field_done(&it);
+ upb_msg_field_next(&it)) {
+ upb_fielddef* f = upb_msg_iter_field(&it);
+ uint32_t offset = desc->layout->fields[upb_fielddef_index(f)].offset;
+ bool containing_oneof = false;
+
+ if (upb_fielddef_containingoneof(f)) {
+ uint32_t oneof_case_offset =
+ desc->layout->fields[upb_fielddef_index(f)].case_offset;
+ // For a oneof, check that this field is actually present -- skip all the
+ // below if not.
+ if (DEREF(message_data(msg), oneof_case_offset, uint32_t) !=
+ upb_fielddef_number(f)) {
+ continue;
+ }
+ // Otherwise, fall through to the appropriate singular-field handler
+ // below.
+ containing_oneof = true;
+ }
+
+ if (is_map_field(f)) {
+ MapIter map_it;
+ int len, size;
+ const upb_fielddef* value_field;
+
+ value_field = map_field_value(f);
+ if (!upb_fielddef_issubmsg(value_field)) continue;
+
+ zval* map_php = CACHED_PTR_TO_ZVAL_PTR(
+ DEREF(message_data(msg), offset, CACHED_VALUE*));
+ if (map_php == NULL) continue;
+
+ Map* intern = UNBOX(Map, map_php);
+ for (map_begin(map_php, &map_it TSRMLS_CC);
+ !map_done(&map_it); map_next(&map_it)) {
+ upb_value value = map_iter_value(&map_it, &len);
+ void* memory = raw_value(upb_value_memory(&value), value_field);
+#if PHP_MAJOR_VERSION < 7
+ MessageHeader *submsg = UNBOX(MessageHeader, *(zval**)memory);
+#else
+ MessageHeader *submsg =
+ (MessageHeader*)((char*)(Z_OBJ_P((zval*)memory)) -
+ XtOffsetOf(MessageHeader, std));
+#endif
+ discard_unknown_fields(submsg);
+ }
+ } else if (upb_fielddef_isseq(f)) {
+ if (!upb_fielddef_issubmsg(f)) continue;
+
+ zval* array_php = CACHED_PTR_TO_ZVAL_PTR(
+ DEREF(message_data(msg), offset, CACHED_VALUE*));
+ if (array_php == NULL) continue;
+
+ int size, i;
+ RepeatedField* intern = UNBOX(RepeatedField, array_php);
+ HashTable *ht = PHP_PROTO_HASH_OF(intern->array);
+ size = zend_hash_num_elements(ht);
+ if (size == 0) continue;
+
+ for (i = 0; i < size; i++) {
+ void* memory = repeated_field_index_native(intern, i TSRMLS_CC);
+#if PHP_MAJOR_VERSION < 7
+ MessageHeader *submsg = UNBOX(MessageHeader, *(zval**)memory);
+#else
+ MessageHeader *submsg =
+ (MessageHeader*)((char*)(Z_OBJ_P((zval*)memory)) -
+ XtOffsetOf(MessageHeader, std));
+#endif
+ discard_unknown_fields(submsg);
+ }
+ } else if (upb_fielddef_issubmsg(f)) {
+ zval* submsg_php = CACHED_PTR_TO_ZVAL_PTR(
+ DEREF(message_data(msg), offset, CACHED_VALUE*));
+ if (Z_TYPE_P(submsg_php) == IS_NULL) continue;
+ MessageHeader* submsg = UNBOX(MessageHeader, submsg_php);
+ discard_unknown_fields(submsg);
+ }
+ }
+}
+
+PHP_METHOD(Message, discardUnknownFields) {
+ MessageHeader* msg = UNBOX(MessageHeader, getThis());
+ discard_unknown_fields(msg);
+}
diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c
index cf75d979..b14c1f0c 100644
--- a/php/ext/google/protobuf/message.c
+++ b/php/ext/google/protobuf/message.c
@@ -42,6 +42,7 @@ static void hex_to_binary(const char* hex, char** binary, int* binary_len);
static zend_function_entry message_methods[] = {
PHP_ME(Message, clear, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Message, discardUnknownFields, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Message, serializeToString, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Message, mergeFromString, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Message, serializeToJsonString, NULL, ZEND_ACC_PUBLIC)
diff --git a/php/ext/google/protobuf/package.xml b/php/ext/google/protobuf/package.xml
index 0107ebc2..626eb46b 100644
--- a/php/ext/google/protobuf/package.xml
+++ b/php/ext/google/protobuf/package.xml
@@ -10,11 +10,11 @@
<email>protobuf-opensource@google.com</email>
<active>yes</active>
</lead>
- <date>2017-12-06</date>
+ <date>2017-12-11</date>
<time>11:02:07</time>
<version>
- <release>3.5.0.1</release>
- <api>3.5.0.1</api>
+ <release>3.5.1</release>
+ <api>3.5.1</api>
</version>
<stability>
<release>stable</release>
@@ -170,6 +170,22 @@ GA release.
</release>
<release>
<version>
+ <release>3.5.0</release>
+ <api>3.5.0</api>
+ </version>
+ <stability>
+ <release>stable</release>
+ <api>stable</api>
+ </stability>
+ <date>2017-11-15</date>
+ <time>11:02:07</time>
+ <license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license>
+ <notes>
+GA release.
+ </notes>
+ </release>
+ <release>
+ <version>
<release>3.5.0.1</release>
<api>3.5.0.1</api>
</version>
@@ -184,5 +200,21 @@ GA release.
GA release.
</notes>
</release>
+ <release>
+ <version>
+ <release>3.5.1</release>
+ <api>3.5.1</api>
+ </version>
+ <stability>
+ <release>stable</release>
+ <api>stable</api>
+ </stability>
+ <date>2017-12-11</date>
+ <time>11:02:07</time>
+ <license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license>
+ <notes>
+GA release.
+ </notes>
+ </release>
</changelog>
</package>
diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h
index 8289eb2b..f299b415 100644
--- a/php/ext/google/protobuf/protobuf.h
+++ b/php/ext/google/protobuf/protobuf.h
@@ -37,7 +37,7 @@
#include "upb.h"
#define PHP_PROTOBUF_EXTNAME "protobuf"
-#define PHP_PROTOBUF_VERSION "3.5.0.1"
+#define PHP_PROTOBUF_VERSION "3.5.1"
#define MAX_LENGTH_OF_INT64 20
#define SIZEOF_INT64 8
@@ -957,6 +957,7 @@ PHP_METHOD(Message, serializeToString);
PHP_METHOD(Message, mergeFromString);
PHP_METHOD(Message, serializeToJsonString);
PHP_METHOD(Message, mergeFromJsonString);
+PHP_METHOD(Message, discardUnknownFields);
// -----------------------------------------------------------------------------
// Type check / conversion.
diff --git a/php/src/Google/Protobuf/Any.php b/php/src/Google/Protobuf/Any.php
index 91ba4bd5..f027b05d 100644
--- a/php/src/Google/Protobuf/Any.php
+++ b/php/src/Google/Protobuf/Any.php
@@ -4,7 +4,6 @@
namespace Google\Protobuf;
-use Google\Protobuf\Internal\DescriptorPool;
use Google\Protobuf\Internal\GPBType;
use Google\Protobuf\Internal\GPBUtil;
use Google\Protobuf\Internal\Message;
@@ -217,7 +216,7 @@ class Any extends \Google\Protobuf\Internal\Message
substr($this->type_url, $url_prifix_len);
// Create message according to fully qualified name.
- $pool = DescriptorPool::getGeneratedPool();
+ $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
$desc = $pool->getDescriptorByProtoName( ".".$fully_qualifed_name);
if (is_null($desc)) {
throw new \Exception("Class ".$fully_qualifed_name
@@ -248,7 +247,7 @@ class Any extends \Google\Protobuf\Internal\Message
$this->value = $msg->serializeToString();
// Set type url.
- $pool = DescriptorPool::getGeneratedPool();
+ $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
$desc = $pool->getDescriptorByClassName(get_class($msg));
$fully_qualifed_name = $desc->getFullName();
$this->type_url = GPBUtil::TYPE_URL_PREFIX.substr(
@@ -262,7 +261,7 @@ class Any extends \Google\Protobuf\Internal\Message
*/
public function is($klass)
{
- $pool = DescriptorPool::getGeneratedPool();
+ $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
$desc = $pool->getDescriptorByClassName($klass);
$fully_qualifed_name = $desc->getFullName();
$type_url = GPBUtil::TYPE_URL_PREFIX.substr(
diff --git a/php/src/Google/Protobuf/Internal/Message.php b/php/src/Google/Protobuf/Internal/Message.php
index a7a4f272..93e81c01 100644
--- a/php/src/Google/Protobuf/Internal/Message.php
+++ b/php/src/Google/Protobuf/Internal/Message.php
@@ -577,6 +577,43 @@ class Message
}
/**
+ * Clear all unknown fields previously parsed.
+ * @return null.
+ */
+ public function discardUnknownFields()
+ {
+ $this->unknown = "";
+ foreach ($this->desc->getField() as $field) {
+ if ($field->getType() != GPBType::MESSAGE) {
+ continue;
+ }
+ if ($field->isMap()) {
+ $value_field = $field->getMessageType()->getFieldByNumber(2);
+ if ($value_field->getType() != GPBType::MESSAGE) {
+ continue;
+ }
+ $getter = $field->getGetter();
+ $map = $this->$getter();
+ foreach ($map as $key => $value) {
+ $value->discardUnknownFields();
+ }
+ } else if ($field->getLabel() === GPBLabel::REPEATED) {
+ $getter = $field->getGetter();
+ $arr = $this->$getter();
+ foreach ($arr as $sub) {
+ $sub->discardUnknownFields();
+ }
+ } else if ($field->getLabel() === GPBLabel::OPTIONAL) {
+ $getter = $field->getGetter();
+ $sub = $this->$getter();
+ if (!is_null($sub)) {
+ $sub->discardUnknownFields();
+ }
+ }
+ }
+ }
+
+ /**
* Merges the contents of the specified message into current message.
*
* This method merges the contents of the specified message into the
diff --git a/php/tests/encode_decode_test.php b/php/tests/encode_decode_test.php
index 4dca922b..74d5526d 100644
--- a/php/tests/encode_decode_test.php
+++ b/php/tests/encode_decode_test.php
@@ -443,29 +443,74 @@ class EncodeDecodeTest extends TestBase
public function testUnknown()
{
+ // Test preserve unknown for varint.
$m = new TestMessage();
- $from = hex2bin('F80601');
+ $from = hex2bin('F80601'); // TODO(teboring): Add a util to encode
+ // varint for better readability
$m->mergeFromString($from);
$to = $m->serializeToString();
$this->assertSame(bin2hex($from), bin2hex($to));
+ // Test preserve unknown for 64-bit.
$m = new TestMessage();
$from = hex2bin('F9060000000000000000');
$m->mergeFromString($from);
$to = $m->serializeToString();
$this->assertSame(bin2hex($from), bin2hex($to));
+ // Test preserve unknown for length delimited.
$m = new TestMessage();
$from = hex2bin('FA0600');
$m->mergeFromString($from);
$to = $m->serializeToString();
$this->assertSame(bin2hex($from), bin2hex($to));
+ // Test preserve unknown for 32-bit.
$m = new TestMessage();
$from = hex2bin('FD0600000000');
$m->mergeFromString($from);
$to = $m->serializeToString();
$this->assertSame(bin2hex($from), bin2hex($to));
+
+ // Test discard unknown in message.
+ $m = new TestMessage();
+ $from = hex2bin('F80601');
+ $m->mergeFromString($from);
+ $m->discardUnknownFields();
+ $to = $m->serializeToString();
+ $this->assertSame("", bin2hex($to));
+
+ // Test discard unknown for singular message field.
+ $m = new TestMessage();
+ $from = hex2bin('8A0103F80601');
+ $m->mergeFromString($from);
+ $m->discardUnknownFields();
+ $to = $m->serializeToString();
+ $this->assertSame("8a0100", bin2hex($to));
+
+ // Test discard unknown for repeated message field.
+ $m = new TestMessage();
+ $from = hex2bin('FA0203F80601');
+ $m->mergeFromString($from);
+ $m->discardUnknownFields();
+ $to = $m->serializeToString();
+ $this->assertSame("fa0200", bin2hex($to));
+
+ // Test discard unknown for map message value field.
+ $m = new TestMessage();
+ $from = hex2bin("BA050708011203F80601");
+ $m->mergeFromString($from);
+ $m->discardUnknownFields();
+ $to = $m->serializeToString();
+ $this->assertSame("ba050408011200", bin2hex($to));
+
+ // Test discard unknown for singular message field.
+ $m = new TestMessage();
+ $from = hex2bin('9A0403F80601');
+ $m->mergeFromString($from);
+ $m->discardUnknownFields();
+ $to = $m->serializeToString();
+ $this->assertSame("9a0400", bin2hex($to));
}
public function testJsonEncode()