Repository: laravel/framework (php)

Issue:
Error with new aws/aws-sdk-php
<!-- DO NOT THROW THIS AWAY -->
<!-- Fill out the FULL versions with patch versions -->

- Laravel Version: 9.40.1
- PHP Version: 8.1.5
- Database Driver & Version: Mysql 8.0.28

### Description:
We are currently using a filesystem that is hosted at DigitalOcean (space), we are using the AWS adapter requiring a few packages, one of the packages: aws/aws-sdk-php

By upgrading from 3.242.1 to 3.243.0 we suddenly got issues in our system (a nasty Xdebug has detected a possible infinite loop, and aborted your script with a stack depth of '256' frames)
![image](https://user-images.githubusercontent.com/179987/202395901-25a8ba8a-4d80-478c-aada-ac7f1b79dc06.png)


We tested by pinning in our composer.json
"aws/aws-sdk-php": "3.242.1", -> OK
"aws/aws-sdk-php": "3.243.0", -> NOT OK

After investigation, we identified this bug reported on that repo:
https://github.com/aws/aws-sdk-php/issues/2563

We tried to apply the patch proposed on src/Illuminate/Filesystem/FilesystemManager.php (before $client = new S3Client($s3Config)):
`$s3Config['endpoint_provider'] = PartitionEndpointProvider::defaultProvider(); `
and that fixes the issue...

Seems like it's linked to a file  that starts with / (example : /private/image.gif )




Pull request description:
Strip key, secret and token from root config options on aws clients
Fixes #44977

Related to https://github.com/aws/aws-sdk-php/issues/2567

Patch:
diff --git a/src/Illuminate/Filesystem/FilesystemManager.php b/src/Illuminate/Filesystem/FilesystemManager.php
index 77e820512f..9bfab780cb 100644
--- a/src/Illuminate/Filesystem/FilesystemManager.php
+++ b/src/Illuminate/Filesystem/FilesystemManager.php
@@ -265,7 +265,7 @@ protected function formatS3Config(array $config)
             $config['credentials'] = Arr::only($config, ['key', 'secret', 'token']);
         }
 
-        return $config;
+        return Arr::except($config, ['token']);
     }
 
     /**
diff --git a/src/Illuminate/Hashing/AbstractHasher.php b/src/Illuminate/Hashing/AbstractHasher.php
index 7ec087bee2..f10371290b 100644
--- a/src/Illuminate/Hashing/AbstractHasher.php
+++ b/src/Illuminate/Hashing/AbstractHasher.php
@@ -19,13 +19,13 @@ public function info($hashedValue)
      * Check the given plain value against a hash.
      *
      * @param  string  $value
-     * @param  string  $hashedValue
+     * @param  string|null  $hashedValue
      * @param  array  $options
      * @return bool
      */
     public function check($value, $hashedValue, array $options = [])
     {
-        if (strlen($hashedValue) === 0) {
+        if (is_null($hashedValue) || strlen($hashedValue) === 0) {
             return false;
         }
 
diff --git a/src/Illuminate/Hashing/Argon2IdHasher.php b/src/Illuminate/Hashing/Argon2IdHasher.php
index 0a36a30002..9aca47ac9c 100644
--- a/src/Illuminate/Hashing/Argon2IdHasher.php
+++ b/src/Illuminate/Hashing/Argon2IdHasher.php
@@ -10,7 +10,7 @@ class Argon2IdHasher extends ArgonHasher
      * Check the given plain value against a hash.
      *
      * @param  string  $value
-     * @param  string  $hashedValue
+     * @param  string|null  $hashedValue
      * @param  array  $options
      * @return bool
      *
@@ -22,7 +22,7 @@ public function check($value, $hashedValue, array $options = [])
             throw new RuntimeException('This password does not use the Argon2id algorithm.');
         }
 
-        if (strlen($hashedValue) === 0) {
+        if (is_null($hashedValue) || strlen($hashedValue) === 0) {
             return false;
         }
 
diff --git a/src/Illuminate/Mail/MailManager.php b/src/Illuminate/Mail/MailManager.php
index 03edae29bf..8d60b34dad 100644
--- a/src/Illuminate/Mail/MailManager.php
+++ b/src/Illuminate/Mail/MailManager.php
@@ -253,7 +253,7 @@ protected function addSesCredentials(array $config)
             $config['credentials'] = Arr::only($config, ['key', 'secret', 'token']);
         }
 
-        return $config;
+        return Arr::except($config, ['token']);
     }
 
     /**
diff --git a/src/Illuminate/Queue/Connectors/SqsConnector.php b/src/Illuminate/Queue/Connectors/SqsConnector.php
index 029c607c43..d70bd8e5f9 100755
--- a/src/Illuminate/Queue/Connectors/SqsConnector.php
+++ b/src/Illuminate/Queue/Connectors/SqsConnector.php
@@ -23,7 +23,9 @@ public function connect(array $config)
         }
 
         return new SqsQueue(
-            new SqsClient($config),
+            new SqsClient(
+                Arr::except($config, ['token'])
+            ),
             $config['queue'],
             $config['prefix'] ?? '',
             $config['suffix'] ?? '',
diff --git a/src/Illuminate/Validation/Rules/DatabaseRule.php b/src/Illuminate/Validation/Rules/DatabaseRule.php
index bac3736345..c523bec6c5 100644
--- a/src/Illuminate/Validation/Rules/DatabaseRule.php
+++ b/src/Illuminate/Validation/Rules/DatabaseRule.php
@@ -182,6 +182,19 @@ public function withoutTrashed($deletedAtColumn = 'deleted_at')
         return $this;
     }
 
+    /**
+     * Only include soft deleted models during the existence check.
+     *
+     * @param  string  $deletedAtColumn
+     * @return $this
+     */
+    public function onlyTrashed($deletedAtColumn = 'deleted_at')
+    {
+        $this->whereNotNull($deletedAtColumn);
+
+        return $this;
+    }
+
     /**
      * Register a custom query callback.
      *
diff --git a/src/Illuminate/Validation/Rules/In.php b/src/Illuminate/Validation/Rules/In.php
index 58086bfbd2..cc45b338f3 100644
--- a/src/Illuminate/Validation/Rules/In.php
+++ b/src/Illuminate/Validation/Rules/In.php
@@ -6,6 +6,8 @@ class In
 {
     /**
      * The name of the rule.
+     *
+     * @var string
      */
     protected $rule = 'in';
 


