Skip to content

Commit

Permalink
bugfix: dot segment handling (#2835)
Browse files Browse the repository at this point in the history
  • Loading branch information
stobrien89 authored Nov 22, 2023
1 parent 3daedce commit aebc9f8
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 2 deletions.
7 changes: 7 additions & 0 deletions .changes/nextrelease/s3-dot-segment.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[
{
"type": "bugfix",
"category": "s3",
"description": "Disables transformation of request URI paths with dot segments"
}
]
11 changes: 9 additions & 2 deletions src/Api/Serializer/RestSerializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -242,14 +242,21 @@ function (array $matches) use ($varDefinitions) {
$path = rtrim($path, '/');
}
$relative = $path . $relative;

if (strpos($relative, '../') !== false) {
if ($relative[0] !== '/') {
$relative = '/' . $relative;
}
return new Uri($this->endpoint . $relative);
}
}
// If endpoint has path, remove leading '/' to preserve URI resolution.
if ($path && $relative[0] === '/') {
$relative = substr($relative, 1);
}

//Append path to endpoint when leading '//...' present
// as uri cannot be properly resolved
//Append path to endpoint when leading '//...'
// present as uri cannot be properly resolved
if ($this->api->isModifiedModel()
&& strpos($relative, '//') === 0
) {
Expand Down
53 changes: 53 additions & 0 deletions tests/S3/S3ClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2321,4 +2321,57 @@ public function testDoesNotComputeMD5($options, $operation)
);
$s3->execute($command);
}

/**
* @dataProvider dotSegmentProvider
*/
public function testHandlesDotSegmentsInKey($key, $expectedUri)
{
$s3 = $this->getTestClient('s3');
$this->addMockResults($s3, [[]]);
$command = $s3->getCommand('getObject', ['Bucket' => 'foo', 'Key' => $key]);
$command->getHandlerList()->appendSign(
Middleware::tap(function ($cmd, $req) use ($expectedUri) {
$this->assertSame($expectedUri, (string) $req->getUri());
})
);
$s3->execute($command);
}

public function dotSegmentProvider()
{
return [
['../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']
];
}

/**
* @dataProvider dotSegmentPathStyleProvider
*/
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->getHandlerList()->appendSign(
Middleware::tap(function ($cmd, $req) use ($expectedUri) {
$this->assertSame($expectedUri, (string) $req->getUri());
})
);
$s3->execute($command);
}

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'],
];
}

}

0 comments on commit aebc9f8

Please sign in to comment.