This PR changes the handling of file lookups so that they are mediated via a virtual filesystem (or "vfs", a thin wrapper around http.FileSystem). Instead of passing around paths on the host system, locations which comprise a vfs and a path within it are used.
The point of it all is to reduce the opportunities for escaping the "sandbox" -- instead of having to carefully guard which paths can be read to make sure they are under an allowed directory, they are just read from a filesystem that doesn't include anything outside the directory.
As a benefit, other implementations of http.FileSystem can now be substituted, to introduce alternative sources of files (e.g., container images).
There are complications:
some careful work must be done to construct paths relative to a location within a filesystem (and I'm not completely satisfied I've got it correct everywhere)
in some places it's important that files are given identities, e.g., so as not to load the same module, referred to two different ways (foo in one place and foo.js in another), more than once. In those cases, the file must be qualified with a string identifying the filesystem it belongs to
This also rationalised the import system: there is now an importer that uses NPM rules, an importer that uses the simpler "module/path" rules, and an importer that resolves paths that are explicitly relative to the importing module. This reduces some duplication, especially of that latter mode of resolution.
[x] One noticeable difference is that files that lie outside the input-directory are now reported as "not found", rather than as "not allowed". This is corrected by checking for parent paths.
This PR changes the handling of file lookups so that they are mediated via a virtual filesystem (or "vfs", a thin wrapper around http.FileSystem). Instead of passing around paths on the host system, locations which comprise a vfs and a path within it are used.
The point of it all is to reduce the opportunities for escaping the "sandbox" -- instead of having to carefully guard which paths can be read to make sure they are under an allowed directory, they are just read from a filesystem that doesn't include anything outside the directory.
As a benefit, other implementations of http.FileSystem can now be substituted, to introduce alternative sources of files (e.g., container images).
There are complications:
foo
in one place andfoo.js
in another), more than once. In those cases, the file must be qualified with a string identifying the filesystem it belongs toThis also rationalised the import system: there is now an importer that uses NPM rules, an importer that uses the simpler "module/path" rules, and an importer that resolves paths that are explicitly relative to the importing module. This reduces some duplication, especially of that latter mode of resolution.