diff --git a/.gitignore b/.gitignore index 31033ab..60163aa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ node_modules +package-lock.json .idea lerna-debug.log yarn-error.log diff --git a/lib/Resolve.ts b/lib/Resolve.ts index 883a616..1dc4571 100644 --- a/lib/Resolve.ts +++ b/lib/Resolve.ts @@ -47,10 +47,15 @@ export function resolve(relativeIRI: string, baseIRI?: string): string { return removeDotSegmentsOfPath(relativeIRI, relativeColonPos); } - // Ignore baseIRI if the value is absolute + // Ignore baseIRI if the value is absolute. + // Per RFC 3986, a URI scheme cannot contain a '/', so if a '/' appears before the first ':', + // the IRI is a relative path (not an absolute IRI). const valueColonPos: number = relativeIRI.indexOf(':'); if (valueColonPos >= 0) { - return removeDotSegmentsOfPath(relativeIRI, valueColonPos); + const valueSlashPos: number = relativeIRI.indexOf('/'); + if (valueSlashPos < 0 || valueColonPos < valueSlashPos) { + return removeDotSegmentsOfPath(relativeIRI, valueColonPos); + } } // At this point, the baseIRI MUST be absolute, otherwise we error diff --git a/test/Resolve-test.ts b/test/Resolve-test.ts index 9702780..87c43be 100644 --- a/test/Resolve-test.ts +++ b/test/Resolve-test.ts @@ -441,6 +441,21 @@ describe('#resolve', () => { expect(resolve('../.../../../', 'http://example.org/a/b/c/')) .toEqual('http://example.org/a/'); }); + + it('create an IRI from a relative IRI with a slash before a colon and a baseIRI with trailing slash', () => { + expect(resolve('x/y:z', 'http://base.org/path/')) + .toEqual('http://base.org/path/x/y:z'); + }); + + it('create an IRI from a relative IRI with a slash before a colon and a baseIRI without trailing slash', () => { + expect(resolve('x/y:z', 'http://base.org/path')) + .toEqual('http://base.org/x/y:z'); + }); + + it('create an IRI from a relative IRI with multiple colons after a slash', () => { + expect(resolve('x/y:z:w', 'http://base.org/path/')) + .toEqual('http://base.org/path/x/y:z:w'); + }); }); describe('#removeDotSegments', () => {