Skip to content

Commit aebc9f8

Browse files
authored
bugfix: dot segment handling (#2835)
1 parent 3daedce commit aebc9f8

File tree

3 files changed

+69
-2
lines changed

3 files changed

+69
-2
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[
2+
{
3+
"type": "bugfix",
4+
"category": "s3",
5+
"description": "Disables transformation of request URI paths with dot segments"
6+
}
7+
]

src/Api/Serializer/RestSerializer.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,14 +242,21 @@ function (array $matches) use ($varDefinitions) {
242242
$path = rtrim($path, '/');
243243
}
244244
$relative = $path . $relative;
245+
246+
if (strpos($relative, '../') !== false) {
247+
if ($relative[0] !== '/') {
248+
$relative = '/' . $relative;
249+
}
250+
return new Uri($this->endpoint . $relative);
251+
}
245252
}
246253
// If endpoint has path, remove leading '/' to preserve URI resolution.
247254
if ($path && $relative[0] === '/') {
248255
$relative = substr($relative, 1);
249256
}
250257

251-
//Append path to endpoint when leading '//...' present
252-
// as uri cannot be properly resolved
258+
//Append path to endpoint when leading '//...'
259+
// present as uri cannot be properly resolved
253260
if ($this->api->isModifiedModel()
254261
&& strpos($relative, '//') === 0
255262
) {

tests/S3/S3ClientTest.php

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2321,4 +2321,57 @@ public function testDoesNotComputeMD5($options, $operation)
23212321
);
23222322
$s3->execute($command);
23232323
}
2324+
2325+
/**
2326+
* @dataProvider dotSegmentProvider
2327+
*/
2328+
public function testHandlesDotSegmentsInKey($key, $expectedUri)
2329+
{
2330+
$s3 = $this->getTestClient('s3');
2331+
$this->addMockResults($s3, [[]]);
2332+
$command = $s3->getCommand('getObject', ['Bucket' => 'foo', 'Key' => $key]);
2333+
$command->getHandlerList()->appendSign(
2334+
Middleware::tap(function ($cmd, $req) use ($expectedUri) {
2335+
$this->assertSame($expectedUri, (string) $req->getUri());
2336+
})
2337+
);
2338+
$s3->execute($command);
2339+
}
2340+
2341+
public function dotSegmentProvider()
2342+
{
2343+
return [
2344+
['../foo' , 'https://foo.s3.amazonaws.com/../foo'],
2345+
['bar/../../foo', 'https://foo.s3.amazonaws.com/bar/../../foo'],
2346+
['/../foo', 'https://foo.s3.amazonaws.com//../foo'],
2347+
['foo/bar/../baz', 'https://foo.s3.amazonaws.com/foo/bar/../baz']
2348+
];
2349+
}
2350+
2351+
/**
2352+
* @dataProvider dotSegmentPathStyleProvider
2353+
*/
2354+
public function testHandlesDotSegmentsInKeyWithPathStyle($key, $expectedUri)
2355+
{
2356+
$s3 = $this->getTestClient('s3', ['use_path_style_endpoint' => true]);
2357+
$this->addMockResults($s3, [[]]);
2358+
$command = $s3->getCommand('getObject', ['Bucket' => 'foo', 'Key' => $key]);
2359+
$command->getHandlerList()->appendSign(
2360+
Middleware::tap(function ($cmd, $req) use ($expectedUri) {
2361+
$this->assertSame($expectedUri, (string) $req->getUri());
2362+
})
2363+
);
2364+
$s3->execute($command);
2365+
}
2366+
2367+
public function dotSegmentPathStyleProvider()
2368+
{
2369+
return [
2370+
['../foo' , 'https://s3.amazonaws.com/foo/foo/../foo'],
2371+
['bar/../../foo', 'https://s3.amazonaws.com/foo/foo/bar/../../foo'],
2372+
['/../foo', 'https://s3.amazonaws.com/foo/foo//../foo'],
2373+
['foo/bar/../baz', 'https://s3.amazonaws.com/foo/foo/foo/bar/../baz'],
2374+
];
2375+
}
2376+
23242377
}

0 commit comments

Comments
 (0)