Skip to content

Commit

Permalink
Fix wrong combined paths when traversing upwards. Fixes #557 (#652)
Browse files Browse the repository at this point in the history
* Fix wrong combined paths when traversing upwards. Fixes #557

* docs: add changelog entry

---------

Co-authored-by: Danny van der Sluijs <[email protected]>
  • Loading branch information
uncaught and DannyvdSluijs authored Sep 20, 2024
1 parent 60488b2 commit eac0893
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 21 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add missing property in UriResolverTest ([#743](https://github.com/jsonrainbow/json-schema/pull/743))
- Correct casing of paths used in tests ([#745](https://github.com/jsonrainbow/json-schema/pull/745))
- Resolve deprecations of optional parameter ([#752](https://github.com/jsonrainbow/json-schema/pull/752))
- Fix wrong combined paths when traversing upward, fixes #557 ([#652](https://github.com/jsonrainbow/json-schema/pull/652))

### Changed
- Bump to minimum PHP 7.2 ([#746](https://github.com/jsonrainbow/json-schema/pull/746))
Expand Down
10 changes: 0 additions & 10 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -1030,21 +1030,11 @@ parameters:
count: 1
path: src/JsonSchema/Uri/UriResolver.php

-
message: "#^Offset 0 does not exist on array\\{0\\?\\: string, 1\\?\\: non\\-falsy\\-string\\}\\.$#"
count: 1
path: src/JsonSchema/Uri/UriResolver.php

-
message: "#^Parameter \\#1 \\$uri of method JsonSchema\\\\Uri\\\\UriResolver\\:\\:parse\\(\\) expects string, string\\|null given\\.$#"
count: 1
path: src/JsonSchema/Uri/UriResolver.php

-
message: "#^Parameter \\#3 \\$length of function array_slice expects int\\|null, float\\|int\\<1, max\\> given\\.$#"
count: 1
path: src/JsonSchema/Uri/UriResolver.php

-
message: "#^Parameter \\#3 \\$subject of function preg_replace expects array\\|string, string\\|null given\\.$#"
count: 1
Expand Down
34 changes: 23 additions & 11 deletions src/JsonSchema/Uri/UriResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,25 +125,37 @@ public function resolve($uri, $baseUri = null)
public static function combineRelativePathWithBasePath($relativePath, $basePath)
{
$relativePath = self::normalizePath($relativePath);
if ($relativePath == '') {
if (!$relativePath) {
return $basePath;
}
if ($relativePath[0] == '/') {
if ($relativePath[0] === '/') {
return $relativePath;
}

$basePathSegments = explode('/', $basePath);

preg_match('|^/?(\.\./(?:\./)*)*|', $relativePath, $match);
$numLevelUp = strlen($match[0]) /3 + 1;
if ($numLevelUp >= count($basePathSegments)) {
if (!$basePath) {
throw new UriResolverException(sprintf("Unable to resolve URI '%s' from base '%s'", $relativePath, $basePath));
}

$basePathSegments = array_slice($basePathSegments, 0, -$numLevelUp);
$path = preg_replace('|^/?(\.\./(\./)*)*|', '', $relativePath);
$dirname = $basePath[strlen($basePath) - 1] === '/' ? $basePath : dirname($basePath);
$combined = rtrim($dirname, '/') . '/' . ltrim($relativePath, '/');
$combinedSegments = explode('/', $combined);
$collapsedSegments = [];
while ($combinedSegments) {
$segment = array_shift($combinedSegments);
if ($segment === '..') {
if (count($collapsedSegments) <= 1) {
// Do not remove the top level (domain)
// This is not ideal - the domain should not be part of the path here. parse() and generate()
// should handle the "domain" separately, like the schema.
// Then the if-condition here would be `if (!$collapsedSegments) {`.
throw new UriResolverException(sprintf("Unable to resolve URI '%s' from base '%s'", $relativePath, $basePath));
}
array_pop($collapsedSegments);
} else {
$collapsedSegments[] = $segment;
}
}

return implode('/', $basePathSegments) . '/' . $path;
return implode('/', $collapsedSegments);
}

/**
Expand Down
18 changes: 18 additions & 0 deletions tests/Uri/UriResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

class UriResolverTest extends TestCase
{
/**
* @var UriResolver
*/
private $resolver;

public function setUp(): void
Expand Down Expand Up @@ -85,6 +88,21 @@ public function testCombineRelativePathWithBasePathNoPath(): void
);
}

/**
* Covers https://github.com/justinrainbow/json-schema/issues/557
* Relative paths yield wrong result.
*/
public function testCombineRelativePathWithBasePathTraversingUp(): void
{
$this->assertEquals(
'/var/packages/schema/UuidSchema.json',
UriResolver::combineRelativePathWithBasePath(
'../../../schema/UuidSchema.json',
'/var/packages/foo/tests/UnitTests/DemoData/../../../schema/Foo/FooSchema_latest.json'
)
);
}

public function testResolveAbsoluteUri(): void
{
$this->assertEquals(
Expand Down

0 comments on commit eac0893

Please sign in to comment.