From 4d3e4cfa4a1bf01e8a19515967f127ddd4b5cdf3 Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Fri, 23 Sep 2016 23:53:43 -0700 Subject: [PATCH 01/24] Fix MSVC stack overflow issue. --- src/google/protobuf/util/internal/json_stream_parser_test.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/google/protobuf/util/internal/json_stream_parser_test.cc b/src/google/protobuf/util/internal/json_stream_parser_test.cc index 945fc6caa5b00..eaa7e045338ef 100644 --- a/src/google/protobuf/util/internal/json_stream_parser_test.cc +++ b/src/google/protobuf/util/internal/json_stream_parser_test.cc @@ -139,7 +139,12 @@ class JsonStreamParserTest : public ::testing::Test { } +#ifndef _MSC_VER + // TODO(xiaofeng): We have to disable InSequence check for MSVC because it + // causes stack overflow due to its use of a linked list that is desctructed + // recursively. ::testing::InSequence in_sequence_; +#endif // !_MSC_VER MockObjectWriter mock_; ExpectingObjectWriter ow_; }; From 530eede12b8e6c8d8612f7280da738a274ea5797 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 26 Sep 2016 10:38:00 +0200 Subject: [PATCH 02/24] Update README.md --- csharp/README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/csharp/README.md b/csharp/README.md index ddf1d2be6f72e..ed5c7be706880 100644 --- a/csharp/README.md +++ b/csharp/README.md @@ -1,8 +1,5 @@ This directory contains the C# Protocol Buffers runtime library. -Status: Beta - ready for external testing -========================================= - Usage ===== From 787f3fb16380a403c99716a23ed09cd7b9ea5b67 Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Mon, 26 Sep 2016 12:48:28 -0700 Subject: [PATCH 03/24] Fixing inconsistent php version number. --- php/ext/google/protobuf/package.xml | 2 +- php/ext/google/protobuf/protobuf.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/php/ext/google/protobuf/package.xml b/php/ext/google/protobuf/package.xml index e1064b37c4663..01aad411752ff 100644 --- a/php/ext/google/protobuf/package.xml +++ b/php/ext/google/protobuf/package.xml @@ -6,7 +6,7 @@ https://developers.google.com/protocol-buffers/ Bo Yang - teboring + stanleycheung protobuf-opensource@google.com yes diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h index 0330f36f762b8..b3ad20dd920f4 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 "0.01" +#define PHP_PROTOBUF_VERSION "3.1.0a1" // ----------------------------------------------------------------------------- // Forward Declaration From c4d70123ac99ff1a0886fc7dfa492010b027210a Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Tue, 27 Sep 2016 15:36:41 -0700 Subject: [PATCH 04/24] Fixed references to foreign nested messages with CommonJS-style imports A bug was causing generated JSPB code with CommonJS-style imports to refer incorrectly to nested messages from other .proto files. The generated code would have things like "test_pb.InnerMessage" instead of "test_pb.OuterMessage.InnerMessage". This commit fixes the problem by correctly taking into account any message nesting. --- js/message_test.js | 14 +++++++++ js/test.proto | 8 +++++ js/test2.proto | 6 ++++ .../protobuf/compiler/js/js_generator.cc | 30 ++++++++++--------- 4 files changed, 44 insertions(+), 14 deletions(-) diff --git a/js/message_test.js b/js/message_test.js index 97c594c8c85c0..b0a0a72e649b5 100644 --- a/js/message_test.js +++ b/js/message_test.js @@ -1040,4 +1040,18 @@ describe('Message test suite', function() { assertNan(message.getDefaultDoubleField()); }); + // Verify that we can successfully use a field referring to a nested message + // from a different .proto file. + it('testForeignNestedMessage', function() { + var msg = new proto.jspb.test.ForeignNestedFieldMessage(); + var nested = new proto.jspb.test.Deeply.Nested.Message(); + nested.setCount(5); + msg.setDeeplyNestedMessage(nested); + + // After a serialization-deserialization round trip we should get back the + // same data we started with. + var serialized = msg.serializeBinary(); + var deserialized = proto.jspb.test.ForeignNestedFieldMessage.deserializeBinary(serialized); + assertEquals(5, deserialized.getDeeplyNestedMessage().getCount()); + }); }); diff --git a/js/test.proto b/js/test.proto index 48cb37e112e98..db238e1a6b7ea 100644 --- a/js/test.proto +++ b/js/test.proto @@ -260,3 +260,11 @@ enum MapValueEnumNoBinary { message MapValueMessageNoBinary { optional int32 foo = 1; } + +message Deeply { + message Nested { + message Message { + optional int32 count = 1; + } + } +} diff --git a/js/test2.proto b/js/test2.proto index 44e55effcb47e..b67f93fa9ece8 100644 --- a/js/test2.proto +++ b/js/test2.proto @@ -35,6 +35,8 @@ option java_multiple_files = true; package jspb.test; +import "test.proto"; + message TestExtensionsMessage { optional int32 intfield = 1; extensions 100 to max; @@ -52,3 +54,7 @@ extend TestExtensionsMessage { optional ExtensionMessage floating_msg_field = 101; optional string floating_str_field = 102; } + +message ForeignNestedFieldMessage { + optional Deeply.Nested.Message deeply_nested_message = 1; +} diff --git a/src/google/protobuf/compiler/js/js_generator.cc b/src/google/protobuf/compiler/js/js_generator.cc index fec465fef7907..58597b4cae841 100755 --- a/src/google/protobuf/compiler/js/js_generator.cc +++ b/src/google/protobuf/compiler/js/js_generator.cc @@ -208,28 +208,28 @@ string GetPath(const GeneratorOptions& options, } } -// Forward declare, so that GetPrefix can call this method, -// which in turn, calls GetPrefix. -string GetPath(const GeneratorOptions& options, - const Descriptor* descriptor); +// Returns the name of the message with a leading dot and taking into account +// nesting, for example ".OuterMessage.InnerMessage", or returns empty if +// descriptor is null. This function does not handle namespacing, only message +// nesting. +string GetNestedMessageName(const Descriptor* descriptor) { + if (descriptor == NULL) { + return ""; + } + return StripPrefixString(descriptor->full_name(), + descriptor->file()->package()); +} // Returns the path prefix for a message or enumeration that // lives under the given file and containing type. string GetPrefix(const GeneratorOptions& options, const FileDescriptor* file_descriptor, const Descriptor* containing_type) { - string prefix = ""; - - if (containing_type == NULL) { - prefix = GetPath(options, file_descriptor); - } else { - prefix = GetPath(options, containing_type); - } - + string prefix = GetPath(options, file_descriptor) + + GetNestedMessageName(containing_type); if (!prefix.empty()) { prefix += "."; } - return prefix; } @@ -277,7 +277,9 @@ string MaybeCrossFileRef(const GeneratorOptions& options, from_file != to_message->file()) { // Cross-file ref in CommonJS needs to use the module alias instead of // the global name. - return ModuleAlias(to_message->file()->name()) + "." + to_message->name(); + return ModuleAlias(to_message->file()->name()) + + GetNestedMessageName(to_message->containing_type()) + + "." + to_message->name(); } else { // Within a single file we use a full name. return GetPath(options, to_message); From 8b54280395fe9236428c7a50c9b6c0e57c3131e5 Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Wed, 28 Sep 2016 10:52:32 -0700 Subject: [PATCH 05/24] Added alias getFieldProto3 as used by older generated code. Un-breaks users who have old generated code and upgrade to the 3.1.0 release. --- js/message.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/js/message.js b/js/message.js index b150722a3599c..8def763e9cd13 100644 --- a/js/message.js +++ b/js/message.js @@ -754,6 +754,18 @@ jspb.Message.getFieldWithDefault = function(msg, fieldNumber, defaultValue) { }; +/** + * Alias for getFieldWithDefault used by older generated code. + * @template T + * @param {!jspb.Message} msg A jspb proto. + * @param {number} fieldNumber The field number. + * @param {T} defaultValue The default value. + * @return {T} The field's value. + * @protected + */ +jspb.Message.getFieldProto3 = jspb.Message.getFieldWithDefault; + + /** * Gets the value of a map field, lazily creating the map container if * necessary. From b9bad65bf32cebc6210b4da9251919503d479dbd Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Wed, 28 Sep 2016 13:51:57 -0700 Subject: [PATCH 06/24] Add script to build Google.Protobuf.Tools for csharp. --- csharp/build_tools.sh | 52 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100755 csharp/build_tools.sh diff --git a/csharp/build_tools.sh b/csharp/build_tools.sh new file mode 100755 index 0000000000000..182c5c5c82eab --- /dev/null +++ b/csharp/build_tools.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +if [ $# -ne 1 ]; then + cat < + +Example: + $ $0 3.0.0 + +This script will download pre-built protoc binaries from maven repository and +create the Google.Protobuf.Tools package. Well-known type .proto files will also +be included. +EOF + exit 1 +fi + +VERSION_NUMBER=$1 +# pairs. +declare -a FILE_NAMES=( \ + windows_x86 windows-x86_32.exe \ + windows_x64 windows-x86_64.exe \ + macosx_x86 osx-x86_32.exe \ + macosx_x64 osx-x86_64.exe \ + linux_x86 linux-x86_32.exe \ + linux_x64 linux-x86_64.exe \ +) + +set -e + +mkdir -p protoc +# Create a zip file for each binary. +for((i=0;i<${#FILE_NAMES[@]};i+=2));do + DIR_NAME=${FILE_NAMES[$i]} + mkdir -p protoc/$DIR_NAME + + if [ ${DIR_NAME:0:3} = "win" ]; then + TARGET_BINARY="protoc.exe" + else + TARGET_BINARY="protoc" + fi + + BINARY_NAME=${FILE_NAMES[$(($i+1))]} + BINARY_URL=http://repo1.maven.org/maven2/com/google/protobuf/protoc/${VERSION_NUMBER}/protoc-${VERSION_NUMBER}-${BINARY_NAME} + + if ! wget ${BINARY_URL} -O protoc/$DIR_NAME/$TARGET_BINARY &> /dev/null; then + echo "[ERROR] Failed to download ${BINARY_URL}" >&2 + echo "[ERROR] Skipped $protoc-${VERSION_NAME}-${DIR_NAME}" >&2 + continue + fi +done + +nuget pack Google.Protobuf.Tools.nuspec From 1d2c7b6c7376f396c8c7dd9b6afd2d4f83f3cb05 Mon Sep 17 00:00:00 2001 From: Derek Murray Date: Thu, 29 Sep 2016 12:52:54 -0700 Subject: [PATCH 07/24] Fix MSVC build when HAVE_LONG_LONG is defined. --- src/google/protobuf/stubs/type_traits.h | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/google/protobuf/stubs/type_traits.h b/src/google/protobuf/stubs/type_traits.h index 8d48c6aa9e281..3ab5ea7d4eab5 100644 --- a/src/google/protobuf/stubs/type_traits.h +++ b/src/google/protobuf/stubs/type_traits.h @@ -139,18 +139,10 @@ template<> struct is_integral : true_type { }; template<> struct is_integral : true_type { }; template<> struct is_integral : true_type { }; template<> struct is_integral : true_type { }; -#ifdef HAVE_LONG_LONG +#if defined(HAVE_LONG_LONG) || defined(_MSC_VER) template<> struct is_integral : true_type { }; template<> struct is_integral : true_type { }; #endif -#if defined(_MSC_VER) -// With VC, __int8, __int16, and __int32 are synonymous with standard types -// with the same size, but __int64 has not equivalent (i.e., it's neither -// long, nor long long and should be treated differnetly). -// https://msdn.microsoft.com/en-us/library/29dh1w7z.aspx -template<> struct is_integral<__int64> : true_type { }; -template<> struct is_integral : true_type {}; -#endif template struct is_integral : is_integral { }; template struct is_integral : is_integral { }; template struct is_integral : is_integral { }; From 1baaedfb3d3d716e32d4ff72079c0324da1bccac Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Fri, 30 Sep 2016 00:07:47 +0000 Subject: [PATCH 08/24] Add php test script for automated tests. --- tests.sh | 71 +++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 63 insertions(+), 8 deletions(-) diff --git a/tests.sh b/tests.sh index c8c7dabcfda72..e659504433191 100755 --- a/tests.sh +++ b/tests.sh @@ -35,14 +35,13 @@ internal_build_cpp() { build_cpp() { internal_build_cpp make check -j2 - pushd conformance - make test_cpp - popd + cd conformance && make test_cpp && cd .. # Verify benchmarking code can build successfully. - pushd benchmarks - make && ./generate-datasets - popd + git submodule init + git submodule update + cd third_party/benchmark && cmake -DCMAKE_BUILD_TYPE=Release && make && cd ../.. + cd benchmarks && make && ./generate-datasets && cd .. } build_cpp_distcheck() { @@ -51,7 +50,7 @@ build_cpp_distcheck() { make dist # List all files that should be included in the distribution package. - git ls-files | grep "^\(java\|python\|objectivec\|csharp\|js\|ruby\|php\|cmake\|examples\)" |\ + git ls-files | grep "^\(java\|python\|objectivec\|csharp\|js\|ruby\|cmake\|examples\)" |\ grep -v ".gitignore" | grep -v "java/compatibility_tests" > dist.lst # Unzip the dist tar file. DIST=`ls *.tar.gz` @@ -296,6 +295,8 @@ build_python() { build_python_cpp() { internal_build_cpp internal_install_python_deps + export LD_LIBRARY_PATH=../src/.libs # for Linux + export DYLD_LIBRARY_PATH=../src/.libs # for OS X cd python # Only test Python 2.6/3.x on Linux if [ $(uname -s) == "Linux" ]; then @@ -333,6 +334,54 @@ build_javascript() { cd js && npm install && npm test && cd .. } +build_php5.5_c() { + ln -sfn /usr/bin/php5.5 /usr/bin/php + ln -sfn /usr/bin/php-config5.5 /usr/bin/php-config + ln -sfn /usr/bin/phpize5.5 /usr/bin/phpize + cd php/tests && /bin/bash ./test.sh && cd ../.. +} + +build_php5.5() { + ln -sfn /usr/bin/php5.5 /usr/bin/php + ln -sfn /usr/bin/php-config5.5 /usr/bin/php-config + ln -sfn /usr/bin/phpize5.5 /usr/bin/phpize + rm -rf vendor + cp -r /usr/local/vendor-5.5 vendor + ./vendor/bin/phpunit +} + +build_php5.6_c() { + ln -sfn /usr/bin/php5.6 /usr/bin/php + ln -sfn /usr/bin/php-config5.6 /usr/bin/php-config + ln -sfn /usr/bin/phpize5.6 /usr/bin/phpize + cd php/tests && /bin/bash ./test.sh && cd ../.. +} + +build_php5.6() { + ln -sfn /usr/bin/php5.6 /usr/bin/php + ln -sfn /usr/bin/php-config5.6 /usr/bin/php-config + ln -sfn /usr/bin/phpize5.6 /usr/bin/phpize + rm -rf vendor + cp -r /usr/local/vendor-5.6 vendor + ./vendor/bin/phpunit +} + +build_php7.0_c() { + ln -sfn /usr/bin/php7.0 /usr/bin/php + ln -sfn /usr/bin/php-config7.0 /usr/bin/php-config + ln -sfn /usr/bin/phpize7.0 /usr/bin/phpize + cd php/tests && /bin/bash ./test.sh && cd ../.. +} + +build_php7.0() { + ln -sfn /usr/bin/php7.0 /usr/bin/php + ln -sfn /usr/bin/php-config7.0 /usr/bin/php-config + ln -sfn /usr/bin/phpize7.0 /usr/bin/phpize + rm -rf vendor + cp -r /usr/local/vendor-7.0 vendor + ./vendor/bin/phpunit +} + # Note: travis currently does not support testing more than one language so the # .travis.yml cheats and claims to only be cpp. If they add multiple language # support, this should probably get updated to install steps and/or @@ -363,7 +412,13 @@ Usage: $0 { cpp | ruby21 | ruby22 | jruby | - ruby_all) + ruby_all | + php5.5 | + php5.5_c | + php5.6 | + php5.6_c | + php7.0 | + php7.0_c) " exit 1 fi From f17528a1fa51e1a81af94aa0a2a445265d6b7e83 Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Fri, 30 Sep 2016 01:10:27 +0000 Subject: [PATCH 09/24] Set up environment for php automated tests. --- jenkins/docker/Dockerfile | 52 ++++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/jenkins/docker/Dockerfile b/jenkins/docker/Dockerfile index 9c2a834dd8944..8c3a1a2970f4c 100644 --- a/jenkins/docker/Dockerfile +++ b/jenkins/docker/Dockerfile @@ -14,25 +14,29 @@ RUN echo 'deb http://ppa.launchpad.net/fkrull/deadsnakes/ubuntu trusty main' > / apt-key adv --keyserver keyserver.ubuntu.com --recv-keys DB82666C # Apt source for Oracle Java. -run echo 'deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main' > /etc/apt/sources.list.d/webupd8team-java-trusty.list && \ +RUN echo 'deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main' > /etc/apt/sources.list.d/webupd8team-java-trusty.list && \ apt-key adv --keyserver keyserver.ubuntu.com --recv-keys EEA14886 && \ echo "oracle-java7-installer shared/accepted-oracle-license-v1-1 select true" | debconf-set-selections # Apt source for Mono -run echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list && \ +RUN echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list && \ echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list && \ apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF +# Apt source for php +RUN echo "deb http://ppa.launchpad.net/ondrej/php/ubuntu trusty main" | tee /etc/apt/sources.list.d/various-php.list && \ + apt-key adv --keyserver keyserver.ubuntu.com --recv-keys F4FCBB07 + # Install dotnet SDK based on https://www.microsoft.com/net/core#debian # (Ubuntu instructions need apt to support https) -RUN apt-get update && apt-get install -y curl libunwind8 gettext && \ - curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130 && \ +RUN apt-get update && apt-get install -y --force-yes curl libunwind8 gettext && \ + curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130 && \ mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnet && \ ln -s /opt/dotnet/dotnet /usr/local/bin # Install dependencies. We start with the basic ones require to build protoc # and the C++ build -RUN apt-get update && apt-get install -y \ +RUN apt-get clean && apt-get update && apt-get install -y --force-yes \ autoconf \ autotools-dev \ build-essential \ @@ -71,6 +75,18 @@ RUN apt-get update && apt-get install -y \ python3.4-dev \ # -- For Ruby -- ruby \ + # -- For PHP -- + php5.5 \ + php5.5-dev \ + php5.5-xml \ + php5.6 \ + php5.6-dev \ + php5.6-xml \ + php7.0 \ + php7.0-dev \ + php7.0-xml \ + phpunit \ + valgrind \ && apt-get clean ################## @@ -121,6 +137,30 @@ RUN cd /tmp && \ cd ../javanano && \ $MVN install dependency:go-offline -Dmaven.repo.local=$MAVEN_REPO +################## +# PHP dependencies. +RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" +RUN php composer-setup.php +RUN mv composer.phar /usr/bin/composer +RUN php -r "unlink('composer-setup.php');" +RUN cd /tmp && \ + cd protobuf && \ + ln -sfn /usr/bin/php5.5 /usr/bin/php && \ + ln -sfn /usr/bin/php-config5.5 /usr/bin/php-config && \ + ln -sfn /usr/bin/phpize5.5 /usr/bin/phpize && \ + composer install && \ + mv vendor /usr/local/vendor-5.5 && \ + ln -sfn /usr/bin/php5.6 /usr/bin/php && \ + ln -sfn /usr/bin/php-config5.6 /usr/bin/php-config && \ + ln -sfn /usr/bin/phpize5.6 /usr/bin/phpize && \ + composer install && \ + mv vendor /usr/local/vendor-5.6 && \ + ln -sfn /usr/bin/php7.0 /usr/bin/php && \ + ln -sfn /usr/bin/php-config7.0 /usr/bin/php-config && \ + ln -sfn /usr/bin/phpize7.0 /usr/bin/phpize && \ + composer install && \ + mv vendor /usr/local/vendor-7.0 + ################## # Go dependencies. RUN apt-get install -y \ @@ -129,7 +169,7 @@ RUN apt-get install -y \ ################## # Javascript dependencies. -Run apt-get install -y \ +RUN apt-get install -y \ # -- For javascript -- \ npm From dae50dc56a48d86fdce3bb52151a2a4652e5c33b Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Fri, 30 Sep 2016 01:20:41 +0000 Subject: [PATCH 10/24] Trigger automated tests for php. --- jenkins/pull_request_in_docker.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/jenkins/pull_request_in_docker.sh b/jenkins/pull_request_in_docker.sh index 78a9253a41d6c..66f3bb23be1ee 100755 --- a/jenkins/pull_request_in_docker.sh +++ b/jenkins/pull_request_in_docker.sh @@ -58,6 +58,12 @@ parallel --results $LOG_OUTPUT_DIR --joblog $OUTPUT_DIR/joblog $TEST_SCRIPT ::: ruby_all \ javascript \ golang \ + php5.5 \ + php5.6 \ + php7.0 \ + php5.5_c \ + php5.6_c \ + php7.0_c \ || true # Process test results even if tests fail. cat $OUTPUT_DIR/joblog From bcb32c0b8692774634cb9de10be921d11d7fbf8a Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Fri, 30 Sep 2016 19:07:33 +0000 Subject: [PATCH 11/24] Test php5.5_c test on jenkins --- jenkins/pull_request_in_docker.sh | 7 +---- php/tests/test.sh | 10 +++---- tests.sh | 49 +++++++++++++++++++------------ 3 files changed, 36 insertions(+), 30 deletions(-) diff --git a/jenkins/pull_request_in_docker.sh b/jenkins/pull_request_in_docker.sh index 66f3bb23be1ee..b843a355667a6 100755 --- a/jenkins/pull_request_in_docker.sh +++ b/jenkins/pull_request_in_docker.sh @@ -58,12 +58,7 @@ parallel --results $LOG_OUTPUT_DIR --joblog $OUTPUT_DIR/joblog $TEST_SCRIPT ::: ruby_all \ javascript \ golang \ - php5.5 \ - php5.6 \ - php7.0 \ - php5.5_c \ - php5.6_c \ - php7.0_c \ + php_all \ || true # Process test results even if tests fail. cat $OUTPUT_DIR/joblog diff --git a/php/tests/test.sh b/php/tests/test.sh index f3f04a4700dd5..15df768cd6c16 100755 --- a/php/tests/test.sh +++ b/php/tests/test.sh @@ -1,10 +1,5 @@ #!/bin/bash -# Compile protoc -pushd ../../ -./autogen.sh && ./configure && make -popd - # Generate test file ../../src/protoc --php_out=. test.proto test_include.proto @@ -29,4 +24,9 @@ done # Make sure to run the memory test in debug mode. php -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php +php --version +which php +pwd +ls +ls -l `which php` USE_ZEND_ALLOC=0 valgrind --leak-check=yes php -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php diff --git a/tests.sh b/tests.sh index e659504433191..f0d2abc9dbfb2 100755 --- a/tests.sh +++ b/tests.sh @@ -334,54 +334,64 @@ build_javascript() { cd js && npm install && npm test && cd .. } +use_php() { + VERSION=$1 + PHP=`which php` + PHP_CONFIG=`which php-config` + PHPIZE=`which phpize` + rm $PHP + rm $PHP_CONFIG + rm $PHPIZE + cp "/usr/bin/php$VERSION" $PHP + cp "/usr/bin/php-config$VERSION" $PHP_CONFIG + cp "/usr/bin/phpize$VERSION" $PHPIZE +} + build_php5.5_c() { - ln -sfn /usr/bin/php5.5 /usr/bin/php - ln -sfn /usr/bin/php-config5.5 /usr/bin/php-config - ln -sfn /usr/bin/phpize5.5 /usr/bin/phpize + use_php 5.5 cd php/tests && /bin/bash ./test.sh && cd ../.. } build_php5.5() { - ln -sfn /usr/bin/php5.5 /usr/bin/php - ln -sfn /usr/bin/php-config5.5 /usr/bin/php-config - ln -sfn /usr/bin/phpize5.5 /usr/bin/phpize + use_php 5.5 rm -rf vendor cp -r /usr/local/vendor-5.5 vendor ./vendor/bin/phpunit } build_php5.6_c() { - ln -sfn /usr/bin/php5.6 /usr/bin/php - ln -sfn /usr/bin/php-config5.6 /usr/bin/php-config - ln -sfn /usr/bin/phpize5.6 /usr/bin/phpize + use_php 5.6 cd php/tests && /bin/bash ./test.sh && cd ../.. } build_php5.6() { - ln -sfn /usr/bin/php5.6 /usr/bin/php - ln -sfn /usr/bin/php-config5.6 /usr/bin/php-config - ln -sfn /usr/bin/phpize5.6 /usr/bin/phpize + use_php 5.6 rm -rf vendor cp -r /usr/local/vendor-5.6 vendor ./vendor/bin/phpunit } build_php7.0_c() { - ln -sfn /usr/bin/php7.0 /usr/bin/php - ln -sfn /usr/bin/php-config7.0 /usr/bin/php-config - ln -sfn /usr/bin/phpize7.0 /usr/bin/phpize + use_php 7.0 cd php/tests && /bin/bash ./test.sh && cd ../.. } build_php7.0() { - ln -sfn /usr/bin/php7.0 /usr/bin/php - ln -sfn /usr/bin/php-config7.0 /usr/bin/php-config - ln -sfn /usr/bin/phpize7.0 /usr/bin/phpize + use_php 7.0 rm -rf vendor cp -r /usr/local/vendor-7.0 vendor ./vendor/bin/phpunit } +build_php_all() { + build_php5.5 + build_php5.6 + build_php7.0 + build_php5.5_c + build_php5.6_c + # build_php7.0_c +} + # Note: travis currently does not support testing more than one language so the # .travis.yml cheats and claims to only be cpp. If they add multiple language # support, this should probably get updated to install steps and/or @@ -418,7 +428,8 @@ Usage: $0 { cpp | php5.6 | php5.6_c | php7.0 | - php7.0_c) + php7.0_c | + php_all) " exit 1 fi From 858db7a202a36c57aeed998ef088a03cae48e582 Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Mon, 3 Oct 2016 21:59:58 +0000 Subject: [PATCH 12/24] Add travis test on Mac for php. --- .travis.yml | 1 + tests.sh | 28 +++++++++++++++++++--------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 094235e028b17..d331a26e3c5bc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,6 +30,7 @@ env: - CONFIG=ruby21 - CONFIG=ruby22 - CONFIG=jruby + - CONFIG=php5.5_mac matrix: exclude: # It's nontrivial to programmatically install a new JDK from the command diff --git a/tests.sh b/tests.sh index f0d2abc9dbfb2..c3c66aa438023 100755 --- a/tests.sh +++ b/tests.sh @@ -347,11 +347,6 @@ use_php() { cp "/usr/bin/phpize$VERSION" $PHPIZE } -build_php5.5_c() { - use_php 5.5 - cd php/tests && /bin/bash ./test.sh && cd ../.. -} - build_php5.5() { use_php 5.5 rm -rf vendor @@ -359,8 +354,18 @@ build_php5.5() { ./vendor/bin/phpunit } -build_php5.6_c() { - use_php 5.6 +build_php5.5_c() { + use_php 5.5 + cd php/tests && /bin/bash ./test.sh && cd ../.. +} +build_php5.5_c() { + use_php 5.5 + cd php/tests && /bin/bash ./test.sh && cd ../.. +} + +build_php5.5_mac() { + curl -s https://php-osx.liip.ch/install.sh | bash -s 5.5 + export PATH="/usr/local/php5-5.5.38-20160831-100002/bin:$PATH" cd php/tests && /bin/bash ./test.sh && cd ../.. } @@ -371,8 +376,8 @@ build_php5.6() { ./vendor/bin/phpunit } -build_php7.0_c() { - use_php 7.0 +build_php5.6_c() { + use_php 5.6 cd php/tests && /bin/bash ./test.sh && cd ../.. } @@ -383,6 +388,11 @@ build_php7.0() { ./vendor/bin/phpunit } +build_php7.0_c() { + use_php 7.0 + cd php/tests && /bin/bash ./test.sh && cd ../.. +} + build_php_all() { build_php5.5 build_php5.6 From 149659b72a61ea6f1c537ef8741be50b6826cb91 Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Thu, 29 Sep 2016 14:29:23 -0700 Subject: [PATCH 13/24] Do strict enum name checking only for proto3 There seem to already be .proto files out there that have conflicting enum names, which will not be able to build successfully for some languages (like C#). To prevent this problem from spreading, let's make it an error for proto3 but just issue a warning for proto2. This fixes issue #2179. --- src/google/protobuf/descriptor.cc | 19 ++++++++++++++----- src/google/protobuf/descriptor_unittest.cc | 17 +++++++++++++---- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index 4dccb585958d2..be1e1d69cc9ec 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -4707,11 +4707,20 @@ void DescriptorBuilder::CheckEnumValueUniqueness( // stripping should de-dup the labels in this case). if (!inserted && insert_result.first->second->name() != value->name() && insert_result.first->second->number() != value->number()) { - AddError(value->full_name(), proto.value(i), - DescriptorPool::ErrorCollector::NAME, - "When enum name is stripped and label is PascalCased (" + - stripped + "), this value label conflicts with " + - values[stripped]->name()); + string error_message = + "When enum name is stripped and label is PascalCased (" + stripped + + "), this value label conflicts with " + values[stripped]->name() + + ". This will make the proto fail to compile for some languages, such " + "as C#."; + // There are proto2 enums out there with conflicting names, so to preserve + // compatibility we issue only a warning for proto2. + if (result->file()->syntax() == FileDescriptor::SYNTAX_PROTO2) { + AddWarning(value->full_name(), proto.value(i), + DescriptorPool::ErrorCollector::NAME, error_message); + } else { + AddError(value->full_name(), proto.value(i), + DescriptorPool::ErrorCollector::NAME, error_message); + } } } } diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc index 0795341688b61..f6b3f1c55aba6 100644 --- a/src/google/protobuf/descriptor_unittest.cc +++ b/src/google/protobuf/descriptor_unittest.cc @@ -5565,6 +5565,7 @@ TEST_F(ValidationErrorTest, MapEntryConflictsWithEnum) { TEST_F(ValidationErrorTest, EnumValuesConflictWhenPrefixesStripped) { BuildFileWithErrors( + "syntax: 'proto3'" "name: 'foo.proto' " "enum_type {" " name: 'FooEnum' " @@ -5572,9 +5573,11 @@ TEST_F(ValidationErrorTest, EnumValuesConflictWhenPrefixesStripped) { " value { name: 'BAZ' number: 1 }" "}", "foo.proto: BAZ: NAME: When enum name is stripped and label is " - "PascalCased (Baz), this value label conflicts with FOO_ENUM_BAZ\n"); + "PascalCased (Baz), this value label conflicts with FOO_ENUM_BAZ. This " + "will make the proto fail to compile for some languages, such as C#.\n"); BuildFileWithErrors( + "syntax: 'proto3'" "name: 'foo.proto' " "enum_type {" " name: 'FooEnum' " @@ -5582,9 +5585,11 @@ TEST_F(ValidationErrorTest, EnumValuesConflictWhenPrefixesStripped) { " value { name: 'BAZ' number: 1 }" "}", "foo.proto: BAZ: NAME: When enum name is stripped and label is " - "PascalCased (Baz), this value label conflicts with FOOENUM_BAZ\n"); + "PascalCased (Baz), this value label conflicts with FOOENUM_BAZ. This " + "will make the proto fail to compile for some languages, such as C#.\n"); BuildFileWithErrors( + "syntax: 'proto3'" "name: 'foo.proto' " "enum_type {" " name: 'FooEnum' " @@ -5593,9 +5598,11 @@ TEST_F(ValidationErrorTest, EnumValuesConflictWhenPrefixesStripped) { "}", "foo.proto: BAR__BAZ: NAME: When enum name is stripped and label is " "PascalCased (BarBaz), this value label conflicts with " - "FOO_ENUM_BAR_BAZ\n"); + "FOO_ENUM_BAR_BAZ. This " + "will make the proto fail to compile for some languages, such as C#.\n"); BuildFileWithErrors( + "syntax: 'proto3'" "name: 'foo.proto' " "enum_type {" " name: 'FooEnum' " @@ -5604,11 +5611,13 @@ TEST_F(ValidationErrorTest, EnumValuesConflictWhenPrefixesStripped) { "}", "foo.proto: BAR_BAZ: NAME: When enum name is stripped and label is " "PascalCased (BarBaz), this value label conflicts with " - "FOO_ENUM__BAR_BAZ\n"); + "FOO_ENUM__BAR_BAZ. This " + "will make the proto fail to compile for some languages, such as C#.\n"); // This isn't an error because the underscore will cause the PascalCase to // differ by case (BarBaz vs. Barbaz). BuildFile( + "syntax: 'proto3'" "name: 'foo.proto' " "enum_type {" " name: 'FooEnum' " From 3a055be9257b7ff9fe102243a744107b2712d583 Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Tue, 4 Oct 2016 17:22:26 +0000 Subject: [PATCH 14/24] Prepare jenkins for testing php zts build. --- jenkins/docker/Dockerfile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/jenkins/docker/Dockerfile b/jenkins/docker/Dockerfile index 8c3a1a2970f4c..4bfbef3411837 100644 --- a/jenkins/docker/Dockerfile +++ b/jenkins/docker/Dockerfile @@ -87,6 +87,7 @@ RUN apt-get clean && apt-get update && apt-get install -y --force-yes \ php7.0-xml \ phpunit \ valgrind \ + libxml2-dev \ && apt-get clean ################## @@ -160,6 +161,11 @@ RUN cd /tmp && \ ln -sfn /usr/bin/phpize7.0 /usr/bin/phpize && \ composer install && \ mv vendor /usr/local/vendor-7.0 +RUN wget http://am1.php.net/get/php-5.5.38.tar.bz2/from/this/mirror +RUN mv mirror php-5.5.38.tar.bz2 +RUN tar -xvf php-5.5.38.tar.bz2 +RUN cd php-5.5.38 && ./configure --enable-maintainer-zts --prefix=/usr/local/php-5.5-zts && \ + make && make install ################## # Go dependencies. From 2d897c8fa2cbe21683263e3eeddd1ab8e0d89091 Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Tue, 4 Oct 2016 17:32:08 +0000 Subject: [PATCH 15/24] Add test for php zts build. --- tests.sh | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/tests.sh b/tests.sh index c3c66aa438023..ccf49f00804f0 100755 --- a/tests.sh +++ b/tests.sh @@ -347,6 +347,16 @@ use_php() { cp "/usr/bin/phpize$VERSION" $PHPIZE } +use_php_zts() { + VERSION=$1 + PHP=`which php` + PHP_CONFIG=`which php-config` + PHPIZE=`which phpize` + ln -sfn "/usr/local/php-${VERSION}-zts/bin/php" $PHP + ln -sfn "/usr/local/php-${VERSION}-zts/bin/php-config" $PHP_CONFIG + ln -sfn "/usr/local/php-${VERSION}-zts/bin/phpize" $PHPIZE +} + build_php5.5() { use_php 5.5 rm -rf vendor @@ -354,10 +364,6 @@ build_php5.5() { ./vendor/bin/phpunit } -build_php5.5_c() { - use_php 5.5 - cd php/tests && /bin/bash ./test.sh && cd ../.. -} build_php5.5_c() { use_php 5.5 cd php/tests && /bin/bash ./test.sh && cd ../.. @@ -369,6 +375,11 @@ build_php5.5_mac() { cd php/tests && /bin/bash ./test.sh && cd ../.. } +build_php5.5_zts_c() { + use_php_zts 5.5 + cd php/tests && /bin/bash ./test.sh && cd ../.. +} + build_php5.6() { use_php 5.6 rm -rf vendor @@ -400,6 +411,7 @@ build_php_all() { build_php5.5_c build_php5.6_c # build_php7.0_c + build_php5.5_zts_c } # Note: travis currently does not support testing more than one language so the From 52ab3b07ac9a6889ed0ac9bf21afd8dab8ef0014 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Tue, 4 Oct 2016 13:39:51 -0700 Subject: [PATCH 16/24] PHP: fix ZTS tsrm_ls errors (#2189) * PHP: fix ZTS tsrm_ls errors * Fix a few more macros --- php/ext/google/protobuf/array.c | 5 +- php/ext/google/protobuf/encode_decode.c | 64 +++++++++++++------------ php/ext/google/protobuf/map.c | 19 ++++---- php/ext/google/protobuf/message.c | 5 +- php/ext/google/protobuf/protobuf.h | 15 +++--- php/ext/google/protobuf/storage.c | 20 ++++---- 6 files changed, 69 insertions(+), 59 deletions(-) diff --git a/php/ext/google/protobuf/array.c b/php/ext/google/protobuf/array.c index fde4f7268492f..f96e95ec11c96 100644 --- a/php/ext/google/protobuf/array.c +++ b/php/ext/google/protobuf/array.c @@ -160,7 +160,8 @@ static void repeated_field_write_dimension(zval *object, zval *offset, unsigned char memory[NATIVE_SLOT_MAX_SIZE]; memset(memory, 0, NATIVE_SLOT_MAX_SIZE); - if (!native_slot_set(intern->type, intern->msg_ce, memory, value)) { + if (!native_slot_set(intern->type, intern->msg_ce, memory, value + TSRMLS_CC)) { return; } @@ -192,7 +193,7 @@ static HashTable *repeated_field_get_gc(zval *object, zval ***table, // C RepeatedField Utilities // ----------------------------------------------------------------------------- -void *repeated_field_index_native(RepeatedField *intern, int index) { +void *repeated_field_index_native(RepeatedField *intern, int index TSRMLS_DC) { HashTable *ht = HASH_OF(intern->array); void *value; diff --git a/php/ext/google/protobuf/encode_decode.c b/php/ext/google/protobuf/encode_decode.c index 4b51dabe2cc93..af90ff3320e6b 100644 --- a/php/ext/google/protobuf/encode_decode.c +++ b/php/ext/google/protobuf/encode_decode.c @@ -199,11 +199,11 @@ static void *startseq_handler(void* closure, const void* hd) { // Handlers that append primitive values to a repeated field. #define DEFINE_APPEND_HANDLER(type, ctype) \ static bool append##type##_handler(void* closure, const void* hd, \ - ctype val) { \ + ctype val TSRMLS_DC) { \ zval* array = (zval*)closure; \ RepeatedField* intern = \ (RepeatedField*)zend_object_store_get_object(array TSRMLS_CC); \ - repeated_field_push_native(intern, &val); \ + repeated_field_push_native(intern, &val TSRMLS_CC); \ return true; \ } @@ -218,7 +218,7 @@ DEFINE_APPEND_HANDLER(double, double) // Appends a string to a repeated field. static void* appendstr_handler(void *closure, const void *hd, - size_t size_hint) { + size_t size_hint TSRMLS_DC) { zval* array = (zval*)closure; RepeatedField* intern = (RepeatedField*)zend_object_store_get_object(array TSRMLS_CC); @@ -234,7 +234,7 @@ static void* appendstr_handler(void *closure, // Appends a 'bytes' string to a repeated field. static void* appendbytes_handler(void *closure, const void *hd, - size_t size_hint) { + size_t size_hint TSRMLS_DC) { zval* array = (zval*)closure; RepeatedField* intern = (RepeatedField*)zend_object_store_get_object(array TSRMLS_CC); @@ -296,7 +296,7 @@ static size_t stringdata_handler(void* closure, const void* hd, } // Appends a submessage to a repeated field. -static void *appendsubmsg_handler(void *closure, const void *hd) { +static void *appendsubmsg_handler(void *closure, const void *hd TSRMLS_DC) { zval* array = (zval*)closure; RepeatedField* intern = (RepeatedField*)zend_object_store_get_object(array TSRMLS_CC); @@ -319,7 +319,7 @@ static void *appendsubmsg_handler(void *closure, const void *hd) { } // Sets a non-repeated submessage field in a message. -static void *submsg_handler(void *closure, const void *hd) { +static void *submsg_handler(void *closure, const void *hd TSRMLS_DC) { MessageHeader* msg = closure; const submsg_handlerdata_t* submsgdata = hd; zval* subdesc_php = get_def_obj((void*)submsgdata->md); @@ -423,7 +423,8 @@ static void map_slot_key(upb_fieldtype_t type, const void* from, char** keyval, } } -static void map_slot_value(upb_fieldtype_t type, const void* from, upb_value* v) { +static void map_slot_value(upb_fieldtype_t type, const void* from, + upb_value* v) { size_t len; void* to = upb_value_memory(v); #ifndef NDEBUG @@ -464,7 +465,8 @@ static void *startmapentry_handler(void *closure, const void *hd) { // Handler to end a map entry: inserts the value defined during the message into // the map. This is the 'endmsg' handler on the map entry msgdef. -static bool endmap_handler(void *closure, const void *hd, upb_status* s) { +static bool endmap_handler(void *closure, const void *hd, upb_status* s + TSRMLS_DC) { map_parse_frame_t* frame = closure; const map_handlerdata_t* mapdata = hd; @@ -574,7 +576,7 @@ static void *oneofbytes_handler(void *closure, // Handler for a submessage field in a oneof. static void *oneofsubmsg_handler(void *closure, - const void *hd) { + const void *hd TSRMLS_DC) { MessageHeader* msg = closure; const oneof_handlerdata_t *oneofdata = hd; uint32_t oldcase = DEREF(msg, oneofdata->case_ofs, uint32_t); @@ -771,7 +773,8 @@ static void add_handlers_for_oneof_field(upb_handlers *h, upb_handlerattr_uninit(&attr); } -static void add_handlers_for_message(const void *closure, upb_handlers *h) { +static void add_handlers_for_message(const void *closure, upb_handlers *h + TSRMLS_DC) { const upb_msgdef* msgdef = upb_handlers_msgdef(h); Descriptor* desc = (Descriptor*)zend_object_store_get_object( get_def_obj((void*)msgdef) TSRMLS_CC); @@ -860,7 +863,7 @@ static const upb_pbdecodermethod *msgdef_decodermethod(Descriptor* desc) { // ----------------------------------------------------------------------------- static void putmsg(zval* msg, const Descriptor* desc, upb_sink* sink, - int depth); + int depth TSRMLS_DC); static void putstr(zval* str, const upb_fielddef* f, upb_sink* sink); @@ -868,11 +871,12 @@ static void putrawstr(const char* str, int len, const upb_fielddef* f, upb_sink* sink); static void putsubmsg(zval* submsg, const upb_fielddef* f, upb_sink* sink, - int depth); + int depth TSRMLS_DC); static void putarray(zval* array, const upb_fielddef* f, upb_sink* sink, - int depth); -static void putmap(zval* map, const upb_fielddef* f, upb_sink* sink, int depth); + int depth TSRMLS_DC); +static void putmap(zval* map, const upb_fielddef* f, upb_sink* sink, int depth + TSRMLS_DC); static upb_selector_t getsel(const upb_fielddef* f, upb_handlertype_t type) { upb_selector_t ret; @@ -882,7 +886,7 @@ static upb_selector_t getsel(const upb_fielddef* f, upb_handlertype_t type) { } static void put_optional_value(void* memory, int len, const upb_fielddef* f, - int depth, upb_sink* sink) { + int depth, upb_sink* sink TSRMLS_DC) { assert(upb_fielddef_label(f) == UPB_LABEL_OPTIONAL); switch (upb_fielddef_type(f)) { @@ -911,7 +915,7 @@ static void put_optional_value(void* memory, int len, const upb_fielddef* f, break; case UPB_TYPE_MESSAGE: { zval* submsg = *(zval**)memory; - putsubmsg(submsg, f, sink, depth); + putsubmsg(submsg, f, sink, depth TSRMLS_CC); break; } default: @@ -943,7 +947,7 @@ static int raw_value_len(void* memory, int len, const upb_fielddef* f) { } static void putmap(zval* map, const upb_fielddef* f, upb_sink* sink, - int depth) { + int depth TSRMLS_DC) { Map* self; upb_sink subsink; const upb_fielddef* key_field; @@ -960,7 +964,7 @@ static void putmap(zval* map, const upb_fielddef* f, upb_sink* sink, key_field = map_field_key(f); value_field = map_field_value(f); - for (map_begin(map, &it); !map_done(&it); map_next(&it)) { + for (map_begin(map, &it TSRMLS_CC); !map_done(&it); map_next(&it)) { upb_status status; upb_sink entry_sink; @@ -970,13 +974,13 @@ static void putmap(zval* map, const upb_fielddef* f, upb_sink* sink, // Serialize key. const char *key = map_iter_key(&it, &len); - put_optional_value(key, len, key_field, depth + 1, &entry_sink); + put_optional_value(key, len, key_field, depth + 1, &entry_sink TSRMLS_CC); // Serialize value. upb_value value = map_iter_value(&it, &len); put_optional_value(raw_value(upb_value_memory(&value), value_field), raw_value_len(upb_value_memory(&value), len, value_field), - value_field, depth + 1, &entry_sink); + value_field, depth + 1, &entry_sink TSRMLS_CC); upb_sink_endmsg(&entry_sink, &status); upb_sink_endsubmsg(&subsink, getsel(f, UPB_HANDLER_ENDSUBMSG)); @@ -986,7 +990,7 @@ static void putmap(zval* map, const upb_fielddef* f, upb_sink* sink, } static void putmsg(zval* msg_php, const Descriptor* desc, upb_sink* sink, - int depth) { + int depth TSRMLS_DC) { upb_msg_field_iter i; upb_status status; @@ -1023,12 +1027,12 @@ static void putmsg(zval* msg_php, const Descriptor* desc, upb_sink* sink, if (is_map_field(f)) { zval* map = *DEREF(msg, offset, zval**); if (map != NULL) { - putmap(map, f, sink, depth); + putmap(map, f, sink, depth TSRMLS_CC); } } else if (upb_fielddef_isseq(f)) { zval* array = *DEREF(msg, offset, zval**); if (array != NULL) { - putarray(array, f, sink, depth); + putarray(array, f, sink, depth TSRMLS_CC); } } else if (upb_fielddef_isstring(f)) { zval* str = *DEREF(msg, offset, zval**); @@ -1036,7 +1040,7 @@ static void putmsg(zval* msg_php, const Descriptor* desc, upb_sink* sink, putstr(str, f, sink); } } else if (upb_fielddef_issubmsg(f)) { - putsubmsg(*DEREF(msg, offset, zval**), f, sink, depth); + putsubmsg(*DEREF(msg, offset, zval**), f, sink, depth TSRMLS_CC); } else { upb_selector_t sel = getsel(f, upb_handlers_getprimitivehandlertype(f)); @@ -1113,7 +1117,7 @@ static void putrawstr(const char* str, int len, const upb_fielddef* f, } static void putsubmsg(zval* submsg, const upb_fielddef* f, upb_sink* sink, - int depth) { + int depth TSRMLS_DC) { upb_sink subsink; if (Z_TYPE_P(submsg) == IS_NULL) return; @@ -1123,12 +1127,12 @@ static void putsubmsg(zval* submsg, const upb_fielddef* f, upb_sink* sink, (Descriptor*)zend_object_store_get_object(php_descriptor TSRMLS_CC); upb_sink_startsubmsg(sink, getsel(f, UPB_HANDLER_STARTSUBMSG), &subsink); - putmsg(submsg, subdesc, &subsink, depth + 1); + putmsg(submsg, subdesc, &subsink, depth + 1 TSRMLS_CC); upb_sink_endsubmsg(sink, getsel(f, UPB_HANDLER_ENDSUBMSG)); } static void putarray(zval* array, const upb_fielddef* f, upb_sink* sink, - int depth) { + int depth TSRMLS_DC) { upb_sink subsink; upb_fieldtype_t type = upb_fielddef_type(f); upb_selector_t sel = 0; @@ -1147,7 +1151,7 @@ static void putarray(zval* array, const upb_fielddef* f, upb_sink* sink, } for (i = 0; i < size; i++) { - void* memory = repeated_field_index_native(intern, i); + void* memory = repeated_field_index_native(intern, i TSRMLS_CC); switch (type) { #define T(upbtypeconst, upbtype, ctype) \ case upbtypeconst: \ @@ -1168,7 +1172,7 @@ static void putarray(zval* array, const upb_fielddef* f, upb_sink* sink, putstr(*((zval**)memory), f, &subsink); break; case UPB_TYPE_MESSAGE: - putsubmsg(*((zval**)memory), f, &subsink, depth); + putsubmsg(*((zval**)memory), f, &subsink, depth TSRMLS_CC); break; #undef T @@ -1206,7 +1210,7 @@ PHP_METHOD(Message, encode) { stackenv_init(&se, "Error occurred during encoding: %s"); encoder = upb_pb_encoder_create(&se.env, serialize_handlers, &sink.sink); - putmsg(getThis(), desc, upb_pb_encoder_input(encoder), 0); + putmsg(getThis(), desc, upb_pb_encoder_input(encoder), 0 TSRMLS_CC); RETVAL_STRINGL(sink.ptr, sink.len, 1); diff --git a/php/ext/google/protobuf/map.c b/php/ext/google/protobuf/map.c index 6d822fff06b64..6a80d978fbf2b 100644 --- a/php/ext/google/protobuf/map.c +++ b/php/ext/google/protobuf/map.c @@ -88,7 +88,7 @@ void* upb_value_memory(upb_value* v) { static bool table_key(Map* self, zval* key, char* buf, const char** out_key, - size_t* out_length) { + size_t* out_length TSRMLS_DC) { switch (self->key_type) { case UPB_TYPE_STRING: if (!protobuf_convert_to_string(key)) { @@ -108,7 +108,7 @@ static bool table_key(Map* self, zval* key, if (!protobuf_convert_to_##type(key, &type##_value)) { \ return false; \ } \ - native_slot_set(self->key_type, NULL, buf, key); \ + native_slot_set(self->key_type, NULL, buf, key TSRMLS_CC); \ *out_key = buf; \ *out_length = native_slot_size(self->key_type); \ break; \ @@ -248,7 +248,7 @@ void map_field_create_with_type(zend_class_entry *ce, const upb_fielddef *field, const upb_fielddef *value_field = map_field_value(field); intern->key_type = upb_fielddef_type(key_field); intern->value_type = upb_fielddef_type(value_field); - intern->msg_ce = field_type_class(value_field); + intern->msg_ce = field_type_class(value_field TSRMLS_CC); } static void map_field_free_element(void *object) { @@ -270,7 +270,7 @@ static bool *map_field_read_dimension(zval *object, zval *key, int type, #ifndef NDEBUG v.ctype = UPB_CTYPE_UINT64; #endif - if (!table_key(intern, key, keybuf, &keyval, &length)) { + if (!table_key(intern, key, keybuf, &keyval, &length TSRMLS_CC)) { return false; } @@ -303,13 +303,14 @@ static bool map_field_write_dimension(zval *object, zval *key, size_t length = 0; upb_value v; void* mem; - if (!table_key(intern, key, keybuf, &keyval, &length)) { + if (!table_key(intern, key, keybuf, &keyval, &length TSRMLS_CC)) { return false; } mem = upb_value_memory(&v); memset(mem, 0, native_slot_size(intern->value_type)); - if(!native_slot_set(intern->value_type, intern->msg_ce, mem, value)) { + if (!native_slot_set(intern->value_type, intern->msg_ce, mem, value + TSRMLS_CC)) { return false; } #ifndef NDEBUG @@ -333,7 +334,7 @@ static bool map_field_unset_dimension(zval *object, zval *key TSRMLS_DC) { const char* keyval = NULL; size_t length = 0; upb_value v; - if (!table_key(intern, key, keybuf, &keyval, &length)) { + if (!table_key(intern, key, keybuf, &keyval, &length TSRMLS_CC)) { return false; } #ifndef NDEBUG @@ -396,7 +397,7 @@ PHP_METHOD(MapField, offsetExists) { #ifndef NDEBUG v.ctype = UPB_CTYPE_UINT64; #endif - if (!table_key(intern, key, keybuf, &keyval, &length)) { + if (!table_key(intern, key, keybuf, &keyval, &length TSRMLS_CC)) { return false; } @@ -446,7 +447,7 @@ PHP_METHOD(MapField, count) { // Map Iterator // ----------------------------------------------------------------------------- -void map_begin(zval *map_php, MapIter *iter) { +void map_begin(zval *map_php, MapIter *iter TSRMLS_DC) { Map *self = UNBOX(Map, map_php); map_begin_internal(self, iter); } diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c index 0cae6dba5d58e..cb46031eb7e7c 100644 --- a/php/ext/google/protobuf/message.c +++ b/php/ext/google/protobuf/message.c @@ -96,7 +96,7 @@ static void message_set_property(zval* object, zval* member, zval* value, zend_error(E_USER_ERROR, "Unknown field: %s", Z_STRVAL_P(member)); } - layout_set(self->descriptor->layout, self, field, value); + layout_set(self->descriptor->layout, self, field, value TSRMLS_CC); } static zval* message_get_property(zval* object, zval* member, int type, @@ -177,7 +177,8 @@ static zend_object_value message_create(zend_class_entry* ce TSRMLS_DC) { zend_object_std_init(&msg->std, ce TSRMLS_CC); object_properties_init(&msg->std, ce); - layout_init(desc->layout, message_data(msg), msg->std.properties_table); + layout_init(desc->layout, message_data(msg), msg->std.properties_table + TSRMLS_CC); return_value.handle = zend_objects_store_put( msg, (zend_objects_store_dtor_t)zend_objects_destroy_object, message_free, diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h index b3ad20dd920f4..5edb15db3db91 100644 --- a/php/ext/google/protobuf/protobuf.h +++ b/php/ext/google/protobuf/protobuf.h @@ -233,11 +233,12 @@ struct MessageHeader { }; MessageLayout* create_layout(const upb_msgdef* msgdef); -void layout_init(MessageLayout* layout, void* storage, zval** properties_table); +void layout_init(MessageLayout* layout, void* storage, zval** properties_table + TSRMLS_DC); zval* layout_get(MessageLayout* layout, const void* storage, const upb_fielddef* field, zval** cache TSRMLS_DC); void layout_set(MessageLayout* layout, MessageHeader* header, - const upb_fielddef* field, zval* val); + const upb_fielddef* field, zval* val TSRMLS_DC); void free_layout(MessageLayout* layout); PHP_METHOD(Message, readOneof); @@ -293,7 +294,7 @@ PHP_METHOD(Util, checkRepeatedField); size_t native_slot_size(upb_fieldtype_t type); bool native_slot_set(upb_fieldtype_t type, const zend_class_entry* klass, - void* memory, zval* value); + void* memory, zval* value TSRMLS_DC); void native_slot_init(upb_fieldtype_t type, void* memory, zval** cache); // For each property, in order to avoid conversion between the zval object and // the actual data type during parsing/serialization, the containing message @@ -325,7 +326,7 @@ typedef struct { upb_strtable_iter it; } MapIter; -void map_begin(zval* self, MapIter* iter); +void map_begin(zval* self, MapIter* iter TSRMLS_DC); void map_next(MapIter* iter); bool map_done(MapIter* iter); const char* map_iter_key(MapIter* iter, int* len); @@ -377,10 +378,10 @@ void repeated_field_create_with_type(zend_class_entry* ce, zval** repeated_field TSRMLS_DC); // Return the element at the index position from the repeated field. There is // not restriction on the type of stored elements. -void *repeated_field_index_native(RepeatedField *intern, int index); +void *repeated_field_index_native(RepeatedField *intern, int index TSRMLS_DC); // Add the element to the end of the repeated field. There is not restriction on // the type of stored elements. -void repeated_field_push_native(RepeatedField *intern, void *value); +void repeated_field_push_native(RepeatedField *intern, void *value TSRMLS_DC); PHP_METHOD(RepeatedField, __construct); PHP_METHOD(RepeatedField, append); @@ -411,7 +412,7 @@ typedef struct { // ----------------------------------------------------------------------------- upb_fieldtype_t to_fieldtype(upb_descriptortype_t type); -const zend_class_entry *field_type_class(const upb_fielddef *field); +const zend_class_entry *field_type_class(const upb_fielddef *field TSRMLS_DC); // ----------------------------------------------------------------------------- // Utilities. diff --git a/php/ext/google/protobuf/storage.c b/php/ext/google/protobuf/storage.c index 7423552b54df2..56497f622cc00 100644 --- a/php/ext/google/protobuf/storage.c +++ b/php/ext/google/protobuf/storage.c @@ -56,7 +56,7 @@ size_t native_slot_size(upb_fieldtype_t type) { } bool native_slot_set(upb_fieldtype_t type, const zend_class_entry* klass, - void* memory, zval* value) { + void* memory, zval* value TSRMLS_DC) { switch (type) { case UPB_TYPE_STRING: case UPB_TYPE_BYTES: { @@ -295,7 +295,7 @@ const upb_fielddef* map_entry_value(const upb_msgdef* msgdef) { return value_field; } -const zend_class_entry* field_type_class(const upb_fielddef* field) { +const zend_class_entry* field_type_class(const upb_fielddef* field TSRMLS_DC) { if (upb_fielddef_type(field) == UPB_TYPE_MESSAGE) { zval* desc_php = get_def_obj(upb_fielddef_subdef(field)); Descriptor* desc = zend_object_store_get_object(desc_php TSRMLS_CC); @@ -435,7 +435,8 @@ void free_layout(MessageLayout* layout) { FREE(layout); } -void layout_init(MessageLayout* layout, void* storage, zval** properties_table) { +void layout_init(MessageLayout* layout, void* storage, zval** properties_table + TSRMLS_DC) { int i; upb_msg_field_iter it; for (upb_msg_field_begin(&it, layout->msgdef), i = 0; !upb_msg_field_done(&it); @@ -451,11 +452,12 @@ void layout_init(MessageLayout* layout, void* storage, zval** properties_table) *oneof_case = ONEOF_CASE_NONE; } else if (is_map_field(field)) { zval_ptr_dtor(property_ptr); - map_field_create_with_type(map_field_type, field, property_ptr); + map_field_create_with_type(map_field_type, field, property_ptr TSRMLS_CC); DEREF(memory, zval**) = property_ptr; } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) { zval_ptr_dtor(property_ptr); - repeated_field_create_with_type(repeated_field_type, field, property_ptr); + repeated_field_create_with_type(repeated_field_type, field, property_ptr + TSRMLS_CC); DEREF(memory, zval**) = property_ptr; } else { native_slot_init(upb_fielddef_type(field), memory, property_ptr); @@ -501,8 +503,8 @@ zval* layout_get(MessageLayout* layout, const void* storage, } } -void layout_set(MessageLayout* layout, MessageHeader* header, const upb_fielddef* field, - zval* val) { +void layout_set(MessageLayout* layout, MessageHeader* header, + const upb_fielddef* field, zval* val TSRMLS_DC) { void* storage = message_data(header); void* memory = slot_memory(layout, storage, field); uint32_t* oneof_case = slot_oneof_case(layout, storage, field); @@ -535,7 +537,7 @@ void layout_set(MessageLayout* layout, MessageHeader* header, const upb_fielddef break; } - native_slot_set(type, ce, memory, val); + native_slot_set(type, ce, memory, val TSRMLS_CC); *oneof_case = upb_fielddef_number(field); } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) { // Works for both repeated and map fields @@ -554,6 +556,6 @@ void layout_set(MessageLayout* layout, MessageHeader* header, const upb_fielddef Descriptor* desc = zend_object_store_get_object(desc_php TSRMLS_CC); ce = desc->klass; } - native_slot_set(type, ce, value_memory(field, memory), val); + native_slot_set(type, ce, value_memory(field, memory), val TSRMLS_CC); } } From 75b69887aa446aeb7f1b6325ec826f2b5ddfa972 Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Wed, 5 Oct 2016 10:54:39 -0700 Subject: [PATCH 17/24] Fix segmentation fault when ZTS is defined. --- php/ext/google/protobuf/array.c | 3 +- php/ext/google/protobuf/encode_decode.c | 28 ++++++++++------- php/ext/google/protobuf/type_check.c | 1 - php/tests/array_test.php | 40 ++++++++++++------------- tests.sh | 1 + 5 files changed, 39 insertions(+), 34 deletions(-) diff --git a/php/ext/google/protobuf/array.c b/php/ext/google/protobuf/array.c index f96e95ec11c96..c24ede818ca7c 100644 --- a/php/ext/google/protobuf/array.c +++ b/php/ext/google/protobuf/array.c @@ -160,8 +160,7 @@ static void repeated_field_write_dimension(zval *object, zval *offset, unsigned char memory[NATIVE_SLOT_MAX_SIZE]; memset(memory, 0, NATIVE_SLOT_MAX_SIZE); - if (!native_slot_set(intern->type, intern->msg_ce, memory, value - TSRMLS_CC)) { + if (!native_slot_set(intern->type, intern->msg_ce, memory, value TSRMLS_CC)) { return; } diff --git a/php/ext/google/protobuf/encode_decode.c b/php/ext/google/protobuf/encode_decode.c index af90ff3320e6b..b45d1b2acec15 100644 --- a/php/ext/google/protobuf/encode_decode.c +++ b/php/ext/google/protobuf/encode_decode.c @@ -199,8 +199,9 @@ static void *startseq_handler(void* closure, const void* hd) { // Handlers that append primitive values to a repeated field. #define DEFINE_APPEND_HANDLER(type, ctype) \ static bool append##type##_handler(void* closure, const void* hd, \ - ctype val TSRMLS_DC) { \ + ctype val) { \ zval* array = (zval*)closure; \ + TSRMLS_FETCH(); \ RepeatedField* intern = \ (RepeatedField*)zend_object_store_get_object(array TSRMLS_CC); \ repeated_field_push_native(intern, &val TSRMLS_CC); \ @@ -218,8 +219,9 @@ DEFINE_APPEND_HANDLER(double, double) // Appends a string to a repeated field. static void* appendstr_handler(void *closure, const void *hd, - size_t size_hint TSRMLS_DC) { + size_t size_hint) { zval* array = (zval*)closure; + TSRMLS_FETCH(); RepeatedField* intern = (RepeatedField*)zend_object_store_get_object(array TSRMLS_CC); @@ -234,8 +236,9 @@ static void* appendstr_handler(void *closure, // Appends a 'bytes' string to a repeated field. static void* appendbytes_handler(void *closure, const void *hd, - size_t size_hint TSRMLS_DC) { + size_t size_hint) { zval* array = (zval*)closure; + TSRMLS_FETCH(); RepeatedField* intern = (RepeatedField*)zend_object_store_get_object(array TSRMLS_CC); @@ -296,8 +299,9 @@ static size_t stringdata_handler(void* closure, const void* hd, } // Appends a submessage to a repeated field. -static void *appendsubmsg_handler(void *closure, const void *hd TSRMLS_DC) { +static void *appendsubmsg_handler(void *closure, const void *hd) { zval* array = (zval*)closure; + TSRMLS_FETCH(); RepeatedField* intern = (RepeatedField*)zend_object_store_get_object(array TSRMLS_CC); @@ -319,10 +323,11 @@ static void *appendsubmsg_handler(void *closure, const void *hd TSRMLS_DC) { } // Sets a non-repeated submessage field in a message. -static void *submsg_handler(void *closure, const void *hd TSRMLS_DC) { +static void *submsg_handler(void *closure, const void *hd) { MessageHeader* msg = closure; const submsg_handlerdata_t* submsgdata = hd; zval* subdesc_php = get_def_obj((void*)submsgdata->md); + TSRMLS_FETCH(); Descriptor* subdesc = zend_object_store_get_object(subdesc_php TSRMLS_CC); zend_class_entry* subklass = subdesc->klass; zval* submsg_php; @@ -465,11 +470,11 @@ static void *startmapentry_handler(void *closure, const void *hd) { // Handler to end a map entry: inserts the value defined during the message into // the map. This is the 'endmsg' handler on the map entry msgdef. -static bool endmap_handler(void *closure, const void *hd, upb_status* s - TSRMLS_DC) { +static bool endmap_handler(void* closure, const void* hd, upb_status* s) { map_parse_frame_t* frame = closure; const map_handlerdata_t* mapdata = hd; + TSRMLS_FETCH(); Map *map = (Map *)zend_object_store_get_object(frame->map TSRMLS_CC); const char* keyval = NULL; @@ -575,12 +580,12 @@ static void *oneofbytes_handler(void *closure, } // Handler for a submessage field in a oneof. -static void *oneofsubmsg_handler(void *closure, - const void *hd TSRMLS_DC) { +static void* oneofsubmsg_handler(void* closure, const void* hd) { MessageHeader* msg = closure; const oneof_handlerdata_t *oneofdata = hd; uint32_t oldcase = DEREF(msg, oneofdata->case_ofs, uint32_t); zval* subdesc_php = get_def_obj((void*)oneofdata->md); + TSRMLS_FETCH(); Descriptor* subdesc = zend_object_store_get_object(subdesc_php TSRMLS_CC); zend_class_entry* subklass = subdesc->klass; zval* submsg_php; @@ -773,9 +778,10 @@ static void add_handlers_for_oneof_field(upb_handlers *h, upb_handlerattr_uninit(&attr); } -static void add_handlers_for_message(const void *closure, upb_handlers *h - TSRMLS_DC) { +static void add_handlers_for_message(const void* closure, + upb_handlers* h) { const upb_msgdef* msgdef = upb_handlers_msgdef(h); + TSRMLS_FETCH(); Descriptor* desc = (Descriptor*)zend_object_store_get_object( get_def_obj((void*)msgdef) TSRMLS_CC); upb_msg_field_iter i; diff --git a/php/ext/google/protobuf/type_check.c b/php/ext/google/protobuf/type_check.c index fe9359fc5ef6e..c215d72ef2dd9 100644 --- a/php/ext/google/protobuf/type_check.c +++ b/php/ext/google/protobuf/type_check.c @@ -214,7 +214,6 @@ bool protobuf_convert_to_bool(zval* from, int8_t* to) { } else { *to = 1; } - STR_FREE(strval); } break; default: { zend_error(E_USER_ERROR, "Given value cannot be converted to bool."); diff --git a/php/tests/array_test.php b/php/tests/array_test.php index d683add5b6aa7..09d4dc8227577 100644 --- a/php/tests/array_test.php +++ b/php/tests/array_test.php @@ -789,26 +789,26 @@ public function testOffset() $this->assertSame(1, count($arr)); } - public function testInsertRemoval() - { - $arr = new RepeatedField(GPBType::INT32); - - $arr []= 0; - $arr []= 1; - $arr []= 2; - $this->assertSame(3, count($arr)); - - unset($arr[2]); - $this->assertSame(2, count($arr)); - $this->assertSame(0, $arr[0]); - $this->assertSame(1, $arr[1]); - - $arr [] = 3; - $this->assertSame(3, count($arr)); - $this->assertSame(0, $arr[0]); - $this->assertSame(1, $arr[1]); - $this->assertSame(3, $arr[2]); - } + public function testInsertRemoval() + { + $arr = new RepeatedField(GPBType::INT32); + + $arr []= 0; + $arr []= 1; + $arr []= 2; + $this->assertSame(3, count($arr)); + + unset($arr[2]); + $this->assertSame(2, count($arr)); + $this->assertSame(0, $arr[0]); + $this->assertSame(1, $arr[1]); + + $arr [] = 3; + $this->assertSame(3, count($arr)); + $this->assertSame(0, $arr[0]); + $this->assertSame(1, $arr[1]); + $this->assertSame(3, $arr[2]); + } /** * @expectedException PHPUnit_Framework_Error diff --git a/tests.sh b/tests.sh index ccf49f00804f0..5823bff5f3179 100755 --- a/tests.sh +++ b/tests.sh @@ -377,6 +377,7 @@ build_php5.5_mac() { build_php5.5_zts_c() { use_php_zts 5.5 + wget https://phar.phpunit.de/phpunit-old.phar -O /usr/bin/phpunit cd php/tests && /bin/bash ./test.sh && cd ../.. } From 96e2d76491f7ea8aa33b524e7b0a2194b05c473a Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Wed, 5 Oct 2016 18:28:13 -0700 Subject: [PATCH 18/24] Fix compile error for php on Mac. --- .travis.yml | 2 +- php/ext/google/protobuf/array.c | 8 ++++---- php/ext/google/protobuf/def.c | 3 ++- php/ext/google/protobuf/encode_decode.c | 6 ++++-- php/ext/google/protobuf/map.c | 11 ++++++----- php/ext/google/protobuf/protobuf.c | 12 ++++++++++-- php/ext/google/protobuf/protobuf.h | 9 +-------- php/ext/google/protobuf/storage.c | 11 +++++++---- php/ext/google/protobuf/utf8.c | 2 +- php/tests/test.sh | 5 ----- tests.sh | 25 +++++++++++++++++++------ 11 files changed, 55 insertions(+), 39 deletions(-) diff --git a/.travis.yml b/.travis.yml index d331a26e3c5bc..fd54ed1f434e1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,7 +30,7 @@ env: - CONFIG=ruby21 - CONFIG=ruby22 - CONFIG=jruby - - CONFIG=php5.5_mac + - CONFIG=php5.6_mac matrix: exclude: # It's nontrivial to programmatically install a new JDK from the command diff --git a/php/ext/google/protobuf/array.c b/php/ext/google/protobuf/array.c index c24ede818ca7c..215dcd467c118 100644 --- a/php/ext/google/protobuf/array.c +++ b/php/ext/google/protobuf/array.c @@ -169,7 +169,7 @@ static void repeated_field_write_dimension(zval *object, zval *offset, } else { if (protobuf_convert_to_uint64(offset, &index)) { if (!zend_hash_index_exists(ht, index)) { - zend_error(E_USER_ERROR, "Element at %d doesn't exist.\n", index); + zend_error(E_USER_ERROR, "Element at %llu doesn't exist.\n", index); return; } } else { @@ -222,7 +222,7 @@ void repeated_field_create_with_type(zend_class_entry *ce, zend_object_store_get_object(*repeated_field TSRMLS_CC); intern->type = upb_fielddef_type(field); if (intern->type == UPB_TYPE_MESSAGE) { - upb_msgdef *msg = upb_fielddef_msgsubdef(field); + const upb_msgdef *msg = upb_fielddef_msgsubdef(field); zval *desc_php = get_def_obj(msg); Descriptor *desc = zend_object_store_get_object(desc_php TSRMLS_CC); intern->msg_ce = desc->klass; @@ -321,7 +321,7 @@ PHP_METHOD(RepeatedField, offsetGet) { HashTable *table = HASH_OF(intern->array); if (zend_hash_index_find(table, index, (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; } @@ -365,7 +365,7 @@ PHP_METHOD(RepeatedField, offsetUnset) { // Only the element at the end of the array can be removed. if (index == -1 || index != (zend_hash_num_elements(HASH_OF(intern->array)) - 1)) { - zend_error(E_USER_ERROR, "Cannot remove element at %d.\n", index); + zend_error(E_USER_ERROR, "Cannot remove element at %ld.\n", index); return; } diff --git a/php/ext/google/protobuf/def.c b/php/ext/google/protobuf/def.c index cbd0ec62db2b8..156eca07f373c 100644 --- a/php/ext/google/protobuf/def.c +++ b/php/ext/google/protobuf/def.c @@ -318,7 +318,8 @@ PHP_METHOD(DescriptorPool, internalAddGeneratedFile) { add_def_obj(desc->def_type_lower, desc_php); \ /* Unlike other messages, MapEntry is shared by all map fields and doesn't \ * have generated PHP class.*/ \ - if (upb_def_type(def) == UPB_DEF_MSG && upb_msgdef_mapentry(def)) { \ + if (upb_def_type(def) == UPB_DEF_MSG && \ + upb_msgdef_mapentry(upb_downcast_msgdef(def))) { \ break; \ } \ /* Prepend '.' to package name to make it absolute. */ \ diff --git a/php/ext/google/protobuf/encode_decode.c b/php/ext/google/protobuf/encode_decode.c index b45d1b2acec15..eafe1ae8328c9 100644 --- a/php/ext/google/protobuf/encode_decode.c +++ b/php/ext/google/protobuf/encode_decode.c @@ -29,6 +29,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "protobuf.h" +#include "utf8.h" /* stringsink *****************************************************************/ @@ -416,7 +417,8 @@ static void map_slot_uninit(void* memory, upb_fieldtype_t type) { } } -static void map_slot_key(upb_fieldtype_t type, const void* from, char** keyval, +static void map_slot_key(upb_fieldtype_t type, const void* from, + const char** keyval, size_t* length) { if (type == UPB_TYPE_STRING) { zval* key_php = **(zval***)from; @@ -891,7 +893,7 @@ static upb_selector_t getsel(const upb_fielddef* f, upb_handlertype_t type) { return ret; } -static void put_optional_value(void* memory, int len, const upb_fielddef* f, +static void put_optional_value(const void* memory, int len, const upb_fielddef* f, int depth, upb_sink* sink TSRMLS_DC) { assert(upb_fielddef_label(f) == UPB_LABEL_OPTIONAL); diff --git a/php/ext/google/protobuf/map.c b/php/ext/google/protobuf/map.c index 6a80d978fbf2b..35747b05c853d 100644 --- a/php/ext/google/protobuf/map.c +++ b/php/ext/google/protobuf/map.c @@ -33,6 +33,7 @@ #include #include "protobuf.h" +#include "utf8.h" ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetGet, 0, 0, 1) ZEND_ARG_INFO(0, index) @@ -152,7 +153,7 @@ static zend_function_entry map_field_methods[] = { zend_class_entry* map_field_type; zend_object_handlers* map_field_handlers; -static map_begin_internal(Map *map, MapIter *iter) { +static void map_begin_internal(Map *map, MapIter *iter) { iter->self = map; upb_strtable_begin(&iter->it, &map->table); } @@ -258,8 +259,8 @@ static void map_field_free_element(void *object) { // MapField Handlers // ----------------------------------------------------------------------------- -static bool *map_field_read_dimension(zval *object, zval *key, int type, - zval **retval TSRMLS_DC) { +static bool map_field_read_dimension(zval *object, zval *key, int type, + zval **retval TSRMLS_DC) { Map *intern = (Map *)zend_object_store_get_object(object TSRMLS_CC); @@ -398,7 +399,7 @@ PHP_METHOD(MapField, offsetExists) { v.ctype = UPB_CTYPE_UINT64; #endif if (!table_key(intern, key, keybuf, &keyval, &length TSRMLS_CC)) { - return false; + RETURN_BOOL(false); } RETURN_BOOL(upb_strtable_lookup2(&intern->table, keyval, length, &v)); @@ -434,7 +435,7 @@ PHP_METHOD(MapField, offsetUnset) { PHP_METHOD(MapField, count) { Map *intern = - (MapField *)zend_object_store_get_object(getThis() TSRMLS_CC); + (Map *)zend_object_store_get_object(getThis() TSRMLS_CC); if (zend_parse_parameters_none() == FAILURE) { return; diff --git a/php/ext/google/protobuf/protobuf.c b/php/ext/google/protobuf/protobuf.c index d8ad3c8824ebe..019bca29813f9 100644 --- a/php/ext/google/protobuf/protobuf.c +++ b/php/ext/google/protobuf/protobuf.c @@ -55,7 +55,7 @@ static void add_to_table(HashTable* t, const void* def, void* value) { uint nIndex = (ulong)def & t->nTableMask; zval* pDest = NULL; - zend_hash_index_update(t, (zend_ulong)def, &value, sizeof(zval*), &pDest); + zend_hash_index_update(t, (zend_ulong)def, &value, sizeof(zval*), (void**)&pDest); } static void* get_from_table(const HashTable* t, const void* def) { @@ -69,7 +69,7 @@ static void* get_from_table(const HashTable* t, const void* def) { static void add_to_list(HashTable* t, void* value) { zval* pDest = NULL; - zend_hash_next_index_insert(t, &value, sizeof(void*), &pDest); + zend_hash_next_index_insert(t, &value, sizeof(void*), (void**)&pDest); } void add_def_obj(const void* def, zval* value) { @@ -134,6 +134,8 @@ static PHP_RINIT_FUNCTION(protobuf) { generated_pool = NULL; generated_pool_php = NULL; + + return 0; } static PHP_RSHUTDOWN_FUNCTION(protobuf) { @@ -147,6 +149,8 @@ static PHP_RSHUTDOWN_FUNCTION(protobuf) { zval_dtor(generated_pool_php); FREE_ZVAL(generated_pool_php); } + + return 0; } static PHP_MINIT_FUNCTION(protobuf) { @@ -158,10 +162,14 @@ static PHP_MINIT_FUNCTION(protobuf) { descriptor_init(TSRMLS_C); enum_descriptor_init(TSRMLS_C); util_init(TSRMLS_C); + + return 0; } static PHP_MSHUTDOWN_FUNCTION(protobuf) { PEFREE(message_handlers); PEFREE(repeated_field_handlers); PEFREE(map_field_handlers); + + return 0; } diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h index 5edb15db3db91..8a1d9261d7c96 100644 --- a/php/ext/google/protobuf/protobuf.h +++ b/php/ext/google/protobuf/protobuf.h @@ -70,14 +70,6 @@ typedef struct MapField MapField; ZEND_BEGIN_MODULE_GLOBALS(protobuf) ZEND_END_MODULE_GLOBALS(protobuf) -ZEND_DECLARE_MODULE_GLOBALS(protobuf) - -#ifdef ZTS -#define PROTOBUF_G(v) TSRMG(protobuf_globals_id, zend_protobuf_globals*, v) -#else -#define PROTOBUF_G(v) (protobuf_globals.v) -#endif - // Init module and PHP classes. void descriptor_init(TSRMLS_D); void enum_descriptor_init(TSRMLS_D); @@ -347,6 +339,7 @@ void* upb_value_memory(upb_value* v); // These operate on a map field (i.e., a repeated field of submessages whose // submessage type is a map-entry msgdef). +bool is_map_field(const upb_fielddef* field); const upb_fielddef* map_field_key(const upb_fielddef* field); const upb_fielddef* map_field_value(const upb_fielddef* field); diff --git a/php/ext/google/protobuf/storage.c b/php/ext/google/protobuf/storage.c index 56497f622cc00..e94aa3196873d 100644 --- a/php/ext/google/protobuf/storage.c +++ b/php/ext/google/protobuf/storage.c @@ -32,6 +32,8 @@ #include #include +#include "utf8.h" + // ----------------------------------------------------------------------------- // Native slot storage. // ----------------------------------------------------------------------------- @@ -210,7 +212,7 @@ CASE(ENUM, LONG, uint32_t) return; } default: - return EG(uninitialized_zval_ptr); + return; } } @@ -245,7 +247,7 @@ void native_slot_get_default(upb_fieldtype_t type, zval** cache TSRMLS_DC) { return; } default: - return EG(uninitialized_zval_ptr); + return; } } @@ -305,6 +307,7 @@ const zend_class_entry* field_type_class(const upb_fielddef* field TSRMLS_DC) { EnumDescriptor* desc = zend_object_store_get_object(desc_php TSRMLS_CC); return desc->klass; } + return NULL; } // ----------------------------------------------------------------------------- @@ -517,7 +520,7 @@ void layout_set(MessageLayout* layout, MessageHeader* header, // zval in properties table first. switch (type) { case UPB_TYPE_MESSAGE: { - upb_msgdef* msg = upb_fielddef_msgsubdef(field); + const upb_msgdef* msg = upb_fielddef_msgsubdef(field); zval* desc_php = get_def_obj(msg); Descriptor* desc = zend_object_store_get_object(desc_php TSRMLS_CC); ce = desc->klass; @@ -551,7 +554,7 @@ void layout_set(MessageLayout* layout, MessageHeader* header, upb_fieldtype_t type = upb_fielddef_type(field); zend_class_entry *ce = NULL; if (type == UPB_TYPE_MESSAGE) { - upb_msgdef* msg = upb_fielddef_msgsubdef(field); + const upb_msgdef* msg = upb_fielddef_msgsubdef(field); zval* desc_php = get_def_obj(msg); Descriptor* desc = zend_object_store_get_object(desc_php TSRMLS_CC); ce = desc->klass; diff --git a/php/ext/google/protobuf/utf8.c b/php/ext/google/protobuf/utf8.c index a1541636b1b97..2752a08b05937 100644 --- a/php/ext/google/protobuf/utf8.c +++ b/php/ext/google/protobuf/utf8.c @@ -58,7 +58,7 @@ bool is_structurally_valid_utf8(const char* buf, int len) { return false; } for (j = i + 1; j < i + offset; j++) { - if (buf[j] & 0xc0 != 0x80) { + if ((buf[j] & 0xc0) != 0x80) { return false; } } diff --git a/php/tests/test.sh b/php/tests/test.sh index 15df768cd6c16..888e93eb0a218 100755 --- a/php/tests/test.sh +++ b/php/tests/test.sh @@ -24,9 +24,4 @@ done # Make sure to run the memory test in debug mode. php -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php -php --version -which php -pwd -ls -ls -l `which php` USE_ZEND_ALLOC=0 valgrind --leak-check=yes php -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php diff --git a/tests.sh b/tests.sh index 5823bff5f3179..a497f1d2c2111 100755 --- a/tests.sh +++ b/tests.sh @@ -369,12 +369,6 @@ build_php5.5_c() { cd php/tests && /bin/bash ./test.sh && cd ../.. } -build_php5.5_mac() { - curl -s https://php-osx.liip.ch/install.sh | bash -s 5.5 - export PATH="/usr/local/php5-5.5.38-20160831-100002/bin:$PATH" - cd php/tests && /bin/bash ./test.sh && cd ../.. -} - build_php5.5_zts_c() { use_php_zts 5.5 wget https://phar.phpunit.de/phpunit-old.phar -O /usr/bin/phpunit @@ -393,6 +387,25 @@ build_php5.6_c() { cd php/tests && /bin/bash ./test.sh && cd ../.. } +build_php5.6_mac() { + # Install PHP + curl -s https://php-osx.liip.ch/install.sh | bash -s 5.6 + export PATH="/usr/local/php5-5.6.25-20160831-101628/bin:$PATH" + + # Install phpunit + curl https://phar.phpunit.de/phpunit.phar -L -o phpunit.phar + chmod +x phpunit.phar + sudo mv phpunit.phar /usr/local/bin/phpunit + + # Install valgrind + echo "#! /bin/bash" > valgrind + chmod ug+x valgrind + sudo mv valgrind /usr/local/bin/valgrind + + # Test + cd php/tests && /bin/bash ./test.sh && cd ../.. +} + build_php7.0() { use_php 7.0 rm -rf vendor From b0d62dd71388813658222172a42383eca2e37c06 Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Thu, 6 Oct 2016 10:23:34 -0700 Subject: [PATCH 19/24] Add csharp/build_tools.sh for dist check. --- Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.am b/Makefile.am index 83f1043d13b57..69d162e1fe970 100644 --- a/Makefile.am +++ b/Makefile.am @@ -54,6 +54,7 @@ csharp_EXTRA_DIST= \ csharp/Google.Protobuf.Tools.nuspec \ csharp/README.md \ csharp/build_packages.bat \ + csharp/build_tools.sh \ csharp/buildall.sh \ csharp/generate_protos.sh \ csharp/keys/Google.Protobuf.public.snk \ From bc3bff165fac28f7ad967d70dcf572ccb062c481 Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Fri, 7 Oct 2016 16:09:26 -0700 Subject: [PATCH 20/24] Fix python_cpp test on Mac. Link staticly when building extension, so that the extension doesn't require installing protobuf library. (#2232) --- python/tox.ini | 2 +- tests.sh | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/python/tox.ini b/python/tox.ini index cf8d540168511..1600db21fc758 100644 --- a/python/tox.ini +++ b/python/tox.ini @@ -12,7 +12,7 @@ setenv = commands = python setup.py -q build_py python: python setup.py -q build - cpp: python setup.py -q build --cpp_implementation --warnings_as_errors + cpp: python setup.py -q build --cpp_implementation --warnings_as_errors --compile_static_extension python: python setup.py -q test -q cpp: python setup.py -q test -q --cpp_implementation python: python setup.py -q test_conformance diff --git a/tests.sh b/tests.sh index a497f1d2c2111..fb7044f3334d0 100755 --- a/tests.sh +++ b/tests.sh @@ -28,7 +28,8 @@ internal_build_cpp() { fi ./autogen.sh - ./configure + ./configure CXXFLAGS="-fPIC" # -fPIC is needed for python cpp test. + # See python/setup.py for more details make -j2 } From 60d95f36c0081a03b947c2b625c10841bb19736c Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Tue, 11 Oct 2016 10:36:25 -0700 Subject: [PATCH 21/24] Fix the bug that message without namespace is not found in the descriptor pool. (#2240) --- Makefile.am | 2 ++ php/ext/google/protobuf/def.c | 46 +++++++++++++++----------- php/src/Google/Protobuf/descriptor.php | 10 ++++-- php/tests/generated_class_test.php | 9 +++++ php/tests/test_no_namespace.pb.php | 34 +++++++++++++++++++ php/tests/test_no_namespace.proto | 5 +++ 6 files changed, 83 insertions(+), 23 deletions(-) create mode 100644 php/tests/test_no_namespace.pb.php create mode 100644 php/tests/test_no_namespace.proto diff --git a/Makefile.am b/Makefile.am index 69d162e1fe970..de19708875eb3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -600,6 +600,8 @@ php_EXTRA_DIST= \ php/tests/test_include.pb.php \ php/tests/map_field_test.php \ php/tests/test_base.php \ + php/tests/test_no_namespace.proto \ + php/tests/test_no_namespace.pb.php \ php/tests/test_util.php \ php/tests/test.proto \ php/tests/test.pb.php \ diff --git a/php/ext/google/protobuf/def.c b/php/ext/google/protobuf/def.c index 156eca07f373c..5a8c3c258918a 100644 --- a/php/ext/google/protobuf/def.c +++ b/php/ext/google/protobuf/def.c @@ -250,28 +250,36 @@ PHP_METHOD(DescriptorPool, getGeneratedPool) { RETURN_ZVAL(generated_pool_php, 1, 0); } -static void convert_to_class_name_inplace(char *proto_name, - size_t pkg_name_len) { +static void convert_to_class_name_inplace(char *class_name, + const char* fullname, + const char* package_name) { size_t i; bool first_char = false; - - for (i = 0; i <= pkg_name_len + 1; i++) { - // PHP package uses camel case. - if (!first_char && proto_name[i] != '.') { - first_char = true; - proto_name[i] += 'A' - 'a'; - } - // php packages are divided by '\'. - if (proto_name[i] == '.') { - first_char = false; - proto_name[i] = '\\'; + size_t pkg_name_len = package_name == NULL ? 0 : strlen(package_name); + + if (pkg_name_len == 0) { + strcpy(class_name, fullname); + } else { + class_name[0] = '.'; + strcpy(&class_name[1], fullname); + for (i = 0; i <= pkg_name_len + 1; i++) { + // PHP package uses camel case. + if (!first_char && class_name[i] != '.') { + first_char = true; + class_name[i] += 'A' - 'a'; + } + // php packages are divided by '\'. + if (class_name[i] == '.') { + first_char = false; + class_name[i] = '\\'; + } } } // Submessage is concatenated with its containing messages by '_'. - for (i = pkg_name_len; i < strlen(proto_name); i++) { - if (proto_name[i] == '.') { - proto_name[i] = '_'; + for (i = pkg_name_len; i < strlen(class_name); i++) { + if (class_name[i] == '.') { + class_name[i] = '_'; } } } @@ -325,10 +333,8 @@ PHP_METHOD(DescriptorPool, internalAddGeneratedFile) { /* Prepend '.' to package name to make it absolute. */ \ const char *fullname = upb_##def_type_lower##_fullname(def_type_lower); \ char *klass_name = ecalloc(sizeof(char), 2 + strlen(fullname)); \ - klass_name[0] = '.'; \ - strcpy(&klass_name[1], fullname); \ - size_t pkg_name_len = strlen(upb_filedef_package(files[0])); \ - convert_to_class_name_inplace(klass_name, pkg_name_len); \ + convert_to_class_name_inplace(klass_name, fullname, \ + upb_filedef_package(files[0])); \ zend_class_entry **pce; \ if (zend_lookup_class(klass_name, strlen(klass_name), &pce TSRMLS_CC) == \ FAILURE) { \ diff --git a/php/src/Google/Protobuf/descriptor.php b/php/src/Google/Protobuf/descriptor.php index afe082277c118..e5cff0baea9a2 100644 --- a/php/src/Google/Protobuf/descriptor.php +++ b/php/src/Google/Protobuf/descriptor.php @@ -240,9 +240,13 @@ function getFullClassName( $class_name_without_package = implode('_', array_map('ucwords', explode('.', $message_name_without_package))); - $classname = - implode('\\', array_map('ucwords', explode('.', $package))). - "\\".$class_name_without_package; + if ($package === "") { + $classname = $class_name_without_package; + } else { + $classname = + implode('\\', array_map('ucwords', explode('.', $package))). + "\\".$class_name_without_package; + } } class OneofDescriptor diff --git a/php/tests/generated_class_test.php b/php/tests/generated_class_test.php index 56466caee1f72..d1a0bd51c85c6 100644 --- a/php/tests/generated_class_test.php +++ b/php/tests/generated_class_test.php @@ -1,6 +1,7 @@ assertSame('', $m->getOneofString()); $this->assertSame(1, $m->getOneofMessage()->getA()); } + + ######################################################### + # Test oneof field. + ######################################################### + + public function testMessageWithoutNamespace() { + $m = new NoNameSpace(); + } } diff --git a/php/tests/test_no_namespace.pb.php b/php/tests/test_no_namespace.pb.php new file mode 100644 index 0000000000000..2f92c955c4ca1 --- /dev/null +++ b/php/tests/test_no_namespace.pb.php @@ -0,0 +1,34 @@ +a; + } + + public function setA($var) + { + GPBUtil::checkInt32($var); + $this->a = $var; + } + +} + +$pool = DescriptorPool::getGeneratedPool(); + +$pool->internalAddGeneratedFile(hex2bin( + "0a3b0a17746573745f6e6f5f6e616d6573706163652e70726f746f22180a" . + "0b4e6f4e616d65537061636512090a0161180120012805620670726f746f" . + "33" +)); + diff --git a/php/tests/test_no_namespace.proto b/php/tests/test_no_namespace.proto new file mode 100644 index 0000000000000..4331aeabe9309 --- /dev/null +++ b/php/tests/test_no_namespace.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +message NoNameSpace { + int32 a = 1; +} From 2286e5f4d00c478d6f7f5abcd21c0e570feeb17c Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Mon, 21 Nov 2016 12:01:51 -0800 Subject: [PATCH 22/24] Rename Empty to GPBEmpty in php generated file. (#2379) In php, class name cannot be "Empty". Modified code generator to (#2375) generate GPBEmpty instead (for google.protobuf.Empty only). Also change runtime code to work with the new generated code accordingly. --- php/ext/google/protobuf/def.c | 11 ++++++-- php/ext/google/protobuf/message.c | 4 +-- php/src/Google/Protobuf/descriptor.php | 15 +++++++++- php/tests/google/protobuf/empty.pb.php | 28 +++++++++++++++++++ php/tests/test.sh | 2 +- php/tests/well_known_test.php | 13 +++++++++ phpunit.xml | 1 + .../protobuf/compiler/php/php_generator.cc | 18 ++++++++++-- 8 files changed, 84 insertions(+), 8 deletions(-) create mode 100644 php/tests/google/protobuf/empty.pb.php create mode 100644 php/tests/well_known_test.php diff --git a/php/ext/google/protobuf/def.c b/php/ext/google/protobuf/def.c index 5a8c3c258918a..6ea2cc938e8b1 100644 --- a/php/ext/google/protobuf/def.c +++ b/php/ext/google/protobuf/def.c @@ -257,6 +257,11 @@ static void convert_to_class_name_inplace(char *class_name, bool first_char = false; size_t pkg_name_len = package_name == NULL ? 0 : strlen(package_name); + // In php, class name cannot be Empty. + if (strcmp("google.protobuf.Empty", fullname) == 0) { + fullname = "google.protobuf.GPBEmpty"; + } + if (pkg_name_len == 0) { strcpy(class_name, fullname); } else { @@ -330,9 +335,11 @@ PHP_METHOD(DescriptorPool, internalAddGeneratedFile) { upb_msgdef_mapentry(upb_downcast_msgdef(def))) { \ break; \ } \ - /* Prepend '.' to package name to make it absolute. */ \ + /* Prepend '.' to package name to make it absolute. In the 5 additional \ + * bytes allocated, one for '.', one for trailing 0, and 3 for 'GPB' if \ + * given message is google.protobuf.Empty.*/ \ const char *fullname = upb_##def_type_lower##_fullname(def_type_lower); \ - char *klass_name = ecalloc(sizeof(char), 2 + strlen(fullname)); \ + char *klass_name = ecalloc(sizeof(char), 5 + strlen(fullname)); \ convert_to_class_name_inplace(klass_name, fullname, \ upb_filedef_package(files[0])); \ zend_class_entry **pce; \ diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c index cb46031eb7e7c..d8fbbe11fff1f 100644 --- a/php/ext/google/protobuf/message.c +++ b/php/ext/google/protobuf/message.c @@ -177,8 +177,8 @@ static zend_object_value message_create(zend_class_entry* ce TSRMLS_DC) { zend_object_std_init(&msg->std, ce TSRMLS_CC); object_properties_init(&msg->std, ce); - layout_init(desc->layout, message_data(msg), msg->std.properties_table - TSRMLS_CC); + layout_init(desc->layout, message_data(msg), + msg->std.properties_table TSRMLS_CC); return_value.handle = zend_objects_store_put( msg, (zend_objects_store_dtor_t)zend_objects_destroy_object, message_free, diff --git a/php/src/Google/Protobuf/descriptor.php b/php/src/Google/Protobuf/descriptor.php index e5cff0baea9a2..ef6b9dcf47ecd 100644 --- a/php/src/Google/Protobuf/descriptor.php +++ b/php/src/Google/Protobuf/descriptor.php @@ -215,6 +215,18 @@ public static function buildFromProto($proto, $package, $containing) return $desc; } } + +function addPrefixIfSpecial( + $name, + $package) +{ + if ($name === "Empty" && $package === "google.protobuf") { + return "GPBEmpty"; + } else { + return $name; + } +} + function getFullClassName( $proto, $containing, @@ -224,7 +236,8 @@ function getFullClassName( &$fullname) { // Full name needs to start with '.'. - $message_name_without_package = $proto->getName(); + $message_name_without_package = + addPrefixIfSpecial($proto->getName(), $package); if ($containing !== "") { $message_name_without_package = $containing . "." . $message_name_without_package; diff --git a/php/tests/google/protobuf/empty.pb.php b/php/tests/google/protobuf/empty.pb.php new file mode 100644 index 0000000000000..fdd0fe4fe3376 --- /dev/null +++ b/php/tests/google/protobuf/empty.pb.php @@ -0,0 +1,28 @@ +internalAddGeneratedFile(hex2bin( + "0ab7010a1b676f6f676c652f70726f746f6275662f656d7074792e70726f" . + "746f120f676f6f676c652e70726f746f62756622070a05456d7074794276" . + "0a13636f6d2e676f6f676c652e70726f746f627566420a456d7074795072" . + "6f746f50015a276769746875622e636f6d2f676f6c616e672f70726f746f" . + "6275662f7074797065732f656d707479f80101a20203475042aa021e476f" . + "6f676c652e50726f746f6275662e57656c6c4b6e6f776e54797065736206" . + "70726f746f33" +)); + diff --git a/php/tests/test.sh b/php/tests/test.sh index 888e93eb0a218..ba0666b33ad51 100755 --- a/php/tests/test.sh +++ b/php/tests/test.sh @@ -10,7 +10,7 @@ set -e phpize && ./configure --enable-debug CFLAGS='-g -O0' && make popd -tests=( array_test.php encode_decode_test.php generated_class_test.php map_field_test.php ) +tests=( array_test.php encode_decode_test.php generated_class_test.php map_field_test.php well_known_test.php ) for t in "${tests[@]}" do diff --git a/php/tests/well_known_test.php b/php/tests/well_known_test.php new file mode 100644 index 0000000000000..30715ba96b2fc --- /dev/null +++ b/php/tests/well_known_test.php @@ -0,0 +1,13 @@ +php/tests/encode_decode_test.php php/tests/generated_class_test.php php/tests/map_field_test.php + php/tests/well_known_test.php diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc index 75ddb4058b3c7..83e629b99744f 100644 --- a/src/google/protobuf/compiler/php/php_generator.cc +++ b/src/google/protobuf/compiler/php/php_generator.cc @@ -70,6 +70,16 @@ void GenerateEnum(const google::protobuf::EnumDescriptor* en, void Indent(google::protobuf::io::Printer* printer); void Outdent(google::protobuf::io::Printer* printer); +std::string MessagePrefix(const google::protobuf::Descriptor* message) { + // Empty cannot be php class name. + if (message->name() == "Empty" && + message->file()->package() == "google.protobuf") { + return "GPB"; + } else { + return ""; + } +} + std::string MessageName(const google::protobuf::Descriptor* message, bool is_descriptor) { string message_name = message->name(); @@ -78,6 +88,8 @@ std::string MessageName(const google::protobuf::Descriptor* message, message_name = descriptor->name() + '_' + message_name; descriptor = descriptor->containing_type(); } + message_name = MessagePrefix(message) + message_name; + return PhpName(message->file()->package(), is_descriptor) + '\\' + message_name; } @@ -483,8 +495,10 @@ void GenerateMessage(const string& name_prefix, return; } - string message_name = name_prefix.empty()? - message->name() : name_prefix + "_" + message->name(); + string message_name = + name_prefix.empty() + ? message->name() + : name_prefix + "_" + MessagePrefix(message) + message->name(); printer->Print( "class @name@ extends \\Google\\Protobuf\\Internal\\Message\n" From 0c34e86a51daaf267c2170a6da9c82fa1cb4f5f8 Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Tue, 22 Nov 2016 13:34:28 -0800 Subject: [PATCH 23/24] Fix php test on mac. (#2402) Previously, this has been fixed on master in 51c5ff889ccd3836c25f40baafb350f92c9ee103. --- tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests.sh b/tests.sh index fb7044f3334d0..7f280d8a95d09 100755 --- a/tests.sh +++ b/tests.sh @@ -391,7 +391,7 @@ build_php5.6_c() { build_php5.6_mac() { # Install PHP curl -s https://php-osx.liip.ch/install.sh | bash -s 5.6 - export PATH="/usr/local/php5-5.6.25-20160831-101628/bin:$PATH" + export PATH="/usr/local/php5/bin:$PATH" # Install phpunit curl https://phar.phpunit.de/phpunit.phar -L -o phpunit.phar From c6997885739bc9c71e467199c0034b01d36d4b5f Mon Sep 17 00:00:00 2001 From: Thomas Sondergaard Date: Mon, 28 Nov 2016 12:06:34 +0100 Subject: [PATCH 24/24] Export fixed_address_empty_string commit 98835fb8f8 broke use of protobuf as shared library on Windows. Example error message: error LNK2001: unresolved external symbol "class google::protobuf::internal::ExplicitlyConstructed,class std::allocator > > google::protobuf::internal::fixed_address_empty_string" --- src/google/protobuf/generated_message_util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/google/protobuf/generated_message_util.h b/src/google/protobuf/generated_message_util.h index 8dc64c49028b4..28ed495c3a5bc 100644 --- a/src/google/protobuf/generated_message_util.h +++ b/src/google/protobuf/generated_message_util.h @@ -111,7 +111,7 @@ class ExplicitlyConstructed { // Default empty string object. Don't use this directly. Instead, call // GetEmptyString() to get the reference. -extern ExplicitlyConstructed< ::std::string> fixed_address_empty_string; +LIBPROTOBUF_EXPORT extern ExplicitlyConstructed< ::std::string> fixed_address_empty_string; LIBPROTOBUF_EXPORT extern ProtobufOnceType empty_string_once_init_; LIBPROTOBUF_EXPORT void InitEmptyString();