diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 005534e0a..2a1f58f76 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -470,6 +470,10 @@ + + + + @@ -726,9 +730,6 @@ - - - @@ -745,9 +746,6 @@ - - - @@ -759,9 +757,6 @@ - - - @@ -789,11 +784,6 @@ - - - - - options['writeConcern']]]> diff --git a/src/Operation/BulkWrite.php b/src/Operation/BulkWrite.php index dc6dbb4c7..bac22e3b3 100644 --- a/src/Operation/BulkWrite.php +++ b/src/Operation/BulkWrite.php @@ -28,6 +28,7 @@ use MongoDB\Driver\WriteConcern; use MongoDB\Exception\InvalidArgumentException; use MongoDB\Exception\UnsupportedException; +use MongoDB\Exception\UnsupportedValueException; use function array_is_list; use function array_key_exists; @@ -35,6 +36,7 @@ use function current; use function is_array; use function is_bool; +use function is_object; use function key; use function MongoDB\is_document; use function MongoDB\is_first_key_operator; @@ -306,6 +308,10 @@ private function validateOperations(array $operations, ?DocumentCodec $codec, En // $args[0] was already validated above. Since DocumentCodec::encode will always return a Document // instance, there is no need to re-validate the returned value here. if ($codec) { + if (! is_object($args[0])) { + throw UnsupportedValueException::invalidEncodableValue($args[0]); + } + $operations[$i][$type][0] = $codec->encode($args[0]); } @@ -341,6 +347,10 @@ private function validateOperations(array $operations, ?DocumentCodec $codec, En } if ($codec) { + if (! is_object($args[1])) { + throw UnsupportedValueException::invalidEncodableValue($args[1]); + } + $operations[$i][$type][1] = $codec->encode($args[1]); } diff --git a/src/Operation/FindOneAndReplace.php b/src/Operation/FindOneAndReplace.php index 5ea0c5a34..26d1cf751 100644 --- a/src/Operation/FindOneAndReplace.php +++ b/src/Operation/FindOneAndReplace.php @@ -22,9 +22,11 @@ use MongoDB\Driver\Server; use MongoDB\Exception\InvalidArgumentException; use MongoDB\Exception\UnsupportedException; +use MongoDB\Exception\UnsupportedValueException; use function array_key_exists; use function is_integer; +use function is_object; use function MongoDB\is_document; use function MongoDB\is_first_key_operator; use function MongoDB\is_pipeline; @@ -170,11 +172,13 @@ public function getCommandDocument(): array private function validateReplacement(array|object $replacement, ?DocumentCodec $codec): array|object { - if (isset($codec)) { - $replacement = $codec->encode($replacement); - } + if ($codec) { + if (! is_object($replacement)) { + throw UnsupportedValueException::invalidEncodableValue($replacement); + } - if (! is_document($replacement)) { + $replacement = $codec->encode($replacement); + } elseif (! is_document($replacement)) { throw InvalidArgumentException::expectedDocumentType('$replacement', $replacement); } diff --git a/src/Operation/InsertMany.php b/src/Operation/InsertMany.php index 70e149076..0f7dd1c2a 100644 --- a/src/Operation/InsertMany.php +++ b/src/Operation/InsertMany.php @@ -25,10 +25,12 @@ use MongoDB\Driver\WriteConcern; use MongoDB\Exception\InvalidArgumentException; use MongoDB\Exception\UnsupportedException; +use MongoDB\Exception\UnsupportedValueException; use MongoDB\InsertManyResult; use function array_is_list; use function is_bool; +use function is_object; use function MongoDB\is_document; use function sprintf; @@ -190,10 +192,12 @@ private function validateDocuments(array $documents, ?DocumentCodec $codec): arr foreach ($documents as $i => $document) { if ($codec) { - $document = $documents[$i] = $codec->encode($document); - } + if (! is_object($document)) { + throw UnsupportedValueException::invalidEncodableValue($document); + } - if (! is_document($document)) { + $documents[$i] = $codec->encode($document); + } elseif (! is_document($document)) { throw InvalidArgumentException::expectedDocumentType(sprintf('$documents[%d]', $i), $document); } } diff --git a/src/Operation/InsertOne.php b/src/Operation/InsertOne.php index dff9f79f6..0e41db74d 100644 --- a/src/Operation/InsertOne.php +++ b/src/Operation/InsertOne.php @@ -25,9 +25,11 @@ use MongoDB\Driver\WriteConcern; use MongoDB\Exception\InvalidArgumentException; use MongoDB\Exception\UnsupportedException; +use MongoDB\Exception\UnsupportedValueException; use MongoDB\InsertOneResult; use function is_bool; +use function is_object; use function MongoDB\is_document; /** @@ -157,10 +159,12 @@ private function createExecuteOptions(): array private function validateDocument(array|object $document, ?DocumentCodec $codec): array|object { if ($codec) { - $document = $codec->encode($document); - } + if (! is_object($document)) { + throw UnsupportedValueException::invalidEncodableValue($document); + } - if (! is_document($document)) { + $document = $codec->encode($document); + } elseif (! is_document($document)) { throw InvalidArgumentException::expectedDocumentType('$document', $document); } diff --git a/src/Operation/ReplaceOne.php b/src/Operation/ReplaceOne.php index 70bfd8f77..de359b477 100644 --- a/src/Operation/ReplaceOne.php +++ b/src/Operation/ReplaceOne.php @@ -22,8 +22,10 @@ use MongoDB\Driver\Server; use MongoDB\Exception\InvalidArgumentException; use MongoDB\Exception\UnsupportedException; +use MongoDB\Exception\UnsupportedValueException; use MongoDB\UpdateResult; +use function is_object; use function MongoDB\is_document; use function MongoDB\is_first_key_operator; use function MongoDB\is_pipeline; @@ -120,10 +122,12 @@ public function execute(Server $server): UpdateResult private function validateReplacement(array|object $replacement, ?DocumentCodec $codec): array|object { if ($codec) { - $replacement = $codec->encode($replacement); - } + if (! is_object($replacement)) { + throw UnsupportedValueException::invalidEncodableValue($replacement); + } - if (! is_document($replacement)) { + $replacement = $codec->encode($replacement); + } elseif (! is_document($replacement)) { throw InvalidArgumentException::expectedDocumentType('$replacement', $replacement); } diff --git a/tests/Collection/CodecCollectionFunctionalTest.php b/tests/Collection/CodecCollectionFunctionalTest.php index 2447243d0..a145899bf 100644 --- a/tests/Collection/CodecCollectionFunctionalTest.php +++ b/tests/Collection/CodecCollectionFunctionalTest.php @@ -8,6 +8,7 @@ use MongoDB\Collection; use MongoDB\Driver\BulkWrite; use MongoDB\Exception\InvalidArgumentException; +use MongoDB\Exception\UnsupportedValueException; use MongoDB\Model\BSONDocument; use MongoDB\Operation\FindOneAndReplace; use MongoDB\Tests\Fixtures\Codec\TestDocumentCodec; @@ -264,6 +265,12 @@ public function testFindOneAndReplaceWithCodecAndTypemap(): void $this->collection->findOneAndReplace(['_id' => 1], TestObject::createForFixture(1), $options); } + public function testFindOneAndReplaceWithArray(): void + { + $this->expectExceptionObject(UnsupportedValueException::invalidEncodableValue([])); + $this->collection->findOneAndReplace(['_id' => 1], ['foo' => 'bar']); + } + public static function provideFindOptions(): Generator { yield 'Default codec' => [ @@ -413,6 +420,12 @@ public function testInsertMany($expected, $options): void $this->assertEquals($expected, $this->collection->find([], $options)->toArray()); } + public function testInsertManyWithArray(): void + { + $this->expectExceptionObject(UnsupportedValueException::invalidEncodableValue([])); + $this->collection->insertMany([['foo' => 'bar']]); + } + public static function provideInsertOneOptions(): Generator { yield 'Default codec' => [ @@ -452,6 +465,12 @@ public function testInsertOne($expected, $options): void $this->assertEquals($expected, $this->collection->findOne([], $options)); } + public function testInsertOneWithArray(): void + { + $this->expectExceptionObject(UnsupportedValueException::invalidEncodableValue([])); + $this->collection->insertOne(['foo' => 'bar']); + } + public static function provideReplaceOneOptions(): Generator { $replacedObject = TestObject::createDecodedForFixture(1); @@ -499,7 +518,13 @@ public function testReplaceOneWithCodecAndTypemap(): void ]; $this->expectExceptionObject(InvalidArgumentException::cannotCombineCodecAndTypeMap()); - $this->collection->replaceOne(['_id' => 1], ['foo' => 'bar'], $options); + $this->collection->replaceOne(['_id' => 1], (object) ['foo' => 'bar'], $options); + } + + public function testReplaceOneWithArray(): void + { + $this->expectExceptionObject(UnsupportedValueException::invalidEncodableValue([])); + $this->collection->replaceOne(['_id' => 1], ['foo' => 'bar']); } /**