aboutsummaryrefslogtreecommitdiff
path: root/php/ext/google/protobuf/storage.c
diff options
context:
space:
mode:
authorPaul Yang <TeBoring@users.noreply.github.com>2017-07-14 15:48:48 -0600
committerGitHub <noreply@github.com>2017-07-14 15:48:48 -0600
commitc78dbd7c895b8c80cd2f2401d73acf890edf82c6 (patch)
tree98c59f78325ec539b843505a7e9389be97dc6035 /php/ext/google/protobuf/storage.c
parentec3f5dcc725c415cf6bbc8325adf731370a3507d (diff)
downloadprotobuf-c78dbd7c895b8c80cd2f2401d73acf890edf82c6.tar.gz
protobuf-c78dbd7c895b8c80cd2f2401d73acf890edf82c6.tar.bz2
protobuf-c78dbd7c895b8c80cd2f2401d73acf890edf82c6.zip
Initial value in generated code cannot be used by c extension. (#3367)
In the generated code of previous versions, each php field is given an initial value. In c extension, it was assumed that the field order in the generated code is consistent with upb fields order, so that the correct initial value can be bound to the correct upb field. However, this may not be true. The order of fields in generated code is decided by proto compiler, while the order of upb fields is decided by the hash function used in c extension. This PR fixes the issue by reset the initial value at runtime.
Diffstat (limited to 'php/ext/google/protobuf/storage.c')
-rw-r--r--php/ext/google/protobuf/storage.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/php/ext/google/protobuf/storage.c b/php/ext/google/protobuf/storage.c
index 29a3db86..c0e4da3e 100644
--- a/php/ext/google/protobuf/storage.c
+++ b/php/ext/google/protobuf/storage.c
@@ -210,7 +210,7 @@ bool native_slot_set_by_array(upb_fieldtype_t type,
return true;
}
-void native_slot_init(upb_fieldtype_t type, void* memory, void* cache) {
+void native_slot_init(upb_fieldtype_t type, void* memory, CACHED_VALUE* cache) {
zval* tmp = NULL;
switch (type) {
case UPB_TYPE_FLOAT:
@@ -224,6 +224,9 @@ void native_slot_init(upb_fieldtype_t type, void* memory, void* cache) {
break;
case UPB_TYPE_STRING:
case UPB_TYPE_BYTES:
+ DEREF(memory, CACHED_VALUE*) = cache;
+ ZVAL_EMPTY_STRING(CACHED_PTR_TO_ZVAL_PTR(cache));
+ break;
case UPB_TYPE_MESSAGE:
DEREF(memory, CACHED_VALUE*) = cache;
break;
@@ -621,6 +624,21 @@ void layout_init(MessageLayout* layout, void* storage,
int cache_index = slot_property_cache(layout, storage, field);
CACHED_VALUE* property_ptr = &properties_table[cache_index];
+ // Clean up initial value by generated code. In the generated code of
+ // previous versions, each php field is given an initial value. However, the
+ // order to initialize these fields may not be consistent with the order of
+ // upb fields.
+ if (Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(property_ptr)) == IS_STRING) {
+#if PHP_MAJOR_VERSION < 7
+ if (!IS_INTERNED(Z_STRVAL_PP(property_ptr))) {
+ FREE(Z_STRVAL_PP(property_ptr));
+ }
+#else
+ zend_string_release(Z_STR_P(property_ptr));
+#endif
+ }
+ ZVAL_NULL(CACHED_PTR_TO_ZVAL_PTR(property_ptr));
+
if (upb_fielddef_containingoneof(field)) {
memset(memory, 0, NATIVE_SLOT_MAX_SIZE);
*oneof_case = ONEOF_CASE_NONE;