Kaynağa Gözat

Make c extension portable for php 7.4 (#6968)

* Make c extension portable for php 7.4

* Fix conformance tests

* Fix comments

* Fix 32-bit

* Update conformance failure list

* Fix compiler warnings

* Cleanup configure created by phpize
The file created in php 7.4 is not recognizable by previous versions

* Fix conformance tests for 64-bit php

* Fix conformance test

* Fix compile warning

* Fix compile warnings
Paul Yang 5 yıl önce
ebeveyn
işleme
a66423f0fd

+ 2 - 2
conformance/Makefile.am

@@ -353,8 +353,8 @@ test_php: protoc_middleman conformance-test-runner conformance-php $(other_langu
 test_php_c: protoc_middleman conformance-test-runner conformance-php-c $(other_language_protoc_outputs)
 	./conformance-test-runner --enforce_recommended --failure_list failure_list_php_c.txt --text_format_failure_list text_format_failure_list_php.txt ./conformance-php-c
 
-test_php_zts_c: protoc_middleman conformance-test-runner conformance-php-c $(other_language_protoc_outputs)
-	./conformance-test-runner --enforce_recommended --failure_list failure_list_php_zts_c.txt --text_format_failure_list text_format_failure_list_php.txt ./conformance-php-c
+test_php_c_32: protoc_middleman conformance-test-runner conformance-php-c $(other_language_protoc_outputs)
+	./conformance-test-runner --enforce_recommended --failure_list failure_list_php_c_32.txt --text_format_failure_list text_format_failure_list_php.txt ./conformance-php-c
 
 # These depend on library paths being properly set up.  The easiest way to
 # run them is to just use "tox" from the python dir.

+ 0 - 1
conformance/failure_list_php.txt

@@ -64,7 +64,6 @@ Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOu
 Required.Proto3.JsonInput.DoubleFieldTooSmall
 Required.Proto3.JsonInput.FloatFieldTooLarge
 Required.Proto3.JsonInput.FloatFieldTooSmall
-Required.Proto3.JsonInput.Int32FieldLeadingSpace
 Required.Proto3.JsonInput.Int32FieldNotInteger
 Required.Proto3.JsonInput.Int64FieldNotInteger
 Required.Proto3.JsonInput.OneofFieldDuplicate

+ 31 - 31
conformance/failure_list_php_c.txt

@@ -18,33 +18,63 @@ Recommended.Proto3.JsonInput.TimestampHas3FractionalDigits.Validator
 Recommended.Proto3.JsonInput.TimestampHas6FractionalDigits.Validator
 Recommended.Proto3.ProtobufInput.OneofZeroBytes.JsonOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.UnpackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.UnpackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[3].ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[4].ProtobufOutput
 Required.DurationProtoInputTooLarge.JsonOutput
@@ -67,6 +97,7 @@ Required.Proto3.ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput
 Required.Proto3.ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput
 Required.Proto3.ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput
 Required.Proto3.ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput
+Required.Proto3.ProtobufInput.ValidDataOneof.BYTES.DefaultValue.JsonOutput
 Required.Proto3.ProtobufInput.ValidDataRepeated.BYTES.JsonOutput
 Required.Proto3.ProtobufInput.ValidDataRepeated.BYTES.ProtobufOutput
 Required.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.JsonOutput
@@ -76,34 +107,3 @@ Required.Proto3.ProtobufInput.ValidDataRepeated.STRING.ProtobufOutput
 Required.Proto3.ProtobufInput.ValidDataScalar.FLOAT[2].JsonOutput
 Required.TimestampProtoInputTooLarge.JsonOutput
 Required.TimestampProtoInputTooSmall.JsonOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput
-Required.Proto3.ProtobufInput.ValidDataOneof.BYTES.DefaultValue.JsonOutput

+ 142 - 0
conformance/failure_list_php_c_32.txt

@@ -0,0 +1,142 @@
+Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput
+Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
+Recommended.FieldMaskTooManyUnderscore.JsonOutput
+Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput
+Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput
+Recommended.Proto3.JsonInput.DurationHas3FractionalDigits.Validator
+Recommended.Proto3.JsonInput.DurationHas6FractionalDigits.Validator
+Recommended.Proto3.JsonInput.DurationHas9FractionalDigits.Validator
+Recommended.Proto3.JsonInput.DurationHasZeroFractionalDigit.Validator
+Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter
+Recommended.Proto3.JsonInput.MapFieldValueIsNull
+Recommended.Proto3.JsonInput.OneofZeroBytes.JsonOutput
+Recommended.Proto3.JsonInput.RepeatedFieldMessageElementIsNull
+Recommended.Proto3.JsonInput.RepeatedFieldPrimitiveElementIsNull
+Recommended.Proto3.JsonInput.StringEndsWithEscapeChar
+Recommended.Proto3.JsonInput.StringFieldSurrogateInWrongOrder
+Recommended.Proto3.JsonInput.StringFieldUnpairedHighSurrogate
+Recommended.Proto3.JsonInput.StringFieldUnpairedLowSurrogate
+Recommended.Proto3.JsonInput.TimestampHas3FractionalDigits.Validator
+Recommended.Proto3.JsonInput.TimestampHas6FractionalDigits.Validator
+Recommended.Proto3.JsonInput.TimestampHas9FractionalDigits.Validator
+Recommended.Proto3.JsonInput.TimestampHasZeroFractionalDigit.Validator
+Recommended.Proto3.JsonInput.TimestampZeroNormalized.Validator
+Recommended.Proto3.ProtobufInput.OneofZeroBytes.JsonOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.UnpackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.UnpackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.DefaultOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[3].ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[4].ProtobufOutput
+Required.DurationProtoInputTooLarge.JsonOutput
+Required.DurationProtoInputTooSmall.JsonOutput
+Required.Proto3.JsonInput.DoubleFieldMaxNegativeValue.JsonOutput
+Required.Proto3.JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput
+Required.Proto3.JsonInput.DoubleFieldMinPositiveValue.JsonOutput
+Required.Proto3.JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput
+Required.Proto3.JsonInput.DoubleFieldNan.JsonOutput
+Required.Proto3.JsonInput.DurationMaxValue.JsonOutput
+Required.Proto3.JsonInput.DurationMaxValue.ProtobufOutput
+Required.Proto3.JsonInput.DurationMinValue.JsonOutput
+Required.Proto3.JsonInput.DurationMinValue.ProtobufOutput
+Required.Proto3.JsonInput.DurationRepeatedValue.JsonOutput
+Required.Proto3.JsonInput.DurationRepeatedValue.ProtobufOutput
+Required.Proto3.JsonInput.FloatFieldInfinity.JsonOutput
+Required.Proto3.JsonInput.FloatFieldNan.JsonOutput
+Required.Proto3.JsonInput.FloatFieldNegativeInfinity.JsonOutput
+Required.Proto3.JsonInput.Int64FieldMaxValue.JsonOutput
+Required.Proto3.JsonInput.Int64FieldMaxValue.ProtobufOutput
+Required.Proto3.JsonInput.Int64FieldMaxValueNotQuoted.JsonOutput
+Required.Proto3.JsonInput.Int64FieldMaxValueNotQuoted.ProtobufOutput
+Required.Proto3.JsonInput.Int64FieldMinValue.JsonOutput
+Required.Proto3.JsonInput.Int64FieldMinValue.ProtobufOutput
+Required.Proto3.JsonInput.Int64FieldMinValueNotQuoted.JsonOutput
+Required.Proto3.JsonInput.Int64FieldMinValueNotQuoted.ProtobufOutput
+Required.Proto3.JsonInput.OneofFieldDuplicate
+Required.Proto3.JsonInput.RejectTopLevelNull
+Required.Proto3.JsonInput.StringFieldSurrogatePair.JsonOutput
+Required.Proto3.JsonInput.StringFieldSurrogatePair.ProtobufOutput
+Required.Proto3.JsonInput.TimestampLeap.JsonOutput
+Required.Proto3.JsonInput.TimestampLeap.ProtobufOutput
+Required.Proto3.JsonInput.TimestampMaxValue.JsonOutput
+Required.Proto3.JsonInput.TimestampMaxValue.ProtobufOutput
+Required.Proto3.JsonInput.TimestampMinValue.JsonOutput
+Required.Proto3.JsonInput.TimestampMinValue.ProtobufOutput
+Required.Proto3.JsonInput.TimestampRepeatedValue.JsonOutput
+Required.Proto3.JsonInput.TimestampRepeatedValue.ProtobufOutput
+Required.Proto3.JsonInput.TimestampWithNegativeOffset.JsonOutput
+Required.Proto3.JsonInput.TimestampWithNegativeOffset.ProtobufOutput
+Required.Proto3.JsonInput.TimestampWithPositiveOffset.JsonOutput
+Required.Proto3.JsonInput.TimestampWithPositiveOffset.ProtobufOutput
+Required.Proto3.JsonInput.Uint64FieldMaxValue.JsonOutput
+Required.Proto3.JsonInput.Uint64FieldMaxValue.ProtobufOutput
+Required.Proto3.JsonInput.Uint64FieldMaxValueNotQuoted.JsonOutput
+Required.Proto3.JsonInput.Uint64FieldMaxValueNotQuoted.ProtobufOutput
+Required.Proto3.ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput
+Required.Proto3.ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput
+Required.Proto3.ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput
+Required.Proto3.ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput
+Required.Proto3.ProtobufInput.ValidDataOneof.BYTES.DefaultValue.JsonOutput
+Required.Proto3.ProtobufInput.ValidDataRepeated.BYTES.JsonOutput
+Required.Proto3.ProtobufInput.ValidDataRepeated.BYTES.ProtobufOutput
+Required.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.JsonOutput
+Required.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.JsonOutput
+Required.Proto3.ProtobufInput.ValidDataRepeated.STRING.JsonOutput
+Required.Proto3.ProtobufInput.ValidDataRepeated.STRING.ProtobufOutput
+Required.Proto3.ProtobufInput.ValidDataScalar.FLOAT[2].JsonOutput
+Required.TimestampProtoInputTooLarge.JsonOutput
+Required.TimestampProtoInputTooSmall.JsonOutput

+ 0 - 225
conformance/failure_list_php_zts_c.txt

@@ -1,225 +0,0 @@
-Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput
-Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
-Recommended.FieldMaskTooManyUnderscore.JsonOutput
-Recommended.JsonInput.BoolFieldIntegerOne
-Recommended.JsonInput.BoolFieldIntegerZero
-Recommended.JsonInput.DurationHas3FractionalDigits.Validator
-Recommended.JsonInput.DurationHas6FractionalDigits.Validator
-Recommended.JsonInput.DurationHas9FractionalDigits.Validator
-Recommended.JsonInput.DurationHasZeroFractionalDigit.Validator
-Recommended.JsonInput.Int64FieldBeString.Validator
-Recommended.JsonInput.OneofZeroBytes.JsonOutput
-Recommended.JsonInput.OneofZeroBytes.ProtobufOutput
-Recommended.JsonInput.OneofZeroDouble.JsonOutput
-Recommended.JsonInput.OneofZeroDouble.ProtobufOutput
-Recommended.JsonInput.OneofZeroFloat.JsonOutput
-Recommended.JsonInput.OneofZeroFloat.ProtobufOutput
-Recommended.JsonInput.OneofZeroString.JsonOutput
-Recommended.JsonInput.OneofZeroString.ProtobufOutput
-Recommended.JsonInput.OneofZeroUint32.JsonOutput
-Recommended.JsonInput.OneofZeroUint32.ProtobufOutput
-Recommended.JsonInput.OneofZeroUint64.JsonOutput
-Recommended.JsonInput.OneofZeroUint64.ProtobufOutput
-Recommended.JsonInput.StringEndsWithEscapeChar
-Recommended.JsonInput.StringFieldSurrogateInWrongOrder
-Recommended.JsonInput.StringFieldUnpairedHighSurrogate
-Recommended.JsonInput.StringFieldUnpairedLowSurrogate
-Recommended.JsonInput.TimestampHas3FractionalDigits.Validator
-Recommended.JsonInput.TimestampHas6FractionalDigits.Validator
-Recommended.JsonInput.TimestampHas9FractionalDigits.Validator
-Recommended.JsonInput.TimestampHasZeroFractionalDigit.Validator
-Recommended.JsonInput.TimestampZeroNormalized.Validator
-Recommended.JsonInput.Uint64FieldBeString.Validator
-Recommended.ProtobufInput.OneofZeroBytes.JsonOutput
-Recommended.ProtobufInput.OneofZeroBytes.ProtobufOutput
-Recommended.ProtobufInput.OneofZeroString.JsonOutput
-Recommended.ProtobufInput.OneofZeroString.ProtobufOutput
-Required.DurationProtoInputTooLarge.JsonOutput
-Required.DurationProtoInputTooSmall.JsonOutput
-Required.JsonInput.AllFieldAcceptNull.ProtobufOutput
-Required.JsonInput.Any.JsonOutput
-Required.JsonInput.Any.ProtobufOutput
-Required.JsonInput.AnyNested.JsonOutput
-Required.JsonInput.AnyNested.ProtobufOutput
-Required.JsonInput.AnyUnorderedTypeTag.JsonOutput
-Required.JsonInput.AnyUnorderedTypeTag.ProtobufOutput
-Required.JsonInput.AnyWithDuration.JsonOutput
-Required.JsonInput.AnyWithDuration.ProtobufOutput
-Required.JsonInput.AnyWithFieldMask.JsonOutput
-Required.JsonInput.AnyWithFieldMask.ProtobufOutput
-Required.JsonInput.AnyWithInt32ValueWrapper.JsonOutput
-Required.JsonInput.AnyWithInt32ValueWrapper.ProtobufOutput
-Required.JsonInput.AnyWithStruct.JsonOutput
-Required.JsonInput.AnyWithStruct.ProtobufOutput
-Required.JsonInput.AnyWithTimestamp.JsonOutput
-Required.JsonInput.AnyWithTimestamp.ProtobufOutput
-Required.JsonInput.AnyWithValueForInteger.JsonOutput
-Required.JsonInput.AnyWithValueForInteger.ProtobufOutput
-Required.JsonInput.AnyWithValueForJsonObject.JsonOutput
-Required.JsonInput.AnyWithValueForJsonObject.ProtobufOutput
-Required.JsonInput.BoolFieldFalse.ProtobufOutput
-Required.JsonInput.BoolMapField.JsonOutput
-Required.JsonInput.DoubleFieldInfinity.JsonOutput
-Required.JsonInput.DoubleFieldInfinity.ProtobufOutput
-Required.JsonInput.DoubleFieldMaxNegativeValue.JsonOutput
-Required.JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput
-Required.JsonInput.DoubleFieldMaxPositiveValue.JsonOutput
-Required.JsonInput.DoubleFieldMaxPositiveValue.ProtobufOutput
-Required.JsonInput.DoubleFieldMinNegativeValue.JsonOutput
-Required.JsonInput.DoubleFieldMinNegativeValue.ProtobufOutput
-Required.JsonInput.DoubleFieldMinPositiveValue.JsonOutput
-Required.JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput
-Required.JsonInput.DoubleFieldNan.JsonOutput
-Required.JsonInput.DoubleFieldNan.ProtobufOutput
-Required.JsonInput.DoubleFieldNegativeInfinity.JsonOutput
-Required.JsonInput.DoubleFieldNegativeInfinity.ProtobufOutput
-Required.JsonInput.DoubleFieldQuotedValue.JsonOutput
-Required.JsonInput.DoubleFieldQuotedValue.ProtobufOutput
-Required.JsonInput.DurationMaxValue.JsonOutput
-Required.JsonInput.DurationMaxValue.ProtobufOutput
-Required.JsonInput.DurationMinValue.JsonOutput
-Required.JsonInput.DurationMinValue.ProtobufOutput
-Required.JsonInput.DurationRepeatedValue.JsonOutput
-Required.JsonInput.DurationRepeatedValue.ProtobufOutput
-Required.JsonInput.EnumField.ProtobufOutput
-Required.JsonInput.EnumFieldNumericValueNonZero.JsonOutput
-Required.JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput
-Required.JsonInput.EnumFieldNumericValueZero.JsonOutput
-Required.JsonInput.EnumFieldNumericValueZero.ProtobufOutput
-Required.JsonInput.EnumFieldUnknownValue.Validator
-Required.JsonInput.FieldMask.JsonOutput
-Required.JsonInput.FieldMask.ProtobufOutput
-Required.JsonInput.FloatFieldInfinity.JsonOutput
-Required.JsonInput.FloatFieldInfinity.ProtobufOutput
-Required.JsonInput.FloatFieldNan.JsonOutput
-Required.JsonInput.FloatFieldNan.ProtobufOutput
-Required.JsonInput.FloatFieldNegativeInfinity.JsonOutput
-Required.JsonInput.FloatFieldNegativeInfinity.ProtobufOutput
-Required.JsonInput.FloatFieldQuotedValue.JsonOutput
-Required.JsonInput.FloatFieldQuotedValue.ProtobufOutput
-Required.JsonInput.FloatFieldTooLarge
-Required.JsonInput.FloatFieldTooSmall
-Required.JsonInput.Int32FieldExponentialFormat.JsonOutput
-Required.JsonInput.Int32FieldExponentialFormat.ProtobufOutput
-Required.JsonInput.Int32FieldFloatTrailingZero.JsonOutput
-Required.JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput
-Required.JsonInput.Int32FieldMaxFloatValue.JsonOutput
-Required.JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
-Required.JsonInput.Int32FieldMinFloatValue.JsonOutput
-Required.JsonInput.Int32FieldMinFloatValue.ProtobufOutput
-Required.JsonInput.Int32FieldStringValue.JsonOutput
-Required.JsonInput.Int32FieldStringValue.ProtobufOutput
-Required.JsonInput.Int32FieldStringValueEscaped.JsonOutput
-Required.JsonInput.Int32FieldStringValueEscaped.ProtobufOutput
-Required.JsonInput.Int32MapEscapedKey.JsonOutput
-Required.JsonInput.Int32MapEscapedKey.ProtobufOutput
-Required.JsonInput.Int32MapField.JsonOutput
-Required.JsonInput.Int32MapField.ProtobufOutput
-Required.JsonInput.Int64FieldMaxValue.JsonOutput
-Required.JsonInput.Int64FieldMaxValue.ProtobufOutput
-Required.JsonInput.Int64FieldMinValue.JsonOutput
-Required.JsonInput.Int64FieldMinValue.ProtobufOutput
-Required.JsonInput.Int64MapEscapedKey.JsonOutput
-Required.JsonInput.Int64MapEscapedKey.ProtobufOutput
-Required.JsonInput.Int64MapField.JsonOutput
-Required.JsonInput.Int64MapField.ProtobufOutput
-Required.JsonInput.MessageField.JsonOutput
-Required.JsonInput.MessageField.ProtobufOutput
-Required.JsonInput.MessageMapField.JsonOutput
-Required.JsonInput.MessageMapField.ProtobufOutput
-Required.JsonInput.MessageRepeatedField.JsonOutput
-Required.JsonInput.MessageRepeatedField.ProtobufOutput
-Required.JsonInput.OptionalBoolWrapper.JsonOutput
-Required.JsonInput.OptionalBoolWrapper.ProtobufOutput
-Required.JsonInput.OptionalBytesWrapper.JsonOutput
-Required.JsonInput.OptionalBytesWrapper.ProtobufOutput
-Required.JsonInput.OptionalDoubleWrapper.JsonOutput
-Required.JsonInput.OptionalDoubleWrapper.ProtobufOutput
-Required.JsonInput.OptionalFloatWrapper.JsonOutput
-Required.JsonInput.OptionalFloatWrapper.ProtobufOutput
-Required.JsonInput.OptionalInt32Wrapper.JsonOutput
-Required.JsonInput.OptionalInt32Wrapper.ProtobufOutput
-Required.JsonInput.OptionalInt64Wrapper.JsonOutput
-Required.JsonInput.OptionalInt64Wrapper.ProtobufOutput
-Required.JsonInput.OptionalStringWrapper.JsonOutput
-Required.JsonInput.OptionalStringWrapper.ProtobufOutput
-Required.JsonInput.OptionalUint32Wrapper.JsonOutput
-Required.JsonInput.OptionalUint32Wrapper.ProtobufOutput
-Required.JsonInput.OptionalUint64Wrapper.JsonOutput
-Required.JsonInput.OptionalUint64Wrapper.ProtobufOutput
-Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput
-Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput
-Required.JsonInput.PrimitiveRepeatedField.JsonOutput
-Required.JsonInput.PrimitiveRepeatedField.ProtobufOutput
-Required.JsonInput.RepeatedBoolWrapper.JsonOutput
-Required.JsonInput.RepeatedBoolWrapper.ProtobufOutput
-Required.JsonInput.RepeatedBytesWrapper.JsonOutput
-Required.JsonInput.RepeatedBytesWrapper.ProtobufOutput
-Required.JsonInput.RepeatedDoubleWrapper.JsonOutput
-Required.JsonInput.RepeatedDoubleWrapper.ProtobufOutput
-Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
-Required.JsonInput.RepeatedFloatWrapper.JsonOutput
-Required.JsonInput.RepeatedFloatWrapper.ProtobufOutput
-Required.JsonInput.RepeatedInt32Wrapper.JsonOutput
-Required.JsonInput.RepeatedInt32Wrapper.ProtobufOutput
-Required.JsonInput.RepeatedInt64Wrapper.JsonOutput
-Required.JsonInput.RepeatedInt64Wrapper.ProtobufOutput
-Required.JsonInput.RepeatedStringWrapper.JsonOutput
-Required.JsonInput.RepeatedStringWrapper.ProtobufOutput
-Required.JsonInput.RepeatedUint32Wrapper.JsonOutput
-Required.JsonInput.RepeatedUint32Wrapper.ProtobufOutput
-Required.JsonInput.RepeatedUint64Wrapper.JsonOutput
-Required.JsonInput.RepeatedUint64Wrapper.ProtobufOutput
-Required.JsonInput.StringFieldEscape.JsonOutput
-Required.JsonInput.StringFieldEscape.ProtobufOutput
-Required.JsonInput.StringFieldNotAString
-Required.JsonInput.StringFieldSurrogatePair.JsonOutput
-Required.JsonInput.StringFieldSurrogatePair.ProtobufOutput
-Required.JsonInput.StringFieldUnicodeEscape.JsonOutput
-Required.JsonInput.StringFieldUnicodeEscape.ProtobufOutput
-Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.JsonOutput
-Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.ProtobufOutput
-Required.JsonInput.Struct.JsonOutput
-Required.JsonInput.Struct.ProtobufOutput
-Required.JsonInput.TimestampMaxValue.JsonOutput
-Required.JsonInput.TimestampMaxValue.ProtobufOutput
-Required.JsonInput.TimestampMinValue.JsonOutput
-Required.JsonInput.TimestampMinValue.ProtobufOutput
-Required.JsonInput.TimestampRepeatedValue.JsonOutput
-Required.JsonInput.TimestampRepeatedValue.ProtobufOutput
-Required.JsonInput.TimestampWithNegativeOffset.JsonOutput
-Required.JsonInput.TimestampWithNegativeOffset.ProtobufOutput
-Required.JsonInput.TimestampWithPositiveOffset.JsonOutput
-Required.JsonInput.TimestampWithPositiveOffset.ProtobufOutput
-Required.JsonInput.Uint32FieldMaxFloatValue.JsonOutput
-Required.JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput
-Required.JsonInput.Uint32MapField.JsonOutput
-Required.JsonInput.Uint32MapField.ProtobufOutput
-Required.JsonInput.Uint64FieldMaxValue.JsonOutput
-Required.JsonInput.Uint64FieldMaxValue.ProtobufOutput
-Required.JsonInput.Uint64MapField.JsonOutput
-Required.JsonInput.Uint64MapField.ProtobufOutput
-Required.JsonInput.ValueAcceptBool.JsonOutput
-Required.JsonInput.ValueAcceptBool.ProtobufOutput
-Required.JsonInput.ValueAcceptFloat.JsonOutput
-Required.JsonInput.ValueAcceptFloat.ProtobufOutput
-Required.JsonInput.ValueAcceptInteger.JsonOutput
-Required.JsonInput.ValueAcceptInteger.ProtobufOutput
-Required.JsonInput.ValueAcceptList.JsonOutput
-Required.JsonInput.ValueAcceptList.ProtobufOutput
-Required.JsonInput.ValueAcceptNull.JsonOutput
-Required.JsonInput.ValueAcceptNull.ProtobufOutput
-Required.JsonInput.ValueAcceptObject.JsonOutput
-Required.JsonInput.ValueAcceptObject.ProtobufOutput
-Required.JsonInput.ValueAcceptString.JsonOutput
-Required.JsonInput.ValueAcceptString.ProtobufOutput
-Required.JsonInput.WrapperTypesWithNullValue.ProtobufOutput
-Required.ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput
-Required.ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput
-Required.ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput
-Required.ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.ProtobufOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.ProtobufOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.UINT64.ProtobufOutput
-Required.TimestampProtoInputTooLarge.JsonOutput
-Required.TimestampProtoInputTooSmall.JsonOutput

+ 6 - 7
php/ext/google/protobuf/array.c

@@ -73,7 +73,6 @@ static int repeated_field_array_init(zval *array, upb_fieldtype_t type,
                                      uint size ZEND_FILE_LINE_DC);
 static void repeated_field_write_dimension(zval *object, zval *offset,
                                            zval *value TSRMLS_DC);
-static int repeated_field_has_dimension(zval *object, zval *offset TSRMLS_DC);
 static HashTable *repeated_field_get_gc(zval *object, CACHED_VALUE **table,
                                         int *n TSRMLS_DC);
 #if PHP_MAJOR_VERSION < 7
@@ -102,7 +101,7 @@ php_proto_zval_ptr_dtor(&intern->array);
 #endif
 PHP_PROTO_OBJECT_FREE_END
 
-PHP_PROTO_OBJECT_DTOR_START(RepeatedField, repeated_field)
+PHP_PROTO_OBJECT_EMPTY_DTOR_START(RepeatedField, repeated_field)
 PHP_PROTO_OBJECT_DTOR_END
 
 // Define object create method.
@@ -488,10 +487,10 @@ PHP_METHOD(RepeatedField, getIterator) {
 // -----------------------------------------------------------------------------
 
 // Define object free method.
-PHP_PROTO_OBJECT_FREE_START(RepeatedFieldIter, repeated_field_iter)
+PHP_PROTO_OBJECT_EMPTY_FREE_START(RepeatedFieldIter, repeated_field_iter)
 PHP_PROTO_OBJECT_FREE_END
 
-PHP_PROTO_OBJECT_DTOR_START(RepeatedFieldIter, repeated_field_iter)
+PHP_PROTO_OBJECT_EMPTY_DTOR_START(RepeatedFieldIter, repeated_field_iter)
 PHP_PROTO_OBJECT_DTOR_END
 
 // Define object create method.
@@ -519,7 +518,7 @@ PHP_METHOD(RepeatedFieldIter, current) {
   RepeatedFieldIter *intern = UNBOX(RepeatedFieldIter, getThis());
   RepeatedField *repeated_field = intern->repeated_field;
 
-  long index;
+  long index = 0;
   void *memory;
 
   HashTable *table = PHP_PROTO_HASH_OF(repeated_field->array);
@@ -527,13 +526,13 @@ PHP_METHOD(RepeatedFieldIter, current) {
   if (repeated_field->type == UPB_TYPE_MESSAGE) {
     if (php_proto_zend_hash_index_find_zval(table, intern->position,
                                             (void **)&memory) == FAILURE) {
-      zend_error(E_USER_ERROR, "Element at %d doesn't exist.\n", index);
+      zend_error(E_USER_ERROR, "Element at %ld doesn't exist.\n", index);
       return;
     }
   } else {
     if (php_proto_zend_hash_index_find_mem(table, intern->position,
                                            (void **)&memory) == FAILURE) {
-      zend_error(E_USER_ERROR, "Element at %d doesn't exist.\n", index);
+      zend_error(E_USER_ERROR, "Element at %ld doesn't exist.\n", index);
       return;
     }
   }

+ 3 - 110
php/ext/google/protobuf/def.c

@@ -69,31 +69,6 @@ static void check_upb_status(const upb_status* status, const char* msg) {
   }
 }
 
-// Camel-case the field name and append "Entry" for generated map entry name.
-// e.g. map<KeyType, ValueType> foo_map => FooMapEntry
-static void append_map_entry_name(char *result, const char *field_name,
-                                  int pos) {
-  bool cap_next = true;
-  int i;
-
-  for (i = 0; i < strlen(field_name); ++i) {
-    if (field_name[i] == '_') {
-      cap_next = true;
-    } else if (cap_next) {
-      // Note: Do not use ctype.h due to locales.
-      if ('a' <= field_name[i] && field_name[i] <= 'z') {
-        result[pos++] = field_name[i] - 'a' + 'A';
-      } else {
-        result[pos++] = field_name[i];
-      }
-      cap_next = false;
-    } else {
-      result[pos++] = field_name[i];
-    }
-  }
-  strcat(result, "Entry");
-}
-
 // -----------------------------------------------------------------------------
 // GPBType
 // -----------------------------------------------------------------------------
@@ -682,29 +657,6 @@ static void descriptor_pool_init_c_instance(DescriptorPool *pool TSRMLS_DC) {
 static void descriptor_pool_free_c(DescriptorPool *pool TSRMLS_DC) {
 }
 
-static void validate_enumdef(const upb_enumdef *enumdef) {
-  // Verify that an entry exists with integer value 0. (This is the default
-  // value.)
-  const char *lookup = upb_enumdef_iton(enumdef, 0);
-  if (lookup == NULL) {
-    zend_error(E_USER_ERROR,
-               "Enum definition does not contain a value for '0'.");
-  }
-}
-
-static void validate_msgdef(const upb_msgdef* msgdef) {
-  // Verify that no required fields exist. proto3 does not support these.
-  upb_msg_field_iter it;
-  for (upb_msg_field_begin(&it, msgdef);
-       !upb_msg_field_done(&it);
-       upb_msg_field_next(&it)) {
-    const upb_fielddef* field = upb_msg_iter_field(&it);
-    if (upb_fielddef_label(field) == UPB_LABEL_REQUIRED) {
-      zend_error(E_ERROR, "Required fields are unsupported in proto3.");
-    }
-  }
-}
-
 PHP_METHOD(DescriptorPool, getGeneratedPool) {
   init_generated_pool_once(TSRMLS_C);
 #if PHP_MAJOR_VERSION < 7
@@ -725,58 +677,6 @@ PHP_METHOD(InternalDescriptorPool, getGeneratedPool) {
 #endif
 }
 
-static size_t classname_len_max(const char *fullname,
-                                const char *package,
-                                const char *php_namespace,
-                                const char *prefix) {
-  size_t fullname_len = strlen(fullname);
-  size_t package_len = 0;
-  size_t prefix_len = 0;
-  size_t namespace_len = 0;
-  size_t length = fullname_len;
-  int i, segment, classname_start = 0;
-
-  if (package != NULL) {
-    package_len = strlen(package);
-  }
-  if (prefix != NULL) {
-    prefix_len = strlen(prefix);
-  }
-  if (php_namespace != NULL) {
-    namespace_len = strlen(php_namespace);
-  }
-
-  // Process package
-  if (package_len > 0) {
-    segment = 1;
-    for (i = 0; i < package_len; i++) {
-      if (package[i] == '.') {
-        segment++;
-      }
-    }
-    // In case of reserved name in package.
-    length += 3 * segment;
-
-    classname_start = package_len + 1;
-  }
-
-  // Process class name
-  segment = 1;
-  for (i = classname_start; i < fullname_len; i++) {
-    if (fullname[i] == '.') {
-      segment++;
-    }
-  }
-  if (prefix_len == 0) {
-    length += 3 * segment;
-  } else {
-    length += prefix_len * segment;
-  }
-
-  // The additional 2, one is for preceding '.' and the other is for trailing 0.
-  return length + namespace_len + 2;
-}
-
 static bool is_reserved(const char *segment, int length) {
   bool result;
   char* lower = ALLOC_N(char, length + 1);
@@ -797,8 +697,6 @@ 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) {
     stringsink_string(classname, NULL, prefix_given,
                       strlen(prefix_given), NULL);
@@ -834,7 +732,7 @@ static void fill_namespace(const char *package, const char *php_namespace,
       stringsink_string(classname, NULL, "\\", 1, NULL);
     }
   } else if (package != NULL) {
-    int i = 0, j, offset = 0;
+    int i = 0, j = 0;
     size_t package_len = strlen(package);
     while (i < package_len) {
       j = i;
@@ -868,7 +766,7 @@ static void fill_classname(const char *fullname,
     while (j < fullname_len && fullname[j] != '.') {
       j++;
     }
-    if (use_nested_submsg || is_first_segment && j == fullname_len) {
+    if (use_nested_submsg || (is_first_segment && j == fullname_len)) {
       fill_prefix(fullname + i, j - i, prefix, package, classname);
     }
     is_first_segment = false;
@@ -907,9 +805,6 @@ static void fill_classname_for_desc(void *desc, bool is_enum) {
   const char *package = upb_filedef_package(file);
   const char *php_namespace = upb_filedef_phpnamespace(file);
   const char *prefix = upb_filedef_phpprefix(file);
-  size_t classname_len =
-      classname_len_max(fullname, package, php_namespace, prefix);
-  char* after_package;
   stringsink namesink;
   stringsink_init(&namesink);
 
@@ -958,7 +853,7 @@ void register_class(void *desc, bool is_enum TSRMLS_DC) {
     zend_error(
         E_ERROR,
         "Generated message class %s hasn't been defined (%s)",
-        classname);
+        classname, fullname);
     return;
   }
   ret = PHP_PROTO_CE_UNREF(pce);
@@ -1107,9 +1002,7 @@ void internal_add_generated_file(const char *data, PHP_PROTO_SIZE data_len,
 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|b",
                             &data, &data_len, &use_nested_submsg) ==

+ 2 - 46
php/ext/google/protobuf/encode_decode.c

@@ -333,25 +333,6 @@ DEFINE_SINGULAR_HANDLER(double, double)
 
 #undef DEFINE_SINGULAR_HANDLER
 
-#if PHP_MAJOR_VERSION < 7
-static void *empty_php_string(zval** value_ptr) {
-  SEPARATE_ZVAL_IF_NOT_REF(value_ptr);
-  if (Z_TYPE_PP(value_ptr) == IS_STRING &&
-      !IS_INTERNED(Z_STRVAL_PP(value_ptr))) {
-    FREE(Z_STRVAL_PP(value_ptr));
-  }
-  ZVAL_EMPTY_STRING(*value_ptr);
-  return (void*)(*value_ptr);
-}
-#else
-static void *empty_php_string(zval* value_ptr) {
-  if (Z_TYPE_P(value_ptr) == IS_STRING) {
-    zend_string_release(Z_STR_P(value_ptr));
-  }
-  ZVAL_EMPTY_STRING(value_ptr);
-  return value_ptr;
-}
-#endif
 #if PHP_MAJOR_VERSION < 7
 static void new_php_string(zval** value_ptr, const char* str, size_t len) {
   SEPARATE_ZVAL_IF_NOT_REF(value_ptr);
@@ -830,7 +811,6 @@ static map_handlerdata_t* new_map_handlerdata(
   static bool oneof##type##_handler(void* closure, const void* hd, \
                                     ctype val) {                   \
     const oneof_handlerdata_t* oneofdata = hd;                     \
-    MessageHeader* msg = (MessageHeader*)closure;                  \
     DEREF(message_data(closure), oneofdata->case_ofs, uint32_t) =  \
         oneofdata->oneof_case_num;                                 \
     DEREF(message_data(closure), oneofdata->ofs, ctype) = val;     \
@@ -886,22 +866,6 @@ static void oneof_cleanup(MessageHeader* msg,
 }
 
 // Handlers for string/bytes in a oneof.
-static void *oneofbytes_handler(void *closure,
-                                const void *hd,
-                                size_t size_hint) {
-  MessageHeader* msg = closure;
-  const oneof_handlerdata_t *oneofdata = hd;
-
-  oneof_cleanup(msg, oneofdata);
-
-  DEREF(message_data(msg), oneofdata->case_ofs, uint32_t) =
-      oneofdata->oneof_case_num;
-  DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*) =
-      OBJ_PROP(&msg->std, oneofdata->property_ofs);
-
-   return empty_php_string(DEREF(
-       message_data(msg), oneofdata->ofs, CACHED_VALUE*));
-}
 static bool oneofstr_end_handler(void *closure, const void *hd) {
   stringfields_parseframe_t* frame = closure;
   MessageHeader* msg = (MessageHeader*)frame->closure;
@@ -984,7 +948,6 @@ static void* wrapper_submsg_handler(void* closure, const void* hd) {
   TSRMLS_FETCH();
   DescriptorInternal* subdesc = get_msgdef_desc(submsgdata->md);
   register_class(subdesc, false TSRMLS_CC);
-  zend_class_entry* subklass = subdesc->klass;
   zval* submsg_php;
   MessageHeader* submsg;
   wrapperfields_parseframe_t* frame =
@@ -1022,7 +985,6 @@ static void* wrapper_oneofsubmsg_handler(void* closure, const void* hd) {
   TSRMLS_FETCH();
   DescriptorInternal* subdesc = get_msgdef_desc(oneofdata->md);
   register_class(subdesc, false TSRMLS_CC);
-  zend_class_entry* subklass = subdesc->klass;
   wrapperfields_parseframe_t* frame =
       (wrapperfields_parseframe_t*)malloc(sizeof(wrapperfields_parseframe_t));
   CACHED_VALUE* cached = OBJ_PROP(&msg->std, oneofdata->property_ofs);
@@ -1688,11 +1650,10 @@ static void putjsonlistvalue(
   upb_status status;
   upb_sink subsink;
   const upb_fielddef* f = upb_msgdef_itof(desc->msgdef, 1);
-  uint32_t offset = desc->layout->fields[upb_fielddef_index(f)].offset;
   zval* array;
   RepeatedField* intern;
   HashTable *ht;
-  int size, i;
+  int size;
 
   upb_sink_startmsg(sink);
 
@@ -1722,7 +1683,6 @@ static void putjsonstruct(
   upb_status status;
   upb_sink subsink;
   const upb_fielddef* f = upb_msgdef_itof(desc->msgdef, 1);
-  uint32_t offset = desc->layout->fields[upb_fielddef_index(f)].offset;
   zval* map;
   Map* intern;
   int size;
@@ -2247,8 +2207,6 @@ static void discard_unknown_fields(MessageHeader* msg) {
        !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 =
@@ -2261,12 +2219,11 @@ static void discard_unknown_fields(MessageHeader* msg) {
       }
       // Otherwise, fall through to the appropriate singular-field handler
       // below.
-      containing_oneof = true;
     }
 
     if (is_map_field(f)) {
       MapIter map_it;
-      int len, size;
+      int len;
       const upb_fielddef* value_field;
 
       value_field = map_field_value(f);
@@ -2275,7 +2232,6 @@ static void discard_unknown_fields(MessageHeader* msg) {
       zval* map_php = CACHED_PTR_TO_ZVAL_PTR(find_zval_property(msg, f));
       if (ZVAL_IS_NULL(map_php)) 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);

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

@@ -222,7 +222,7 @@ for (map_begin_internal(intern, &it); !map_done(&it); map_next(&it)) {
 upb_strtable_uninit(&intern->table);
 PHP_PROTO_OBJECT_FREE_END
 
-PHP_PROTO_OBJECT_DTOR_START(Map, map_field)
+PHP_PROTO_OBJECT_EMPTY_DTOR_START(Map, map_field)
 PHP_PROTO_OBJECT_DTOR_END
 
 // Define object create method.
@@ -383,7 +383,6 @@ static bool map_field_unset_dimension(zval *object, zval *key TSRMLS_DC) {
   char keybuf[TABLE_KEY_BUF_LENGTH];
   const char* keyval = NULL;
   size_t length = 0;
-  upb_value v;
   if (!table_key(intern, key, keybuf, &keyval, &length TSRMLS_CC)) {
     return false;
   }
@@ -454,7 +453,7 @@ PHP_METHOD(MapField, offsetExists) {
 }
 
 PHP_METHOD(MapField, offsetGet) {
-  zval *index, *value;
+  zval *index;
   if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &index) ==
       FAILURE) {
     return;
@@ -495,7 +494,6 @@ PHP_METHOD(MapField, getIterator) {
   CREATE_OBJ_ON_ALLOCATED_ZVAL_PTR(return_value,
                                    map_field_iter_type);
 
-  Map *intern = UNBOX(Map, getThis());
   MapIter *iter = UNBOX(MapIter, return_value);
   map_begin(getThis(), iter TSRMLS_CC);
 }
@@ -544,10 +542,10 @@ static zend_function_entry map_field_iter_methods[] = {
 // -----------------------------------------------------------------------------
 
 // Define object free method.
-PHP_PROTO_OBJECT_FREE_START(MapIter, map_field_iter)
+PHP_PROTO_OBJECT_EMPTY_FREE_START(MapIter, map_field_iter)
 PHP_PROTO_OBJECT_FREE_END
 
-PHP_PROTO_OBJECT_DTOR_START(MapIter, map_field_iter)
+PHP_PROTO_OBJECT_EMPTY_DTOR_START(MapIter, map_field_iter)
 PHP_PROTO_OBJECT_DTOR_END
 
 // Define object create method.

+ 40 - 32
php/ext/google/protobuf/message.c

@@ -75,8 +75,13 @@ static zval** message_get_property_ptr_ptr(zval* object, zval* member, int type,
                                            php_proto_zend_literal key TSRMLS_DC);
 static HashTable* message_get_gc(zval* object, zval*** table, int* n TSRMLS_DC);
 #else
+#if PHP_VERSION_ID < 70400
 static void message_set_property(zval* object, zval* member, zval* value,
                                  void** cache_slot);
+#else
+static zval* message_set_property(zval* object, zval* member, zval* value,
+                                  void** cache_slot);
+#endif
 static zval* message_get_property(zval* object, zval* member, int type,
                                   void** cache_slot, zval* rv);
 static zval* message_get_property_ptr_ptr(zval* object, zval* member, int type,
@@ -100,7 +105,7 @@ PHP_PROTO_OBJECT_FREE_START(MessageHeader, message)
   }
 PHP_PROTO_OBJECT_FREE_END
 
-PHP_PROTO_OBJECT_DTOR_START(MessageHeader, message)
+PHP_PROTO_OBJECT_EMPTY_DTOR_START(MessageHeader, message)
 PHP_PROTO_OBJECT_DTOR_END
 
 // Define object create method.
@@ -140,13 +145,20 @@ static void message_set_property_internal(zval* object, zval* member,
 #if PHP_MAJOR_VERSION < 7
 static void message_set_property(zval* object, zval* member, zval* value,
                                  php_proto_zend_literal key TSRMLS_DC) {
-#else
+#elif PHP_VERSION_ID < 70400
 static void message_set_property(zval* object, zval* member, zval* value,
                                  void** cache_slot) {
+#else
+static zval* message_set_property(zval* object, zval* member, zval* value,
+                                  void** cache_slot) {
 #endif
   if (Z_TYPE_P(member) != IS_STRING) {
     zend_error(E_USER_ERROR, "Unexpected type for field name");
+#if PHP_VERSION_ID < 70400
     return;
+#else
+    return value;
+#endif
   }
 
 #if PHP_MAJOR_VERSION < 7 || (PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION == 0)
@@ -156,10 +168,17 @@ static void message_set_property(zval* object, zval* member, zval* value,
 #endif
     // User cannot set property directly (e.g., $m->a = 1)
     zend_error(E_USER_ERROR, "Cannot access private property.");
+#if PHP_VERSION_ID < 70400
     return;
+#else
+    return value;
+#endif
   }
 
   message_set_property_internal(object, member, value TSRMLS_CC);
+#if PHP_VERSION_ID >= 70400
+  return value;
+#endif
 }
 
 static zval* message_get_property_internal(zval* object,
@@ -380,7 +399,6 @@ void Message_construct(zval* msg, zval* array_wrapper) {
 
       if (upb_fielddef_issubmsg(value_field)) {
         const upb_msgdef* submsgdef = upb_fielddef_msgsubdef(value_field);
-        upb_wellknowntype_t type = upb_msgdef_wellknowntype(submsgdef);
         is_wrapper = is_wrapper_msg(submsgdef);
 
         if (is_wrapper) {
@@ -420,7 +438,6 @@ void Message_construct(zval* msg, zval* array_wrapper) {
 
       if (upb_fielddef_issubmsg(field)) {
         const upb_msgdef* submsgdef = upb_fielddef_msgsubdef(field);
-        upb_wellknowntype_t type = upb_msgdef_wellknowntype(submsgdef);
         is_wrapper = is_wrapper_msg(submsgdef);
 
         if (is_wrapper) {
@@ -646,6 +663,9 @@ PHP_METHOD(Message, writeWrapperValue) {
       CASE_TYPE(BOOL,   bool,   int8_t)
 
 #undef CASE_TYPE
+      case UPB_TYPE_MESSAGE:
+        zend_error(E_ERROR, "No wrapper for message.");
+        break;
     }
   }
 
@@ -666,7 +686,6 @@ PHP_METHOD(Message, writeWrapperValue) {
     const upb_msgdef* submsgdef = upb_fielddef_msgsubdef(field);
     const upb_fielddef* value_field = upb_msgdef_itof(submsgdef, 1);
     MessageHeader* submsg = UNBOX(MessageHeader, cached_zval);
-    CACHED_VALUE* cached_value = find_zval_property(submsg, value_field);
     layout_set(submsg->descriptor->layout, submsg,
                value_field, value TSRMLS_CC);
   } else {
@@ -1156,7 +1175,11 @@ PHP_METHOD(Field_Cardinality, name) {
       zend_throw_exception_ex(
           NULL, 0 TSRMLS_CC,
           "Enum Google\\Protobuf\\Field_Cardinality has no name "
+#if PHP_MAJOR_VERSION < 7
           "defined for value %d.",
+#else
+          "defined for value " ZEND_LONG_FMT ".",
+#endif
           value);
   }
 }
@@ -1291,7 +1314,11 @@ PHP_METHOD(Field_Kind, name) {
     default:
       zend_throw_exception_ex(NULL, 0 TSRMLS_CC,
                               "Enum Google\\Protobuf\\Field_Kind has no name "
+#if PHP_MAJOR_VERSION < 7
                               "defined for value %d.",
+#else
+                              "defined for value " ZEND_LONG_FMT ".",
+#endif
                               value);
   }
 }
@@ -1362,7 +1389,11 @@ PHP_METHOD(NullValue, name) {
     default:
       zend_throw_exception_ex(NULL, 0 TSRMLS_CC,
                               "Enum Google\\Protobuf\\NullValue has no name "
+#if PHP_MAJOR_VERSION < 7
                               "defined for value %d.",
+#else
+                              "defined for value " ZEND_LONG_FMT ".",
+#endif
                               value);
   }
 }
@@ -1419,7 +1450,11 @@ PHP_METHOD(Syntax, name) {
     default:
       zend_throw_exception_ex(NULL, 0 TSRMLS_CC,
                               "Enum Google\\Protobuf\\Syntax has no name "
+#if PHP_MAJOR_VERSION < 7
                               "defined for value %d.",
+#else
+                              "defined for value " ZEND_LONG_FMT ".",
+#endif
                               value);
   }
 }
@@ -1495,7 +1530,6 @@ static void hex_to_binary(const char* hex, char** binary, int* binary_len) {
 
 PHP_METHOD(Any, __construct) {
   init_file_any(TSRMLS_C);
-  MessageHeader* intern = UNBOX(MessageHeader, getThis());
   INIT_MESSAGE_WITH_ARRAY;
 }
 
@@ -1660,7 +1694,6 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
 
 PHP_METHOD(Duration, __construct) {
   init_file_duration(TSRMLS_C);
-  MessageHeader* intern = UNBOX(MessageHeader, getThis());
   INIT_MESSAGE_WITH_ARRAY;
 }
 
@@ -1695,7 +1728,6 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
 
 PHP_METHOD(Timestamp, __construct) {
   init_file_timestamp(TSRMLS_C);
-  MessageHeader* intern = UNBOX(MessageHeader, getThis());
   INIT_MESSAGE_WITH_ARRAY;
 }
 
@@ -1704,7 +1736,6 @@ PHP_PROTO_FIELD_ACCESSORS(Timestamp, timestamp, Nanos,   "nanos")
 
 PHP_METHOD(Timestamp, fromDateTime) {
   zval* datetime;
-  zval member;
 
   PHP_PROTO_CE_DECLARE date_interface_ce;
   if (php_proto_zend_lookup_class("\\DatetimeInterface", 18,
@@ -1897,7 +1928,6 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
 
 PHP_METHOD(Api, __construct) {
   init_file_api(TSRMLS_C);
-  MessageHeader* intern = UNBOX(MessageHeader, getThis());
   INIT_MESSAGE_WITH_ARRAY;
 }
 
@@ -1931,7 +1961,6 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
 
 PHP_METHOD(BoolValue, __construct) {
   init_file_wrappers(TSRMLS_C);
-  MessageHeader* intern = UNBOX(MessageHeader, getThis());
   INIT_MESSAGE_WITH_ARRAY;
 }
 
@@ -1959,7 +1988,6 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
 
 PHP_METHOD(BytesValue, __construct) {
   init_file_wrappers(TSRMLS_C);
-  MessageHeader* intern = UNBOX(MessageHeader, getThis());
   INIT_MESSAGE_WITH_ARRAY;
 }
 
@@ -1987,7 +2015,6 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
 
 PHP_METHOD(DoubleValue, __construct) {
   init_file_wrappers(TSRMLS_C);
-  MessageHeader* intern = UNBOX(MessageHeader, getThis());
   INIT_MESSAGE_WITH_ARRAY;
 }
 
@@ -2031,7 +2058,6 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
 
 PHP_METHOD(Enum, __construct) {
   init_file_type(TSRMLS_C);
-  MessageHeader* intern = UNBOX(MessageHeader, getThis());
   INIT_MESSAGE_WITH_ARRAY;
 }
 
@@ -2071,7 +2097,6 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
 
 PHP_METHOD(EnumValue, __construct) {
   init_file_type(TSRMLS_C);
-  MessageHeader* intern = UNBOX(MessageHeader, getThis());
   INIT_MESSAGE_WITH_ARRAY;
 }
 
@@ -2101,7 +2126,6 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
 
 PHP_METHOD(FieldMask, __construct) {
   init_file_field_mask(TSRMLS_C);
-  MessageHeader* intern = UNBOX(MessageHeader, getThis());
   INIT_MESSAGE_WITH_ARRAY;
 }
 
@@ -2166,7 +2190,6 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
 
 PHP_METHOD(Field, __construct) {
   init_file_type(TSRMLS_C);
-  MessageHeader* intern = UNBOX(MessageHeader, getThis());
   INIT_MESSAGE_WITH_ARRAY;
 }
 
@@ -2203,7 +2226,6 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
 
 PHP_METHOD(FloatValue, __construct) {
   init_file_wrappers(TSRMLS_C);
-  MessageHeader* intern = UNBOX(MessageHeader, getThis());
   INIT_MESSAGE_WITH_ARRAY;
 }
 
@@ -2227,7 +2249,6 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
 
 PHP_METHOD(GPBEmpty, __construct) {
   init_file_empty(TSRMLS_C);
-  MessageHeader* intern = UNBOX(MessageHeader, getThis());
   INIT_MESSAGE_WITH_ARRAY;
 }
 
@@ -2254,7 +2275,6 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
 
 PHP_METHOD(Int32Value, __construct) {
   init_file_wrappers(TSRMLS_C);
-  MessageHeader* intern = UNBOX(MessageHeader, getThis());
   INIT_MESSAGE_WITH_ARRAY;
 }
 
@@ -2282,7 +2302,6 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
 
 PHP_METHOD(Int64Value, __construct) {
   init_file_wrappers(TSRMLS_C);
-  MessageHeader* intern = UNBOX(MessageHeader, getThis());
   INIT_MESSAGE_WITH_ARRAY;
 }
 
@@ -2310,7 +2329,6 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
 
 PHP_METHOD(ListValue, __construct) {
   init_file_struct(TSRMLS_C);
-  MessageHeader* intern = UNBOX(MessageHeader, getThis());
   INIT_MESSAGE_WITH_ARRAY;
 }
 
@@ -2366,7 +2384,6 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
 
 PHP_METHOD(Method, __construct) {
   init_file_api(TSRMLS_C);
-  MessageHeader* intern = UNBOX(MessageHeader, getThis());
   INIT_MESSAGE_WITH_ARRAY;
 }
 
@@ -2404,7 +2421,6 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
 
 PHP_METHOD(Mixin, __construct) {
   init_file_api(TSRMLS_C);
-  MessageHeader* intern = UNBOX(MessageHeader, getThis());
   INIT_MESSAGE_WITH_ARRAY;
 }
 
@@ -2437,7 +2453,6 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
 
 PHP_METHOD(Option, __construct) {
   init_file_type(TSRMLS_C);
-  MessageHeader* intern = UNBOX(MessageHeader, getThis());
   INIT_MESSAGE_WITH_ARRAY;
 }
 
@@ -2467,7 +2482,6 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
 
 PHP_METHOD(SourceContext, __construct) {
   init_file_source_context(TSRMLS_C);
-  MessageHeader* intern = UNBOX(MessageHeader, getThis());
   INIT_MESSAGE_WITH_ARRAY;
 }
 
@@ -2495,7 +2509,6 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
 
 PHP_METHOD(StringValue, __construct) {
   init_file_wrappers(TSRMLS_C);
-  MessageHeader* intern = UNBOX(MessageHeader, getThis());
   INIT_MESSAGE_WITH_ARRAY;
 }
 
@@ -2523,7 +2536,6 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
 
 PHP_METHOD(Struct, __construct) {
   init_file_struct(TSRMLS_C);
-  MessageHeader* intern = UNBOX(MessageHeader, getThis());
   INIT_MESSAGE_WITH_ARRAY;
 }
 
@@ -2571,7 +2583,6 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
 
 PHP_METHOD(Type, __construct) {
   init_file_type(TSRMLS_C);
-  MessageHeader* intern = UNBOX(MessageHeader, getThis());
   INIT_MESSAGE_WITH_ARRAY;
 }
 
@@ -2604,7 +2615,6 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
 
 PHP_METHOD(UInt32Value, __construct) {
   init_file_wrappers(TSRMLS_C);
-  MessageHeader* intern = UNBOX(MessageHeader, getThis());
   INIT_MESSAGE_WITH_ARRAY;
 }
 
@@ -2632,7 +2642,6 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
 
 PHP_METHOD(UInt64Value, __construct) {
   init_file_wrappers(TSRMLS_C);
-  MessageHeader* intern = UNBOX(MessageHeader, getThis());
   INIT_MESSAGE_WITH_ARRAY;
 }
 
@@ -2671,7 +2680,6 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
 
 PHP_METHOD(Value, __construct) {
   init_file_struct(TSRMLS_C);
-  MessageHeader* intern = UNBOX(MessageHeader, getThis());
   INIT_MESSAGE_WITH_ARRAY;
 }
 

+ 3 - 34
php/ext/google/protobuf/protobuf.c

@@ -63,8 +63,6 @@ upb_strtable reserved_names;
 // -----------------------------------------------------------------------------
 
 static void add_to_table(HashTable* t, const void* def, void* value) {
-  uint nIndex = (ulong)def & t->nTableMask;
-
   zval* pDest = NULL;
   php_proto_zend_hash_index_update_mem(t, (zend_ulong)def, &value,
                                        sizeof(zval*), (void**)&pDest);
@@ -79,28 +77,6 @@ static void* get_from_table(const HashTable* t, const void* def) {
   return *value;
 }
 
-static bool exist_in_table(const HashTable* t, const void* def) {
-  void** value;
-  return (php_proto_zend_hash_index_find_mem(t, (zend_ulong)def,
-                                             (void**)&value) == SUCCESS);
-}
-
-static void add_to_strtable(HashTable* t, const char* key, int key_size,
-                            void* value) {
-  zval* pDest = NULL;
-  php_proto_zend_hash_update_mem(t, key, key_size, &value, sizeof(void*),
-                                 (void**)&pDest);
-}
-
-static void* get_from_strtable(const HashTable* t, const char* key, int key_size) {
-  void** value;
-  if (php_proto_zend_hash_find_mem(t, key, key_size, (void**)&value) ==
-      FAILURE) {
-    return NULL;
-  }
-  return *value;
-}
-
 void add_def_obj(const void* def, PHP_PROTO_HASHTABLE_VALUE value) {
 #if PHP_MAJOR_VERSION < 7
   Z_ADDREF_P(value);
@@ -349,13 +325,9 @@ static void php_proto_hashtable_descriptor_release(zval* value) {
   }
   efree(ptr);
 }
-
-static void test_release(void* value) {
-  void* ptr = value;
-}
 #endif
 
-static initialize_persistent_descriptor_pool(TSRMLS_D) {
+static void initialize_persistent_descriptor_pool(TSRMLS_D) {
   upb_inttable_init(&upb_def_to_desc_map_persistent, UPB_CTYPE_PTR);
   upb_inttable_init(&upb_def_to_enumdesc_map_persistent, UPB_CTYPE_PTR);
   upb_inttable_init(&ce_to_desc_map_persistent, UPB_CTYPE_PTR);
@@ -427,7 +399,7 @@ static void cleanup_enumdesc_table(upb_inttable* t) {
   }
 }
 
-static cleanup_persistent_descriptor_pool(TSRMLS_D) {
+static void cleanup_persistent_descriptor_pool(TSRMLS_D) {
   // Clean up
 
   // Only needs to clean one map out of three (def=>desc, ce=>desc, proto=>desc)
@@ -482,10 +454,7 @@ static PHP_RSHUTDOWN_FUNCTION(protobuf) {
 
 static void reserved_names_init() {
   size_t i;
-  upb_value v;
-#ifndef NDEBUG
-  v.ctype = UPB_CTYPE_UINT64;
-#endif
+  upb_value v = upb_value_bool(false);
   for (i = 0; i < kReservedNamesSize; i++) {
     upb_strtable_insert2(&reserved_names, kReservedNames[i],
                          strlen(kReservedNames[i]), v);

+ 18 - 17
php/ext/google/protobuf/protobuf.h

@@ -143,7 +143,6 @@
 #define PHP_PROTO_INIT_SUBMSGCLASS_START(CLASSNAME, CAMELNAME, LOWWERNAME)   \
   void LOWWERNAME##_init(TSRMLS_D) {                                         \
     zend_class_entry class_type;                                             \
-    const char* class_name = CLASSNAME;                                      \
     INIT_CLASS_ENTRY_EX(class_type, CLASSNAME, strlen(CLASSNAME),            \
                         LOWWERNAME##_methods);                               \
     LOWWERNAME##_type = zend_register_internal_class_ex(                     \
@@ -156,7 +155,6 @@
 #define PHP_PROTO_INIT_ENUMCLASS_START(CLASSNAME, CAMELNAME, LOWWERNAME)     \
   void LOWWERNAME##_init(TSRMLS_D) {                                         \
     zend_class_entry class_type;                                             \
-    const char* class_name = CLASSNAME;                                      \
     INIT_CLASS_ENTRY_EX(class_type, CLASSNAME, strlen(CLASSNAME),            \
                         LOWWERNAME##_methods);                               \
     LOWWERNAME##_type = zend_register_internal_class(&class_type TSRMLS_CC);
@@ -166,7 +164,6 @@
 #define PHP_PROTO_INIT_CLASS_START(CLASSNAME, CAMELNAME, LOWWERNAME)         \
   void LOWWERNAME##_init(TSRMLS_D) {                                         \
     zend_class_entry class_type;                                             \
-    const char* class_name = CLASSNAME;                                      \
     INIT_CLASS_ENTRY_EX(class_type, CLASSNAME, strlen(CLASSNAME),            \
                         LOWWERNAME##_methods);                               \
     LOWWERNAME##_type = zend_register_internal_class(&class_type TSRMLS_CC); \
@@ -187,6 +184,9 @@
   PHP_PROTO_FREE_CLASS_OBJECT(NAME, LOWWERNAME##_free, LOWWERNAME##_handlers); \
   }
 
+#define PHP_PROTO_OBJECT_EMPTY_FREE_START(classname, lowername) \
+  void lowername##_free(void* object TSRMLS_DC) {               \
+    classname* intern = object;
 #define PHP_PROTO_OBJECT_FREE_START(classname, lowername) \
   void lowername##_free(void* object TSRMLS_DC) {         \
     classname* intern = object;
@@ -195,6 +195,7 @@
     efree(intern);                                \
   }
 
+#define PHP_PROTO_OBJECT_EMPTY_DTOR_START(classname, lowername)
 #define PHP_PROTO_OBJECT_DTOR_START(classname, lowername)
 #define PHP_PROTO_OBJECT_DTOR_END
 
@@ -410,32 +411,28 @@ static inline int php_proto_zend_hash_get_current_data_ex(HashTable* ht,
   zend_object std;                \
   };
 
-#define PHP_PROTO_INIT_SUBMSGCLASS_START(CLASSNAME, CAMELNAME, LOWWERNAME)   \
-  void LOWWERNAME##_init(TSRMLS_D) {                                         \
-    zend_class_entry class_type;                                             \
-    const char* class_name = CLASSNAME;                                      \
-    INIT_CLASS_ENTRY_EX(class_type, CLASSNAME, strlen(CLASSNAME),            \
-                        LOWWERNAME##_methods);                               \
-    LOWWERNAME##_type = zend_register_internal_class_ex(                     \
-        &class_type, message_type TSRMLS_CC);                                \
-    zend_do_inheritance(LOWWERNAME##_type, message_type TSRMLS_CC);
+#define PHP_PROTO_INIT_SUBMSGCLASS_START(CLASSNAME, CAMELNAME, LOWWERNAME) \
+  void LOWWERNAME##_init(TSRMLS_D) {                                       \
+    zend_class_entry class_type;                                           \
+    INIT_CLASS_ENTRY_EX(class_type, CLASSNAME, strlen(CLASSNAME),          \
+                        LOWWERNAME##_methods);                             \
+    LOWWERNAME##_type = zend_register_internal_class(&class_type);         \
+    zend_do_inheritance(LOWWERNAME##_type, message_type);
 #define PHP_PROTO_INIT_SUBMSGCLASS_END \
   }
 
 #define PHP_PROTO_INIT_ENUMCLASS_START(CLASSNAME, CAMELNAME, LOWWERNAME)     \
   void LOWWERNAME##_init(TSRMLS_D) {                                         \
     zend_class_entry class_type;                                             \
-    const char* class_name = CLASSNAME;                                      \
     INIT_CLASS_ENTRY_EX(class_type, CLASSNAME, strlen(CLASSNAME),            \
                         LOWWERNAME##_methods);                               \
-    LOWWERNAME##_type = zend_register_internal_class(&class_type TSRMLS_CC);
+    LOWWERNAME##_type = zend_register_internal_class(&class_type);
 #define PHP_PROTO_INIT_ENUMCLASS_END \
   }
 
 #define PHP_PROTO_INIT_CLASS_START(CLASSNAME, CAMELNAME, LOWWERNAME)         \
   void LOWWERNAME##_init(TSRMLS_D) {                                         \
     zend_class_entry class_type;                                             \
-    const char* class_name = CLASSNAME;                                      \
     INIT_CLASS_ENTRY_EX(class_type, CLASSNAME, strlen(CLASSNAME),            \
                         LOWWERNAME##_methods);                               \
     LOWWERNAME##_type = zend_register_internal_class(&class_type TSRMLS_CC); \
@@ -449,6 +446,8 @@ static inline int php_proto_zend_hash_get_current_data_ex(HashTable* ht,
 #define PHP_PROTO_INIT_CLASS_END \
   }
 
+#define PHP_PROTO_OBJECT_EMPTY_FREE_START(classname, lowername) \
+  void lowername##_free(zend_object* object) {
 #define PHP_PROTO_OBJECT_FREE_START(classname, lowername) \
   void lowername##_free(zend_object* object) {            \
     classname* intern =                                   \
@@ -456,6 +455,8 @@ static inline int php_proto_zend_hash_get_current_data_ex(HashTable* ht,
 #define PHP_PROTO_OBJECT_FREE_END           \
   }
 
+#define PHP_PROTO_OBJECT_EMPTY_DTOR_START(classname, lowername) \
+  void lowername##_dtor(zend_object* object) {
 #define PHP_PROTO_OBJECT_DTOR_START(classname, lowername) \
   void lowername##_dtor(zend_object* object) {            \
     classname* intern =                                   \
@@ -569,8 +570,8 @@ static inline int php_proto_zend_lookup_class(
   LOWERNAME##_free_c(intern TSRMLS_CC);             \
   PHP_PROTO_OBJECT_FREE_END
 
-#define DEFINE_PROTOBUF_DTOR(CAMELNAME, LOWERNAME)  \
-  PHP_PROTO_OBJECT_DTOR_START(CAMELNAME, LOWERNAME) \
+#define DEFINE_PROTOBUF_DTOR(CAMELNAME, LOWERNAME)        \
+  PHP_PROTO_OBJECT_EMPTY_DTOR_START(CAMELNAME, LOWERNAME) \
   PHP_PROTO_OBJECT_DTOR_END
 
 #define DEFINE_CLASS(NAME, LOWERNAME, string_name) \

+ 4 - 9
php/ext/google/protobuf/storage.c

@@ -100,8 +100,10 @@ bool native_slot_set(upb_fieldtype_t type, const zend_class_entry* klass,
       if (EXPECTED(cached_zval != NULL)) {
 #if PHP_MAJOR_VERSION < 7
         REPLACE_ZVAL_VALUE((zval**)memory, value, 1);
-#else
+#elif PHP_VERSION_ID < 70400
         zend_assign_to_variable(cached_zval, value, IS_CV);
+#else
+        zend_assign_to_variable(cached_zval, value, IS_CV, 0);
 #endif
       }
       break;
@@ -272,7 +274,6 @@ bool native_slot_set_by_map(upb_fieldtype_t type, const zend_class_entry* klass,
 }
 
 void native_slot_init(upb_fieldtype_t type, void* memory, CACHED_VALUE* cache) {
-  zval* tmp = NULL;
   switch (type) {
     case UPB_TYPE_FLOAT:
       DEREF(memory, float) = 0.0;
@@ -577,11 +578,6 @@ uint32_t* slot_oneof_case(MessageLayout* layout, const void* storage,
                      layout->fields[upb_fielddef_index(field)].case_offset);
 }
 
-static int slot_property_cache(MessageLayout* layout, const void* storage,
-                               const upb_fielddef* field) {
-  return layout->fields[upb_fielddef_index(field)].cache_index;
-}
-
 void* slot_memory(MessageLayout* layout, const void* storage,
                          const upb_fielddef* field) {
   return ((uint8_t*)storage) + layout->fields[upb_fielddef_index(field)].offset;
@@ -998,7 +994,6 @@ static void native_slot_merge_by_array(const upb_fielddef* field, const void* fr
       break;
     }
     case UPB_TYPE_MESSAGE: {
-      const upb_msgdef* msg = upb_fielddef_msgsubdef(field);
       DescriptorInternal* desc = get_msgdef_desc(upb_fielddef_msgsubdef(field));
       register_class(desc, false TSRMLS_CC);
       zend_class_entry* ce = desc->klass;
@@ -1168,7 +1163,7 @@ void layout_merge(MessageLayout* layout, MessageHeader* from,
 const char* layout_get_oneof_case(MessageLayout* layout, const void* storage,
                                   const upb_oneofdef* oneof TSRMLS_DC) {
   upb_oneof_iter i;
-  const upb_fielddef* first_field;
+  const upb_fielddef* first_field = NULL;
 
   // Oneof is guaranteed to have at least one field. Get the first field.
   for(upb_oneof_begin(&i, oneof); !upb_oneof_done(&i); upb_oneof_next(&i)) {

+ 22 - 2
php/ext/google/protobuf/type_check.c

@@ -407,8 +407,6 @@ bool protobuf_convert_to_bool(zval* from, int8_t* to) {
       *to = (int8_t)(Z_LVAL_P(from) != 0);
       break;
     case IS_STRING: {
-      char* strval = Z_STRVAL_P(from);
-
       if (Z_STRLEN_P(from) == 0 ||
           (Z_STRLEN_P(from) == 1 && Z_STRVAL_P(from)[0] == '0')) {
         *to = 0;
@@ -496,7 +494,11 @@ PHP_METHOD(Util, checkMessage) {
   if (!instanceof_function(Z_OBJCE_P(val), klass TSRMLS_CC)) {
     zend_throw_exception_ex(NULL, 0 TSRMLS_CC,
                             "Given value is not an instance of %s.",
+#if PHP_MAJOR_VERSION < 7
                             klass->name);
+#else
+                            ZSTR_VAL(klass->name));
+#endif
     return;
   }
   RETURN_ZVAL(val, 1, 0);
@@ -541,7 +543,11 @@ void check_repeated_field(const zend_class_entry* klass, PHP_PROTO_LONG type,
     if (!instanceof_function(Z_OBJCE_P(val), repeated_field_type TSRMLS_CC)) {
       zend_throw_exception_ex(NULL, 0 TSRMLS_CC,
                               "Given value is not an instance of %s.",
+#if PHP_MAJOR_VERSION < 7
                               repeated_field_type->name);
+#else
+                              ZSTR_VAL(repeated_field_type->name));
+#endif
       return;
     }
     RepeatedField* intern = UNBOX(RepeatedField, val);
@@ -553,7 +559,12 @@ void check_repeated_field(const zend_class_entry* klass, PHP_PROTO_LONG type,
     if (klass != NULL && intern->msg_ce != klass) {
       zend_throw_exception_ex(NULL, 0 TSRMLS_CC,
                               "Expect a repeated field of %s, but %s is given.",
+#if PHP_MAJOR_VERSION < 7
                               klass->name, intern->msg_ce->name);
+#else
+                              ZSTR_VAL(klass->name),
+                              ZSTR_VAL(intern->msg_ce->name));
+#endif
       return;
     }
     RETURN_ZVAL(val, 1, 0);
@@ -617,7 +628,11 @@ void check_map_field(const zend_class_entry* klass, PHP_PROTO_LONG key_type,
     if (!instanceof_function(Z_OBJCE_P(val), map_field_type TSRMLS_CC)) {
       zend_throw_exception_ex(NULL, 0 TSRMLS_CC,
                               "Given value is not an instance of %s.",
+#if PHP_MAJOR_VERSION < 7
                               map_field_type->name);
+#else
+                              ZSTR_VAL(map_field_type->name));
+#endif
       return;
     }
     Map* intern = UNBOX(Map, val);
@@ -636,7 +651,12 @@ void check_map_field(const zend_class_entry* klass, PHP_PROTO_LONG key_type,
     if (klass != NULL && intern->msg_ce != klass) {
       zend_throw_exception_ex(NULL, 0 TSRMLS_CC,
                               "Expect a map field of %s, but %s is given.",
+#if PHP_MAJOR_VERSION < 7
                               klass->name, intern->msg_ce->name);
+#else
+                              ZSTR_VAL(klass->name),
+                              ZSTR_VAL(intern->msg_ce->name));
+#endif
       return;
     }
     RETURN_ZVAL(val, 1, 0);

+ 16 - 0
php/src/Google/Protobuf/Internal/Message.php

@@ -933,6 +933,10 @@ class Message
                    throw new GPBDecodeException(
                        "Invalid data type for int32 field");
                 }
+                if (is_string($value) && trim($value) !== $value) {
+                   throw new GPBDecodeException(
+                       "Invalid data type for int32 field");
+                }
                 if (bccomp($value, "2147483647") > 0) {
                    throw new GPBDecodeException(
                        "Int32 too large");
@@ -951,6 +955,10 @@ class Message
                    throw new GPBDecodeException(
                        "Invalid data type for uint32 field");
                 }
+                if (is_string($value) && trim($value) !== $value) {
+                   throw new GPBDecodeException(
+                       "Invalid data type for int32 field");
+                }
                 if (bccomp($value, 4294967295) > 0) {
                     throw new GPBDecodeException(
                         "Uint32 too large");
@@ -966,6 +974,10 @@ class Message
                    throw new GPBDecodeException(
                        "Invalid data type for int64 field");
                 }
+                if (is_string($value) && trim($value) !== $value) {
+                   throw new GPBDecodeException(
+                       "Invalid data type for int64 field");
+                }
                 if (bccomp($value, "9223372036854775807") > 0) {
                     throw new GPBDecodeException(
                         "Int64 too large");
@@ -984,6 +996,10 @@ class Message
                    throw new GPBDecodeException(
                        "Invalid data type for int64 field");
                 }
+                if (is_string($value) && trim($value) !== $value) {
+                   throw new GPBDecodeException(
+                       "Invalid data type for int64 field");
+                }
                 if (bccomp($value, "18446744073709551615") > 0) {
                     throw new GPBDecodeException(
                         "Uint64 too large");

+ 1 - 1
php/tests/compile_extension.sh

@@ -6,5 +6,5 @@ pushd $EXTENSION_PATH
 make clean || true
 set -e
 # Add following in configure for debug: --enable-debug CFLAGS='-g -O0'
-phpize && ./configure CFLAGS='-g -O0' && make
+phpize && ./configure CFLAGS='-g -O0 -Wall' && make
 popd

+ 143 - 44
tests.sh

@@ -514,14 +514,19 @@ build_php5.5() {
 }
 
 build_php5.5_c() {
+  IS_64BIT=$1
   use_php 5.5
   pushd php/tests
   /bin/bash ./test.sh 5.5
   popd
-  # TODO(teboring): Add it back
-  # pushd conformance
-  # make test_php_c
-  # popd
+  pushd conformance
+  if [ "$IS_64BIT" = "true" ]
+  then
+    make test_php_c
+  else
+    make test_php_c_32
+  fi
+  popd
 }
 
 build_php5.5_mixed() {
@@ -535,12 +540,17 @@ build_php5.5_mixed() {
 }
 
 build_php5.5_zts_c() {
+  IS_64BIT=$1
   use_php_zts 5.5
   cd php/tests && /bin/bash ./test.sh 5.5-zts && cd ../..
-  # TODO(teboring): Add it back
-  # pushd conformance
-  # make test_php_zts_c
-  # popd
+  pushd conformance
+  if [ "$IS_64BIT" = "true" ]
+  then
+    make test_php_c
+  else
+    make test_php_c_32
+  fi
+  popd
 }
 
 build_php5.6() {
@@ -556,12 +566,17 @@ build_php5.6() {
 }
 
 build_php5.6_c() {
+  IS_64BIT=$1
   use_php 5.6
   cd php/tests && /bin/bash ./test.sh 5.6 && cd ../..
-  # TODO(teboring): Add it back
-  # pushd conformance
-  # make test_php_c
-  # popd
+  pushd conformance
+  if [ "$IS_64BIT" = "true" ]
+  then
+    make test_php_c
+  else
+    make test_php_c_32
+  fi
+  popd
 }
 
 build_php5.6_mixed() {
@@ -575,12 +590,17 @@ build_php5.6_mixed() {
 }
 
 build_php5.6_zts_c() {
+  IS_64BIT=$1
   use_php_zts 5.6
   cd php/tests && /bin/bash ./test.sh 5.6-zts && cd ../..
-  # TODO(teboring): Add it back
-  # pushd conformance
-  # make test_php_zts_c
-  # popd
+  pushd conformance
+  if [ "$IS_64BIT" = "true" ]
+  then
+    make test_php_c
+  else
+    make test_php_c_32
+  fi
+  popd
 }
 
 build_php5.6_mac() {
@@ -602,10 +622,9 @@ build_php5.6_mac() {
 
   # Test
   cd php/tests && /bin/bash ./test.sh && cd ../..
-  # TODO(teboring): Add it back
-  # pushd conformance
-  # make test_php_c
-  # popd
+  pushd conformance
+  make test_php_c
+  popd
 }
 
 build_php7.0() {
@@ -621,12 +640,17 @@ build_php7.0() {
 }
 
 build_php7.0_c() {
+  IS_64BIT=$1
   use_php 7.0
   cd php/tests && /bin/bash ./test.sh 7.0 && cd ../..
-  # TODO(teboring): Add it back
-  # pushd conformance
-  # make test_php_c
-  # popd
+  pushd conformance
+  if [ "$IS_64BIT" = "true" ]
+  then
+    make test_php_c
+  else
+    make test_php_c_32
+  fi
+  popd
 }
 
 build_php7.0_mixed() {
@@ -640,12 +664,17 @@ build_php7.0_mixed() {
 }
 
 build_php7.0_zts_c() {
+  IS_64BIT=$1
   use_php_zts 7.0
   cd php/tests && /bin/bash ./test.sh 7.0-zts && cd ../..
-  # TODO(teboring): Add it back.
-  # pushd conformance
-  # make test_php_zts_c
-  # popd
+  pushd conformance
+  if [ "$IS_64BIT" = "true" ]
+  then
+    make test_php_c
+  else
+    make test_php_c_32
+  fi
+  popd
 }
 
 build_php7.0_mac() {
@@ -667,10 +696,9 @@ build_php7.0_mac() {
 
   # Test
   cd php/tests && /bin/bash ./test.sh && cd ../..
-  # TODO(teboring): Add it back
-  # pushd conformance
-  # make test_php_c
-  # popd
+  pushd conformance
+  make test_php_c
+  popd
 }
 
 build_php_compatibility() {
@@ -691,15 +719,17 @@ build_php7.1() {
 }
 
 build_php7.1_c() {
-  ENABLE_CONFORMANCE_TEST=$1
+  IS_64BIT=$1
   use_php 7.1
   cd php/tests && /bin/bash ./test.sh 7.1 && cd ../..
-  if [ "$ENABLE_CONFORMANCE_TEST" = "true" ]
+  pushd conformance
+  if [ "$IS_64BIT" = "true" ]
   then
-    pushd conformance
     make test_php_c
-    popd
+  else
+    make test_php_c_32
   fi
+  popd
 }
 
 build_php7.1_mixed() {
@@ -713,10 +743,75 @@ build_php7.1_mixed() {
 }
 
 build_php7.1_zts_c() {
+  IS_64BIT=$1
   use_php_zts 7.1
   cd php/tests && /bin/bash ./test.sh 7.1-zts && cd ../..
   pushd conformance
-  # make test_php_c
+  if [ "$IS_64BIT" = "true" ]
+  then
+    make test_php_c
+  else
+    make test_php_c_32
+  fi
+  popd
+}
+
+build_php7.4() {
+  use_php 7.4
+  pushd php
+  rm -rf vendor
+  composer update
+  ./vendor/bin/phpunit
+  popd
+  pushd conformance
+  make test_php
+  popd
+}
+
+build_php7.4_c() {
+  IS_64BIT=$1
+  use_php 7.4
+  cd php/tests && /bin/bash ./test.sh 7.4 && cd ../..
+  pushd conformance
+  if [ "$IS_64BIT" = "true" ]
+  then
+    make test_php_c
+  else
+    make test_php_c_32
+  fi
+  popd
+  pushd php/ext/google/protobuf
+  phpize --clean
+  popd
+}
+
+build_php7.4_mixed() {
+  use_php 7.4
+  pushd php
+  rm -rf vendor
+  composer update
+  /bin/bash ./tests/compile_extension.sh ./ext/google/protobuf
+  php -dextension=./ext/google/protobuf/modules/protobuf.so ./vendor/bin/phpunit
+  popd
+  pushd php/ext/google/protobuf
+  phpize --clean
+  popd
+}
+
+build_php7.4_zts_c() {
+  IS_64BIT=$1
+  use_php_zts 7.4
+  cd php/tests && /bin/bash ./test.sh 7.4-zts && cd ../..
+  pushd conformance
+  if [ "$IS_64BIT" = "true" ]
+  then
+    make test_php_c
+  else
+    make test_php_c_32
+  fi
+  popd
+  pushd php/ext/google/protobuf
+  phpize --clean
   popd
 }
 
@@ -725,18 +820,22 @@ build_php_all_32() {
   build_php5.6
   build_php7.0
   build_php7.1
-  build_php5.5_c
-  build_php5.6_c
-  build_php7.0_c
+  build_php7.4
+  build_php5.5_c $1
+  build_php5.6_c $1
+  build_php7.0_c $1
   build_php7.1_c $1
+  build_php7.4_c $1
   build_php5.5_mixed
   build_php5.6_mixed
   build_php7.0_mixed
   build_php7.1_mixed
-  build_php5.5_zts_c
-  build_php5.6_zts_c
-  build_php7.0_zts_c
-  build_php7.1_zts_c
+  build_php7.4_mixed
+  build_php5.5_zts_c $1
+  build_php5.6_zts_c $1
+  build_php7.0_zts_c $1
+  build_php7.1_zts_c $1
+  build_php7.4_zts_c $1
 }
 
 build_php_all() {