@@ -125,25 +125,37 @@ public function resolve($uri, $baseUri = null)
125
125
public static function combineRelativePathWithBasePath ($ relativePath , $ basePath )
126
126
{
127
127
$ relativePath = self ::normalizePath ($ relativePath );
128
- if ($ relativePath == '' ) {
128
+ if (! $ relativePath ) {
129
129
return $ basePath ;
130
130
}
131
- if ($ relativePath [0 ] == '/ ' ) {
131
+ if ($ relativePath [0 ] === '/ ' ) {
132
132
return $ relativePath ;
133
133
}
134
-
135
- $ basePathSegments = explode ('/ ' , $ basePath );
136
-
137
- preg_match ('|^/?(\.\./(?:\./)*)*| ' , $ relativePath , $ match );
138
- $ numLevelUp = strlen ($ match [0 ]) /3 + 1 ;
139
- if ($ numLevelUp >= count ($ basePathSegments )) {
134
+ if (!$ basePath ) {
140
135
throw new UriResolverException (sprintf ("Unable to resolve URI '%s' from base '%s' " , $ relativePath , $ basePath ));
141
136
}
142
137
143
- $ basePathSegments = array_slice ($ basePathSegments , 0 , -$ numLevelUp );
144
- $ path = preg_replace ('|^/?(\.\./(\./)*)*| ' , '' , $ relativePath );
138
+ $ dirname = $ basePath [strlen ($ basePath ) - 1 ] === '/ ' ? $ basePath : dirname ($ basePath );
139
+ $ combined = rtrim ($ dirname , '/ ' ) . '/ ' . ltrim ($ relativePath , '/ ' );
140
+ $ combinedSegments = explode ('/ ' , $ combined );
141
+ $ collapsedSegments = array ();
142
+ while ($ combinedSegments ) {
143
+ $ segment = array_shift ($ combinedSegments );
144
+ if ($ segment === '.. ' ) {
145
+ if (count ($ collapsedSegments ) <= 1 ) {
146
+ // Do not remove the top level (domain)
147
+ // This is not ideal - the domain should not be part of the path here. parse() and generate()
148
+ // should handle the "domain" separately, like the schema.
149
+ // Then the if-condition here would be `if (!$collapsedSegments) {`.
150
+ throw new UriResolverException (sprintf ("Unable to resolve URI '%s' from base '%s' " , $ relativePath , $ basePath ));
151
+ }
152
+ array_pop ($ collapsedSegments );
153
+ } else {
154
+ $ collapsedSegments [] = $ segment ;
155
+ }
156
+ }
145
157
146
- return implode ('/ ' , $ basePathSegments ) . ' / ' . $ path ;
158
+ return implode ('/ ' , $ collapsedSegments ) ;
147
159
}
148
160
149
161
/**
0 commit comments