From ced944b7c188c75472101d7955e87ec607739ad6 Mon Sep 17 00:00:00 2001 From: Sean O'Brien <60306702+stobrien89@users.noreply.github.com> Date: Fri, 8 Dec 2023 14:03:09 -0500 Subject: [PATCH] enhancement: s3 dot segment handling (#2853) --- src/Api/Serializer/RestSerializer.php | 7 +++++-- tests/S3/S3ClientTest.php | 14 ++++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/Api/Serializer/RestSerializer.php b/src/Api/Serializer/RestSerializer.php index 6fc6c3a403..ee64d92038 100644 --- a/src/Api/Serializer/RestSerializer.php +++ b/src/Api/Serializer/RestSerializer.php @@ -236,11 +236,14 @@ function (array $matches) use ($varDefinitions) { } $relative = $path . $relative; - if (strpos($relative, '../') !== false) { + if (strpos($relative, '../') !== false + || substr($relative, -2) === '..' + ) { if ($relative[0] !== '/') { $relative = '/' . $relative; } - return new Uri($this->endpoint . $relative); + + return new Uri($this->endpoint->withPath('') . $relative); } } // If endpoint has path, remove leading '/' to preserve URI resolution. diff --git a/tests/S3/S3ClientTest.php b/tests/S3/S3ClientTest.php index cf54918ad3..9b4f0d64e3 100644 --- a/tests/S3/S3ClientTest.php +++ b/tests/S3/S3ClientTest.php @@ -2444,7 +2444,8 @@ public function dotSegmentProvider() ['../foo' , 'https://foo.s3.amazonaws.com/../foo'], ['bar/../../foo', 'https://foo.s3.amazonaws.com/bar/../../foo'], ['/../foo', 'https://foo.s3.amazonaws.com//../foo'], - ['foo/bar/../baz', 'https://foo.s3.amazonaws.com/foo/bar/../baz'] + ['foo/bar/../baz', 'https://foo.s3.amazonaws.com/foo/bar/../baz'], + ['foo/bar/baz/..', 'https://foo.s3.amazonaws.com/foo/bar/baz/..'] ]; } @@ -2455,7 +2456,7 @@ public function testHandlesDotSegmentsInKeyWithPathStyle($key, $expectedUri) { $s3 = $this->getTestClient('s3', ['use_path_style_endpoint' => true]); $this->addMockResults($s3, [[]]); - $command = $s3->getCommand('getObject', ['Bucket' => 'foo', 'Key' => $key]); + $command = $s3->getCommand('getObject', ['Bucket' => 'bucket', 'Key' => $key]); $command->getHandlerList()->appendSign( Middleware::tap(function ($cmd, $req) use ($expectedUri) { $this->assertSame($expectedUri, (string) $req->getUri()); @@ -2467,10 +2468,11 @@ public function testHandlesDotSegmentsInKeyWithPathStyle($key, $expectedUri) public function dotSegmentPathStyleProvider() { return [ - ['../foo' , 'https://s3.amazonaws.com/foo/foo/../foo'], - ['bar/../../foo', 'https://s3.amazonaws.com/foo/foo/bar/../../foo'], - ['/../foo', 'https://s3.amazonaws.com/foo/foo//../foo'], - ['foo/bar/../baz', 'https://s3.amazonaws.com/foo/foo/foo/bar/../baz'], + ['../foo' , 'https://s3.amazonaws.com/bucket/../foo'], + ['bar/../../foo', 'https://s3.amazonaws.com/bucket/bar/../../foo'], + ['/../foo', 'https://s3.amazonaws.com/bucket//../foo'], + ['foo/bar/../baz', 'https://s3.amazonaws.com/bucket/foo/bar/../baz'], + ['foo/bar/baz/..', 'https://s3.amazonaws.com/bucket/foo/bar/baz/..'] ]; }