Răsfoiți Sursa

Fix the bug that message without namespace is not found in the descriptor pool. (#2240)

Paul Yang 9 ani în urmă
părinte
comite
60d95f36c0

+ 2 - 0
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                                      \

+ 26 - 20
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) {                                                             \

+ 7 - 3
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

+ 9 - 0
php/tests/generated_class_test.php

@@ -1,6 +1,7 @@
 <?php
 
 require_once('test.pb.php');
+require_once('test_no_namespace.pb.php');
 require_once('test_util.php');
 
 use Google\Protobuf\Internal\RepeatedField;
@@ -554,4 +555,12 @@ class GeneratedClassTest extends PHPUnit_Framework_TestCase
         $this->assertSame('', $m->getOneofString());
         $this->assertSame(1, $m->getOneofMessage()->getA());
     }
+
+    #########################################################
+    # Test oneof field.
+    #########################################################
+
+    public function testMessageWithoutNamespace() {
+      $m = new NoNameSpace();
+    }
 }

+ 34 - 0
php/tests/test_no_namespace.pb.php

@@ -0,0 +1,34 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: test_no_namespace.proto
+
+use Google\Protobuf\Internal\DescriptorPool;
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+class NoNameSpace extends \Google\Protobuf\Internal\Message
+{
+    private $a = 0;
+
+    public function getA()
+    {
+        return $this->a;
+    }
+
+    public function setA($var)
+    {
+        GPBUtil::checkInt32($var);
+        $this->a = $var;
+    }
+
+}
+
+$pool = DescriptorPool::getGeneratedPool();
+
+$pool->internalAddGeneratedFile(hex2bin(
+    "0a3b0a17746573745f6e6f5f6e616d6573706163652e70726f746f22180a" .
+    "0b4e6f4e616d65537061636512090a0161180120012805620670726f746f" .
+    "33"
+));
+

+ 5 - 0
php/tests/test_no_namespace.proto

@@ -0,0 +1,5 @@
+syntax = "proto3";
+
+message NoNameSpace {
+  int32 a = 1;
+}