diff options
author | Bo Yang <teboring@google.com> | 2019-03-04 10:18:18 -0800 |
---|---|---|
committer | Bo Yang <teboring@google.com> | 2019-03-04 10:18:18 -0800 |
commit | cb6fa92ee8f924e8c524efdbe502858e97e6975d (patch) | |
tree | fd47f781115c7a55aac7538e652ce96b94a1a7af /php | |
parent | 50bd9f0a7c14ed7689fcb9f5885e9ffacf9b80a9 (diff) | |
parent | 582743bf40c5d3639a70f98f183914a2c0cd0680 (diff) | |
download | protobuf-cb6fa92ee8f924e8c524efdbe502858e97e6975d.tar.gz |
Merge branch '3.7.x'
Diffstat (limited to 'php')
-rw-r--r-- | php/ext/google/protobuf/def.c | 117 | ||||
-rw-r--r-- | php/ext/google/protobuf/encode_decode.c | 12 | ||||
-rw-r--r-- | php/ext/google/protobuf/message.c | 58 | ||||
-rw-r--r-- | php/ext/google/protobuf/package.xml | 50 | ||||
-rw-r--r-- | php/ext/google/protobuf/protobuf.h | 17 | ||||
-rw-r--r-- | php/release.sh | 37 | ||||
-rw-r--r-- | php/src/Google/Protobuf/Internal/Message.php | 3 | ||||
-rw-r--r-- | php/tests/encode_decode_test.php | 10 | ||||
-rw-r--r-- | php/tests/generated_class_test.php | 14 |
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. ######################################################### |