Skip to content

Load every module through the resource loader - #153

Merged
FlorianRappl merged 3 commits into
AngleSharp:develfrom
michaelthyregod:issue-150
Nov 5, 2026
Merged

FlorianRappl merged 3 commits into
AngleSharp:develfrom
michaelthyregod:issue-150

Conversation

@michaelthyregod

Copy link
Copy Markdown
Contributor

Types of Changes

Prerequisites

Please make sure you can check the following two boxes:

  • I have read the CONTRIBUTING document
  • My code follows the code style of this project

Contribution Type

What types of changes does your code introduce? Put an x in all the boxes that apply:

  • Bug fix (non-breaking change which fixes an issue, please reference the issue id)
  • New feature (non-breaking change which adds functionality, make sure to open an associated issue first)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • My change requires a change to the documentation
  • I have updated the documentation accordingly
  • I have added tests to cover my changes
  • All new and existing tests passed (see below: three failures that were there before this change)

Description

Fixes #150, option (1): every module is loaded through AngleSharp's IResourceLoader, whatever its scheme.

  • JsModuleLoader.LoadModuleContents no longer hands non-http(s) URLs to Jint's DefaultModuleLoader, which read them from the local disk.
  • New: LoadModuleContentsAsBytes is overridden the same way. This was a second path to the disk, for import … with { type: 'bytes' }, which Jint's loader always served from the file system.
  • Both share one fetch. A missing response (no requester for the scheme) is reported as an error instead of a NullReferenceException.
  • Module resolution is unchanged.

Normal web use is unaffected: http/https modules already went through the resource loader, and all existing module tests pass. A host that loads modules from disk on purpose now registers a requester for file:. That's the only behaviour change.

Tests: EcmaTests.ModuleIsNotReadFromTheLocalDisk has 5 cases. A page at https://example.com/ tries to read a temporary local file through a direct specifier, an import map, import(), a .js module and a bytes module. All 5 fail without the change and pass with it.

Test runs (Windows 11, .NET SDK 10.0.403, the two classes that go online excluded):

  • net10.0: 533/533 passed under the invariant culture (DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1).
  • net462 and net472 (and net10.0 under the machine's own culture), the failures below are there without this change too:
    • NumbersAreGivenAsNumbers("decimal") and MethodOverloadFittingTheArgumentsIsCalled("overloaded([1.5, 2])") fail under a culture with a decimal comma, such as en-DK, because the tests format the result with the current culture.
    • CrossOriginTests.MessageReachesAFrameOfAnotherOriginWithWhoSentIt is intermittent (here on net462 and net472). I've found the cause and will report it separately.

All library targets build with 0 warnings.

Not in this PR, on purpose: FetchModule still blocks on .Task.Result and doesn't check the response status. Happy to follow up on those separately if you want.

🤖 Generated with Claude Code

@CLAassistant

CLAassistant commented Nov 4, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

Comment thread src/AngleSharp.Js/JsModuleLoader.cs Resolved
JsModuleLoader fetched only http and https modules through AngleSharp's
IResourceLoader. Every other URL went to Jint's DefaultModuleLoader, which
reads it from the local disk, so any page could import file: URLs (through
an import map, a direct specifier or import()) and read or run local files.
Bytes modules (with { type: 'bytes' }) always took Jint's file path.

- LoadModuleContents and LoadModuleContentsAsBytes both go through the
  resource loader for every scheme, so the registered requesters decide
  what a page can reach; a host that wants local modules registers a
  requester for file:
- A missing response is reported as an error instead of a
  NullReferenceException
- Module resolution is unchanged
- Tests: a page at https://example.com/ cannot read a temporary local file
  as a JSON, JavaScript or bytes module, through any of the three ways in

Fixes AngleSharp#150

@FlorianRappl FlorianRappl left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@FlorianRappl FlorianRappl left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@FlorianRappl
FlorianRappl merged commit 6230ff7 into AngleSharp:devel Nov 5, 2026
5 checks passed
@michaelthyregod
michaelthyregod deleted the issue-150 branch November 5, 2026 10:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Page script can read local files through ES module imports

3 participants