From e0be4e8948a47f511150b20bb499946bcdf00c3d Mon Sep 17 00:00:00 2001 From: Rasmus Melchior Jacobsen Date: Mon, 20 Jan 2025 12:19:04 +0100 Subject: [PATCH] Ensure that relative imports from module import are relative to the module directory --- .../Runtime/Modules/DefaultModuleLoaderTests.cs | 14 ++++++++++++++ Jint/Runtime/Modules/DefaultModuleLoader.cs | 9 +++++++++ 2 files changed, 23 insertions(+) diff --git a/Jint.Tests/Runtime/Modules/DefaultModuleLoaderTests.cs b/Jint.Tests/Runtime/Modules/DefaultModuleLoaderTests.cs index 43a141169d..7c7640964c 100644 --- a/Jint.Tests/Runtime/Modules/DefaultModuleLoaderTests.cs +++ b/Jint.Tests/Runtime/Modules/DefaultModuleLoaderTests.cs @@ -21,6 +21,20 @@ public void ShouldResolveRelativePaths(string specifier, string expectedUri) Assert.Equal(SpecifierType.RelativeOrAbsolute, resolved.Type); } + + [Fact] + public void ShouldResolveRelativeToReferencingModuleSpecifier() + { + var resolver = new DefaultModuleLoader("file:///project"); + + var resolved = resolver.Resolve("referencing-module", new ModuleRequest("./local-module-file.js", [])); + + Assert.Equal("./local-module-file.js", resolved.ModuleRequest.Specifier); + Assert.Equal("file:///project/referencing-module/local-module-file.js", resolved.Key); + Assert.Equal("file:///project/referencing-module/local-module-file.js", resolved.Uri?.AbsoluteUri); + Assert.Equal(SpecifierType.RelativeOrAbsolute, resolved.Type); + } + [Theory] [InlineData("./../../other.js")] [InlineData("../../model/other.js")] diff --git a/Jint/Runtime/Modules/DefaultModuleLoader.cs b/Jint/Runtime/Modules/DefaultModuleLoader.cs index 66956ebbf2..cec8392d6e 100644 --- a/Jint/Runtime/Modules/DefaultModuleLoader.cs +++ b/Jint/Runtime/Modules/DefaultModuleLoader.cs @@ -116,7 +116,16 @@ Path traversal prevention is not a concern here because it is checked later */ if (Uri.TryCreate(referencingModuleLocation, UriKind.Absolute, out var referencingLocation) || Uri.TryCreate(_basePath, referencingModuleLocation, out referencingLocation)) + { + if (!Path.HasExtension(referencingLocation.LocalPath) && referencingLocation.LocalPath[^1] != '/') + { + var uriBuilder = new UriBuilder(referencingLocation); + uriBuilder.Path += '/'; + return uriBuilder.Uri; + } + return referencingLocation; + } } return _basePath; }