aboutsummaryrefslogtreecommitdiff
path: root/php
diff options
context:
space:
mode:
authorBo Yang <teboring@google.com>2019-03-04 10:18:18 -0800
committerBo Yang <teboring@google.com>2019-03-04 10:18:18 -0800
commitcb6fa92ee8f924e8c524efdbe502858e97e6975d (patch)
treefd47f781115c7a55aac7538e652ce96b94a1a7af /php
parent50bd9f0a7c14ed7689fcb9f5885e9ffacf9b80a9 (diff)
parent582743bf40c5d3639a70f98f183914a2c0cd0680 (diff)
downloadprotobuf-cb6fa92ee8f924e8c524efdbe502858e97e6975d.tar.gz
Merge branch '3.7.x'
Diffstat (limited to 'php')
-rw-r--r--php/ext/google/protobuf/def.c117
-rw-r--r--php/ext/google/protobuf/encode_decode.c12
-rw-r--r--php/ext/google/protobuf/message.c58
-rw-r--r--php/ext/google/protobuf/package.xml50
-rw-r--r--php/ext/google/protobuf/protobuf.h17
-rw-r--r--php/release.sh37
-rw-r--r--php/src/Google/Protobuf/Internal/Message.php3
-rw-r--r--php/tests/encode_decode_test.php10
-rw-r--r--php/tests/generated_class_test.php14
9 files changed, 229 insertions, 89 deletions
diff --git a/php/ext/google/protobuf/def.c b/php/ext/google/protobuf/def.c
index db6aec701..b14f59164 100644
--- a/php/ext/google/protobuf/def.c
+++ b/php/ext/google/protobuf/def.c
@@ -789,47 +789,44 @@ static bool is_reserved(const char *segment, int length) {
return result;
}
-static char* fill_prefix(const char *segment, int length,
- const char *prefix_given,
- const char *package_name, char *classname) {
+static void fill_prefix(const char *segment, int length,
+ const char *prefix_given,
+ const char *package_name,
+ stringsink *classname) {
size_t i;
if (prefix_given != NULL && strcmp(prefix_given, "") != 0) {
- size_t prefix_len = strlen(prefix_given);
- memcpy(classname, prefix_given, strlen(prefix_given));
- classname += prefix_len;
+ stringsink_string(classname, NULL, prefix_given,
+ strlen(prefix_given), NULL);
} else {
if (is_reserved(segment, length)) {
if (package_name != NULL &&
strcmp("google.protobuf", package_name) == 0) {
- memcpy(classname, "GPB", 3);
- classname += 3;
+ stringsink_string(classname, NULL, "GPB", 3, NULL);
} else {
- memcpy(classname, "PB", 2);
- classname += 2;
+ stringsink_string(classname, NULL, "PB", 2, NULL);
}
}
}
- return classname;
}
-static char* fill_segment(const char *segment, int length,
- char *classname, bool use_camel) {
- memcpy(classname, segment, length);
+static void fill_segment(const char *segment, int length,
+ stringsink *classname, bool use_camel) {
if (use_camel && (segment[0] < 'A' || segment[0] > 'Z')) {
- classname[0] += 'A' - 'a';
+ char first = segment[0] + ('A' - 'a');
+ stringsink_string(classname, NULL, &first, 1, NULL);
+ stringsink_string(classname, NULL, segment + 1, length - 1, NULL);
+ } else {
+ stringsink_string(classname, NULL, segment, length, NULL);
}
- return classname + length;
}
-static char* fill_namespace(const char *package, const char *namespace_given,
- char *classname) {
+static void fill_namespace(const char *package, const char *namespace_given,
+ stringsink *classname) {
if (namespace_given != NULL) {
- size_t namespace_len = strlen(namespace_given);
- memcpy(classname, namespace_given, namespace_len);
- classname += namespace_len;
- *classname = '\\';
- classname++;
+ stringsink_string(classname, NULL, namespace_given,
+ strlen(namespace_given), NULL);
+ stringsink_string(classname, NULL, "\\", 1, NULL);
} else if (package != NULL) {
int i = 0, j, offset = 0;
size_t package_len = strlen(package);
@@ -838,29 +835,27 @@ static char* fill_namespace(const char *package, const char *namespace_given,
while (j < package_len && package[j] != '.') {
j++;
}
- classname = fill_prefix(package + i, j - i, "", package, classname);
- classname = fill_segment(package + i, j - i, classname, true);
- classname[0] = '\\';
- classname++;
+ fill_prefix(package + i, j - i, "", package, classname);
+ fill_segment(package + i, j - i, classname, true);
+ stringsink_string(classname, NULL, "\\", 1, NULL);
i = j + 1;
}
}
- return classname;
}
-static char* fill_classname(const char *fullname,
- const char *package,
- const char *namespace_given,
- const char *prefix, char *classname) {
+static void fill_classname(const char *fullname,
+ const char *package,
+ const char *namespace_given,
+ const char *prefix,
+ stringsink *classname,
+ bool use_nested_submsg) {
int classname_start = 0;
if (package != NULL) {
size_t package_len = strlen(package);
classname_start = package_len == 0 ? 0 : package_len + 1;
}
size_t fullname_len = strlen(fullname);
- classname = fill_prefix(fullname + classname_start,
- fullname_len - classname_start,
- prefix, package, classname);
+ bool is_first_segment = true;
int i = classname_start, j;
while (i < fullname_len) {
@@ -868,22 +863,31 @@ static char* fill_classname(const char *fullname,
while (j < fullname_len && fullname[j] != '.') {
j++;
}
- classname = fill_segment(fullname + i, j - i, classname, false);
+ if (use_nested_submsg || is_first_segment && j == fullname_len) {
+ fill_prefix(fullname + i, j - i, prefix, package, classname);
+ }
+ is_first_segment = false;
+ fill_segment(fullname + i, j - i, classname, false);
if (j != fullname_len) {
- *classname = '_';
- classname++;
+ if (use_nested_submsg) {
+ stringsink_string(classname, NULL, "\\", 1, NULL);
+ } else {
+ stringsink_string(classname, NULL, "_", 1, NULL);
+ }
}
i = j + 1;
}
- return classname;
}
-static char* fill_qualified_classname(const char *fullname,
- const char *package,
- const char *namespace_given,
- const char *prefix, char *classname) {
- classname = fill_namespace(package, namespace_given, classname);
- return fill_classname(fullname, package, namespace_given, prefix, classname);
+static void fill_qualified_classname(const char *fullname,
+ const char *package,
+ const char *namespace_given,
+ const char *prefix,
+ stringsink *classname,
+ bool use_nested_submsg) {
+ fill_namespace(package, namespace_given, classname);
+ fill_classname(fullname, package, namespace_given, prefix,
+ classname, use_nested_submsg);
}
static void classname_no_prefix(const char *fullname, const char *package_name,
@@ -905,7 +909,8 @@ static void classname_no_prefix(const char *fullname, const char *package_name,
}
void internal_add_generated_file(const char *data, PHP_PROTO_SIZE data_len,
- InternalDescriptorPool *pool TSRMLS_DC) {
+ InternalDescriptorPool *pool,
+ bool use_nested_submsg TSRMLS_DC) {
upb_filedef **files;
size_t i;
@@ -946,16 +951,15 @@ void internal_add_generated_file(const char *data, PHP_PROTO_SIZE data_len,
const char *package = upb_filedef_package(files[0]); \
const char *php_namespace = upb_filedef_phpnamespace(files[0]); \
const char *prefix_given = upb_filedef_phpprefix(files[0]); \
- size_t classname_len = classname_len_max(fullname, package, \
- php_namespace, prefix_given); \
- char *classname = ecalloc(sizeof(char), classname_len); \
+ stringsink namesink; \
+ stringsink_init(&namesink); \
fill_qualified_classname(fullname, package, php_namespace, \
- prefix_given, classname); \
+ prefix_given, &namesink, use_nested_submsg); \
PHP_PROTO_CE_DECLARE pce; \
- if (php_proto_zend_lookup_class(classname, strlen(classname), &pce) == \
+ if (php_proto_zend_lookup_class(namesink.ptr, namesink.len, &pce) == \
FAILURE) { \
zend_error(E_ERROR, "Generated message class %s hasn't been defined", \
- classname); \
+ namesink.ptr); \
return; \
} else { \
desc->klass = PHP_PROTO_CE_UNREF(pce); \
@@ -963,7 +967,7 @@ void internal_add_generated_file(const char *data, PHP_PROTO_SIZE data_len,
add_ce_obj(desc->klass, desc_php); \
add_proto_obj(upb_##def_type_lower##_fullname(desc->def_type_lower), \
desc_php); \
- efree(classname); \
+ stringsink_uninit(&namesink); \
break; \
}
@@ -993,15 +997,18 @@ PHP_METHOD(InternalDescriptorPool, internalAddGeneratedFile) {
char *data = NULL;
PHP_PROTO_SIZE data_len;
upb_filedef **files;
+ zend_bool use_nested_submsg = false;
size_t i;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len) ==
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b",
+ &data, &data_len, &use_nested_submsg) ==
FAILURE) {
return;
}
InternalDescriptorPool *pool = UNBOX(InternalDescriptorPool, getThis());
- internal_add_generated_file(data, data_len, pool TSRMLS_CC);
+ internal_add_generated_file(data, data_len, pool,
+ use_nested_submsg TSRMLS_CC);
}
PHP_METHOD(DescriptorPool, getDescriptorByClassName) {
diff --git a/php/ext/google/protobuf/encode_decode.c b/php/ext/google/protobuf/encode_decode.c
index fa7aeb12a..ff185cab1 100644
--- a/php/ext/google/protobuf/encode_decode.c
+++ b/php/ext/google/protobuf/encode_decode.c
@@ -36,22 +36,14 @@
/* stringsink *****************************************************************/
-typedef struct {
- upb_byteshandler handler;
- upb_bytessink sink;
- char *ptr;
- size_t len, size;
-} stringsink;
-
-
static void *stringsink_start(void *_sink, const void *hd, size_t size_hint) {
stringsink *sink = _sink;
sink->len = 0;
return sink;
}
-static size_t stringsink_string(void *_sink, const void *hd, const char *ptr,
- size_t len, const upb_bufhandle *handle) {
+size_t stringsink_string(void *_sink, const void *hd, const char *ptr,
+ size_t len, const upb_bufhandle *handle) {
stringsink *sink = _sink;
size_t new_size = sink->size;
diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c
index 7cc3032c0..a957f2671 100644
--- a/php/ext/google/protobuf/message.c
+++ b/php/ext/google/protobuf/message.c
@@ -464,17 +464,29 @@ void Message_construct(zval* msg, zval* array_wrapper) {
const upb_msgdef* submsgdef = upb_fielddef_msgsubdef(field);
PHP_PROTO_HASHTABLE_VALUE desc_php = get_def_obj(submsgdef);
Descriptor* desc = UNBOX_HASHTABLE_VALUE(Descriptor, desc_php);
- zend_property_info* property_info;
- PHP_PROTO_FAKE_SCOPE_BEGIN(Z_OBJCE_P(msg));
+
+ CACHED_VALUE* cached = NULL;
+ if (upb_fielddef_containingoneof(field)) {
+ void* memory = slot_memory(intern->descriptor->layout,
+ message_data(intern), field);
+ int property_cache_index =
+ intern->descriptor->layout->fields[upb_fielddef_index(field)]
+ .cache_index;
+ cached = OBJ_PROP(Z_OBJ_P(msg), property_cache_index);
+ *(CACHED_VALUE**)(memory) = cached;
+ } else {
+ zend_property_info* property_info;
+ PHP_PROTO_FAKE_SCOPE_BEGIN(Z_OBJCE_P(msg));
#if PHP_MAJOR_VERSION < 7
- property_info =
- zend_get_property_info(Z_OBJCE_P(msg), &key, true TSRMLS_CC);
+ property_info =
+ zend_get_property_info(Z_OBJCE_P(msg), &key, true TSRMLS_CC);
#else
- property_info =
- zend_get_property_info(Z_OBJCE_P(msg), Z_STR_P(&key), true);
+ property_info =
+ zend_get_property_info(Z_OBJCE_P(msg), Z_STR_P(&key), true);
#endif
- PHP_PROTO_FAKE_SCOPE_END;
- CACHED_VALUE* cached = OBJ_PROP(Z_OBJ_P(msg), property_info->offset);
+ PHP_PROTO_FAKE_SCOPE_END;
+ cached = OBJ_PROP(Z_OBJ_P(msg), property_info->offset);
+ }
#if PHP_MAJOR_VERSION < 7
SEPARATE_ZVAL_IF_NOT_REF(cached);
#endif
@@ -689,7 +701,8 @@ static void init_file_any(TSRMLS_D) {
char* binary;
int binary_len;
hex_to_binary(generated_file, &binary, &binary_len);
- internal_add_generated_file(binary, binary_len, generated_pool TSRMLS_CC);
+ internal_add_generated_file(binary, binary_len,
+ generated_pool, true TSRMLS_CC);
FREE(binary);
is_inited_file_any = true;
}
@@ -729,7 +742,8 @@ static void init_file_api(TSRMLS_D) {
char* binary;
int binary_len;
hex_to_binary(generated_file, &binary, &binary_len);
- internal_add_generated_file(binary, binary_len, generated_pool TSRMLS_CC);
+ internal_add_generated_file(binary, binary_len,
+ generated_pool, true TSRMLS_CC);
FREE(binary);
is_inited_file_api = true;
}
@@ -749,7 +763,8 @@ static void init_file_duration(TSRMLS_D) {
char* binary;
int binary_len;
hex_to_binary(generated_file, &binary, &binary_len);
- internal_add_generated_file(binary, binary_len, generated_pool TSRMLS_CC);
+ internal_add_generated_file(binary, binary_len,
+ generated_pool, true TSRMLS_CC);
FREE(binary);
is_inited_file_duration = true;
}
@@ -769,7 +784,8 @@ static void init_file_field_mask(TSRMLS_D) {
char* binary;
int binary_len;
hex_to_binary(generated_file, &binary, &binary_len);
- internal_add_generated_file(binary, binary_len, generated_pool TSRMLS_CC);
+ internal_add_generated_file(binary, binary_len,
+ generated_pool, true TSRMLS_CC);
FREE(binary);
is_inited_file_field_mask = true;
}
@@ -788,7 +804,8 @@ static void init_file_empty(TSRMLS_D) {
char* binary;
int binary_len;
hex_to_binary(generated_file, &binary, &binary_len);
- internal_add_generated_file(binary, binary_len, generated_pool TSRMLS_CC);
+ internal_add_generated_file(binary, binary_len,
+ generated_pool, true TSRMLS_CC);
FREE(binary);
is_inited_file_empty = true;
}
@@ -809,7 +826,8 @@ static void init_file_source_context(TSRMLS_D) {
char* binary;
int binary_len;
hex_to_binary(generated_file, &binary, &binary_len);
- internal_add_generated_file(binary, binary_len, generated_pool TSRMLS_CC);
+ internal_add_generated_file(binary, binary_len,
+ generated_pool, true TSRMLS_CC);
FREE(binary);
is_inited_file_source_context = true;
}
@@ -843,7 +861,8 @@ static void init_file_struct(TSRMLS_D) {
char* binary;
int binary_len;
hex_to_binary(generated_file, &binary, &binary_len);
- internal_add_generated_file(binary, binary_len, generated_pool TSRMLS_CC);
+ internal_add_generated_file(binary, binary_len,
+ generated_pool, true TSRMLS_CC);
FREE(binary);
is_inited_file_struct = true;
}
@@ -863,7 +882,8 @@ static void init_file_timestamp(TSRMLS_D) {
char* binary;
int binary_len;
hex_to_binary(generated_file, &binary, &binary_len);
- internal_add_generated_file(binary, binary_len, generated_pool TSRMLS_CC);
+ internal_add_generated_file(binary, binary_len,
+ generated_pool, true TSRMLS_CC);
FREE(binary);
is_inited_file_timestamp = true;
}
@@ -931,7 +951,8 @@ static void init_file_type(TSRMLS_D) {
char* binary;
int binary_len;
hex_to_binary(generated_file, &binary, &binary_len);
- internal_add_generated_file(binary, binary_len, generated_pool TSRMLS_CC);
+ internal_add_generated_file(binary, binary_len,
+ generated_pool, true TSRMLS_CC);
FREE(binary);
is_inited_file_type = true;
}
@@ -958,7 +979,8 @@ static void init_file_wrappers(TSRMLS_D) {
char* binary;
int binary_len;
hex_to_binary(generated_file, &binary, &binary_len);
- internal_add_generated_file(binary, binary_len, generated_pool TSRMLS_CC);
+ internal_add_generated_file(binary, binary_len,
+ generated_pool, true TSRMLS_CC);
FREE(binary);
is_inited_file_wrappers = true;
}
diff --git a/php/ext/google/protobuf/package.xml b/php/ext/google/protobuf/package.xml
index c60ab6e61..8f5a27dea 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>2018-08-03</date>
- <time>11:02:07</time>
+ <date>2019-02-28</date>
+ <time>10:19:15</time>
<version>
- <release>3.6.1</release>
- <api>3.6.1</api>
+ <release>3.7.0</release>
+ <api>3.7.0</api>
</version>
<stability>
<release>stable</release>
@@ -262,5 +262,47 @@ G A release.
G A release.
</notes>
</release>
+ <release>
+ <version>
+ <release>3.7.0RC2</release>
+ <api>3.7.0</api>
+ </version>
+ <stability>
+ <release>stable</release>
+ <api>stable</api>
+ </stability>
+ <date>2019-02-1</date>
+ <time>10:22:43</time>
+ <license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license>
+ <notes>GA release.</notes>
+ </release>
+ <release>
+ <version>
+ <release>3.7.0RC3</release>
+ <api>3.7.0</api>
+ </version>
+ <stability>
+ <release>beta</release>
+ <api>beta</api>
+ </stability>
+ <date>2019-02-22</date>
+ <time>11:31:21</time>
+ <license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license>
+ <notes>GA release.</notes>
+ </release>
+ <release>
+ <version>
+ <release>3.7.0</release>
+ <api>3.7.0</api>
+ </version>
+ <stability>
+ <release>stable</release>
+ <api>stable</api>
+ </stability>
+ <date>2019-02-28</date>
+ <time>10:19:15</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 c4ab8860d..908e3bad9 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.6.1"
+#define PHP_PROTOBUF_VERSION "3.7.0"
#define MAX_LENGTH_OF_INT64 20
#define SIZEOF_INT64 8
@@ -770,7 +770,8 @@ PHP_METHOD(InternalDescriptorPool, getGeneratedPool);
PHP_METHOD(InternalDescriptorPool, internalAddGeneratedFile);
void internal_add_generated_file(const char* data, PHP_PROTO_SIZE data_len,
- InternalDescriptorPool* pool TSRMLS_DC);
+ InternalDescriptorPool* pool,
+ bool use_nested_submsg TSRMLS_DC);
void init_generated_pool_once(TSRMLS_D);
// wrapper of generated pool
@@ -1453,6 +1454,18 @@ const zend_class_entry* field_type_class(
const upb_fielddef* field PHP_PROTO_TSRMLS_DC);
void stringsink_uninit_opaque(void *sink);
+typedef struct {
+ upb_byteshandler handler;
+ upb_bytessink sink;
+ char *ptr;
+ size_t len, size;
+} stringsink;
+
+void stringsink_init(stringsink *sink);
+void stringsink_uninit(stringsink *sink);
+size_t stringsink_string(void *_sink, const void *hd, const char *ptr,
+ size_t len, const upb_bufhandle *handle);
+
// -----------------------------------------------------------------------------
// Utilities.
// -----------------------------------------------------------------------------
diff --git a/php/release.sh b/php/release.sh
new file mode 100644
index 000000000..220ca2aa4
--- /dev/null
+++ b/php/release.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+set -ex
+
+# Make sure we are in a protobuf source tree.
+[ -f "php/release.sh" ] || {
+ echo "This script must be ran under root of protobuf source tree."
+ exit 1
+}
+
+VERSION=$1
+
+git clone https://github.com/protocolbuffers/protobuf-php.git
+git clone https://github.com/protocolbuffers/protobuf.git
+
+# Clean old files
+pushd protobuf-php
+rm -rf src
+popd
+
+# Checkout the target version
+pushd protobuf/php
+git checkout $VERSION
+popd
+
+# Copy files
+pushd protobuf-php
+mv ../protobuf/php/src src
+mv ../protobuf/composer.json composer.json
+sed -i 's|php/src|src|g' composer.json
+git add .
+git commit -m "$VERSION"
+git tag "$VERSION"
+popd
+
+# Clean up
+rm -rf protobuf
diff --git a/php/src/Google/Protobuf/Internal/Message.php b/php/src/Google/Protobuf/Internal/Message.php
index 9765e09b5..1ff2dc9a6 100644
--- a/php/src/Google/Protobuf/Internal/Message.php
+++ b/php/src/Google/Protobuf/Internal/Message.php
@@ -832,6 +832,9 @@ class Message
if (is_null($value)) {
return $this->defaultValue($field);
}
+ if (is_numeric($value)) {
+ return strval($value);
+ }
if (!is_string($value)) {
throw new GPBDecodeException(
"String field only accepts string value");
diff --git a/php/tests/encode_decode_test.php b/php/tests/encode_decode_test.php
index 57b1bf1f5..1325db2cf 100644
--- a/php/tests/encode_decode_test.php
+++ b/php/tests/encode_decode_test.php
@@ -1148,4 +1148,14 @@ class EncodeDecodeTest extends TestBase
$m->serializeToJsonString());
}
+ public function testJsonDecodeNumericStringMapKey()
+ {
+ $m = new TestMessage();
+ $m->getMapStringString()["1"] = "1";
+ $data = $m->serializeToJsonString();
+ $this->assertSame("{\"mapStringString\":{\"1\":\"1\"}}", $data);
+ $n = new TestMessage();
+ $n->mergeFromJsonString($data);
+ }
+
}
diff --git a/php/tests/generated_class_test.php b/php/tests/generated_class_test.php
index 93b7b29bb..a9ad793be 100644
--- a/php/tests/generated_class_test.php
+++ b/php/tests/generated_class_test.php
@@ -1447,6 +1447,20 @@ class GeneratedClassTest extends TestBase
}
}
+ public function testOneofMessageInArrayConstructor()
+ {
+ $m = new TestMessage([
+ 'oneof_message' => new Sub(),
+ ]);
+ }
+
+ public function testOneofStringInArrayConstructor()
+ {
+ $m = new TestMessage([
+ 'oneof_string' => 'abc',
+ ]);
+ }
+
#########################################################
# Test message equals.
#########################################################