Переглянути джерело

Ensure string field names for legacy projection

Andreas Braun 9 роки тому
батько
коміт
dcae136e88

+ 17 - 1
lib/Alcaeus/MongoDbAdapter/TypeConverter.php

@@ -98,6 +98,8 @@ class TypeConverter
      *
      * @param array $fields
      * @return array
+     *
+     * @throws \MongoException
      */
     public static function convertProjection($fields)
     {
@@ -105,7 +107,21 @@ class TypeConverter
             return [];
         }
 
-        $projection = TypeConverter::isNumericArray($fields) ? array_fill_keys($fields, true) : $fields;
+        if (! TypeConverter::isNumericArray($fields)) {
+            $projection = TypeConverter::fromLegacy($fields);
+        } else {
+            $projection = array_fill_keys(
+                array_map(function ($field) {
+                    if (!is_string($field)) {
+                        throw new \MongoException('field names must be strings', 8);
+                    }
+
+                    return $field;
+                }, $fields),
+                true
+            );
+        }
+
         return TypeConverter::fromLegacy($projection);
     }
 

+ 8 - 7
tests/Alcaeus/MongoDbAdapter/Mongo/MongoCollectionTest.php

@@ -492,24 +492,25 @@ class MongoCollectionTest extends TestCase
     public static function dataFindWithProjectionAndNumericKeys()
     {
         return [
-            'sequentialIntegersStartingWithZero' => [
-                ['0' => 'foo', '1' => 'bar', '2' => 'foobar'],
-                [0 => true, 1 => true],
-                ['0' => 'foo', '1' => 'bar'],
-            ],
             'sequentialIntegersStartingWithOne' => [
                 ['0' => 'foo', '1' => 'bar', '2' => 'foobar'],
                 [1 => true, 2 => true],
                 ['1' => 'bar', '2' => 'foobar'],
             ],
             'nonSequentialIntegers' => [
-                ['0' => 'foo', '1' => 'bar', '2' => 'foobar'],
+                ['0' => 'foo', '1' => 'bar', '2' => 'foobar', '3' => 'barfoo'],
                 [1 => true, 3 => true],
-                ['0' => 'foo', '2' => 'foobar'],
+                ['1' => 'bar', '3' => 'barfoo'],
             ]
         ];
     }
 
+    public function testFindWithProjectionAndSequentialNumericKeys()
+    {
+        $this->setExpectedException(\MongoException::class, 'field names must be strings', 8);
+        $this->getCollection()->findOne([], [true, false]);
+    }
+
     /**
      * @dataProvider dataFindWithProjectionExcludeId
      */