Test patch:
diff --git a/tests/Hashing/HasherTest.php b/tests/Hashing/HasherTest.php
index 62e06e4ac8..9c70666135 100755
--- a/tests/Hashing/HasherTest.php
+++ b/tests/Hashing/HasherTest.php
@@ -10,6 +10,26 @@
 
 class HasherTest extends TestCase
 {
+    public function testEmptyHashedValueReturnsFalse()
+    {
+        $hasher = new BcryptHasher();
+        $this->assertFalse($hasher->check('password', ''));
+        $hasher = new ArgonHasher();
+        $this->assertFalse($hasher->check('password', ''));
+        $hasher = new Argon2IdHasher();
+        $this->assertFalse($hasher->check('password', ''));
+    }
+
+    public function testNullHashedValueReturnsFalse()
+    {
+        $hasher = new BcryptHasher();
+        $this->assertFalse($hasher->check('password', null));
+        $hasher = new ArgonHasher();
+        $this->assertFalse($hasher->check('password', null));
+        $hasher = new Argon2IdHasher();
+        $this->assertFalse($hasher->check('password', null));
+    }
+
     public function testBasicBcryptHashing()
     {
         $hasher = new BcryptHasher;
diff --git a/tests/Validation/ValidationExistsRuleTest.php b/tests/Validation/ValidationExistsRuleTest.php
index 561ef227eb..bf4654532f 100644
--- a/tests/Validation/ValidationExistsRuleTest.php
+++ b/tests/Validation/ValidationExistsRuleTest.php
@@ -234,6 +234,17 @@ public function testItIgnoresSoftDeletes()
         $this->assertSame('exists:table,NULL,softdeleted_at,"NULL"', (string) $rule);
     }
 
+    public function testItOnlyTrashedSoftDeletes()
+    {
+        $rule = new Exists('table');
+        $rule->onlyTrashed();
+        $this->assertSame('exists:table,NULL,deleted_at,"NOT_NULL"', (string) $rule);
+
+        $rule = new Exists('table');
+        $rule->onlyTrashed('softdeleted_at');
+        $this->assertSame('exists:table,NULL,softdeleted_at,"NOT_NULL"', (string) $rule);
+    }
+
     protected function createSchema()
     {
         $this->schema('default')->create('users', function ($table) {
diff --git a/tests/Validation/ValidationUniqueRuleTest.php b/tests/Validation/ValidationUniqueRuleTest.php
index cea86c7e11..69212ab406 100644
--- a/tests/Validation/ValidationUniqueRuleTest.php
+++ b/tests/Validation/ValidationUniqueRuleTest.php
@@ -92,6 +92,17 @@ public function testItIgnoresSoftDeletes()
         $rule->withoutTrashed('softdeleted_at');
         $this->assertSame('unique:table,NULL,NULL,id,softdeleted_at,"NULL"', (string) $rule);
     }
+
+    public function testItOnlyTrashedSoftDeletes()
+    {
+        $rule = new Unique('table');
+        $rule->onlyTrashed();
+        $this->assertSame('unique:table,NULL,NULL,id,deleted_at,"NOT_NULL"', (string) $rule);
+
+        $rule = new Unique('table');
+        $rule->onlyTrashed('softdeleted_at');
+        $this->assertSame('unique:table,NULL,NULL,id,softdeleted_at,"NOT_NULL"', (string) $rule);
+    }
 }
 
 class EloquentModelStub extends Model