diff options
author | Luca Casonato <lucacasonato@yahoo.com> | 2021-05-17 09:44:38 +0200 |
---|---|---|
committer | Luca Casonato <lucacasonato@yahoo.com> | 2021-05-17 09:45:54 +0200 |
commit | 5151afa123a9635d2f4de9555f8843460b284a11 (patch) | |
tree | 7c4686c3f5562dc27d8b863897225236aeb97b14 | |
parent | 910935c07125e4710830be0df32a16c3ef278ba6 (diff) |
fix: static import permissions in dynamic imports
Co-authored-by: Bartek IwaĆczuk <biwanczuk@gmail.com>
39 files changed, 271 insertions, 65 deletions
diff --git a/cli/lsp/sources.rs b/cli/lsp/sources.rs index aa72ab904..5894e8d97 100644 --- a/cli/lsp/sources.rs +++ b/cli/lsp/sources.rs @@ -35,6 +35,7 @@ pub async fn cache( let handler = Arc::new(Mutex::new(FetchHandler::new( &program_state, Permissions::allow_all(), + Permissions::allow_all(), )?)); let mut builder = GraphBuilder::new(handler, maybe_import_map.clone(), None); builder.add(specifier, false).await diff --git a/cli/main.rs b/cli/main.rs index 604b786f9..5a5972e92 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -398,6 +398,7 @@ async fn info_command( // info accesses dynamically imported modules just for their information // so we allow access to all of them. Permissions::allow_all(), + Permissions::allow_all(), )?)); let mut builder = module_graph::GraphBuilder::new( handler, @@ -478,6 +479,7 @@ async fn cache_command( specifier, lib.clone(), Permissions::allow_all(), + Permissions::allow_all(), false, program_state.maybe_import_map.clone(), ) @@ -544,6 +546,7 @@ async fn create_module_graph_and_maybe_check( // when bundling, dynamic imports are only access for their type safety, // therefore we will allow the graph to access any module. Permissions::allow_all(), + Permissions::allow_all(), )?)); let mut builder = module_graph::GraphBuilder::new( handler, @@ -780,6 +783,7 @@ async fn run_with_watch(flags: Flags, script: String) -> Result<(), AnyError> { let handler = Arc::new(Mutex::new(FetchHandler::new( &program_state, Permissions::allow_all(), + Permissions::allow_all(), )?)); let mut builder = module_graph::GraphBuilder::new( handler, @@ -942,6 +946,7 @@ async fn test_command( let handler = Arc::new(Mutex::new(FetchHandler::new( &program_state, Permissions::allow_all(), + Permissions::allow_all(), )?)); let paths_to_watch: Vec<_> = include.iter().map(PathBuf::from).collect(); diff --git a/cli/module_graph.rs b/cli/module_graph.rs index a70a124a7..1ca738977 100644 --- a/cli/module_graph.rs +++ b/cli/module_graph.rs @@ -1775,7 +1775,7 @@ impl GraphBuilder { } Some(Ok(cached_module)) => { let is_root = &cached_module.specifier == specifier; - self.visit(cached_module, is_root)?; + self.visit(cached_module, is_root, is_dynamic)?; } _ => {} } @@ -1823,6 +1823,7 @@ impl GraphBuilder { &mut self, cached_module: CachedModule, is_root: bool, + is_root_dynamic: bool, ) -> Result<(), AnyError> { let specifier = cached_module.specifier.clone(); let requested_specifier = cached_module.requested_specifier.clone(); @@ -1859,14 +1860,22 @@ impl GraphBuilder { for (_, dep) in module.dependencies.iter() { let maybe_referrer = Some(dep.location.clone()); if let Some(specifier) = dep.maybe_code.as_ref() { - self.fetch(specifier, &maybe_referrer, dep.is_dynamic); + self.fetch( + specifier, + &maybe_referrer, + is_root_dynamic || dep.is_dynamic, + ); } if let Some(specifier) = dep.maybe_type.as_ref() { - self.fetch(specifier, &maybe_referrer, dep.is_dynamic); + self.fetch( + specifier, + &maybe_referrer, + is_root_dynamic || dep.is_dynamic, + ); } } if let Some((_, specifier)) = module.maybe_types.as_ref() { - self.fetch(specifier, &None, false); + self.fetch(specifier, &None, is_root_dynamic); } if specifier != requested_specifier { self diff --git a/cli/module_loader.rs b/cli/module_loader.rs index 26b9e28ff..acf762506 100644 --- a/cli/module_loader.rs +++ b/cli/module_loader.rs @@ -22,10 +22,10 @@ pub struct CliModuleLoader { /// import map file will be resolved and set. pub import_map: Option<ImportMap>, pub lib: TypeLib, - /// The initial set of permissions used to resolve the imports in the worker. - /// They are decoupled from the worker permissions since read access errors - /// must be raised based on the parent thread permissions - pub initial_permissions: Rc<RefCell<Option<Permissions>>>, + /// The initial set of permissions used to resolve the static imports in the + /// worker. They are decoupled from the worker (dynamic) permissions since + /// read access errors must be raised based on the parent thread permissions. + pub root_permissions: Permissions, pub program_state: Arc<ProgramState>, } @@ -42,7 +42,7 @@ impl CliModuleLoader { Rc::new(CliModuleLoader { import_map, lib, - initial_permissions: Rc::new(RefCell::new(None)), + root_permissions: Permissions::allow_all(), program_state, }) } @@ -60,7 +60,7 @@ impl CliModuleLoader { Rc::new(CliModuleLoader { import_map: None, lib, - initial_permissions: Rc::new(RefCell::new(Some(permissions))), + root_permissions: permissions, program_state, }) } @@ -125,16 +125,8 @@ impl ModuleLoader for CliModuleLoader { let maybe_import_map = self.import_map.clone(); let state = op_state.borrow(); - // The permissions that should be applied to any dynamically imported module - let dynamic_permissions = - // If there are initial permissions assigned to the loader take them - // and use only once for top level module load. - // Otherwise use permissions assigned to the current worker. - if let Some(permissions) = self.initial_permissions.borrow_mut().take() { - permissions - } else { - state.borrow::<Permissions>().clone() - }; + let root_permissions = self.root_permissions.clone(); + let dynamic_permissions = state.borrow::<Permissions>().clone(); let lib = self.lib.clone(); drop(state); @@ -145,6 +137,7 @@ impl ModuleLoader for CliModuleLoader { .prepare_module_load( specifier, lib, + root_permissions, dynamic_permissions, is_dynamic, maybe_import_map, diff --git a/cli/ops/runtime_compiler.rs b/cli/ops/runtime_compiler.rs index 2dfd995b5..c2d5582e7 100644 --- a/cli/ops/runtime_compiler.rs +++ b/cli/ops/runtime_compiler.rs @@ -66,15 +66,14 @@ async fn op_emit( // when we are actually resolving modules without provided sources, we should // treat the root module as a dynamic import so that runtime permissions are // applied. - let mut is_dynamic = false; let handler: Arc<Mutex<dyn SpecifierHandler>> = if let Some(sources) = args.sources { Arc::new(Mutex::new(MemoryHandler::new(sources))) } else { - is_dynamic = true; Arc::new(Mutex::new(FetchHandler::new( &program_state, runtime_permissions.clone(), + runtime_permissions.clone(), )?)) }; let maybe_import_map = if let Some(import_map_str) = args.import_map_path { @@ -103,15 +102,12 @@ async fn op_emit( }; let mut builder = GraphBuilder::new(handler, maybe_import_map, None); let root_specifier = resolve_url_or_path(&root_specifier)?; - builder - .add(&root_specifier, is_dynamic) - .await - .map_err(|_| { - type_error(format!( - "Unable to handle the given specifier: {}", - &root_specifier - )) - })?; + builder.add(&root_specifier, false).await.map_err(|_| { + type_error(format!( + "Unable to handle the given specifier: {}", + &root_specifier + )) + })?; let bundle_type = match args.bundle { Some(RuntimeBundleType::Module) => BundleType::Module, Some(RuntimeBundleType::Classic) => BundleType::Classic, diff --git a/cli/program_state.rs b/cli/program_state.rs index 0051e744b..50890b9e4 100644 --- a/cli/program_state.rs +++ b/cli/program_state.rs @@ -153,12 +153,14 @@ impl ProgramState { self: &Arc<Self>, specifiers: Vec<ModuleSpecifier>, lib: TypeLib, - runtime_permissions: Permissions, + root_permissions: Permissions, + dynamic_permissions: Permissions, maybe_import_map: Option<ImportMap>, ) -> Result<(), AnyError> { let handler = Arc::new(Mutex::new(FetchHandler::new( self, - runtime_permissions.clone(), + root_permissions, + dynamic_permissions, )?)); let mut builder = @@ -221,19 +223,17 @@ impl ProgramState { self: &Arc<Self>, specifier: ModuleSpecifier, lib: TypeLib, - mut runtime_permissions: Permissions, + root_permissions: Permissions, + dynamic_permissions: Permissions, is_dynamic: bool, maybe_import_map: Option<ImportMap>, ) -> Result<(), AnyError> { let specifier = specifier.clone(); - // Workers are subject to the current runtime permissions. We do the - // permission check here early to avoid "wasting" time building a module - // graph for a module that cannot be loaded. - if lib == TypeLib::DenoWorker || lib == TypeLib::UnstableDenoWorker { - runtime_permissions.check_specifier(&specifier)?; - } - let handler = - Arc::new(Mutex::new(FetchHandler::new(self, runtime_permissions)?)); + let handler = Arc::new(Mutex::new(FetchHandler::new( + self, + root_permissions, + dynamic_permissions, + )?)); let mut builder = GraphBuilder::new(handler, maybe_import_map, self.lockfile.clone()); builder.add(&specifier, is_dynamic).await?; diff --git a/cli/specifier_handler.rs b/cli/specifier_handler.rs index 066ed87f4..900b918ab 100644 --- a/cli/specifier_handler.rs +++ b/cli/specifier_handler.rs @@ -222,9 +222,10 @@ impl CompiledFileMetadata { pub struct FetchHandler { /// An instance of disk where generated (emitted) files are stored. disk_cache: DiskCache, - /// The set of current runtime permissions which need to be applied to - /// dynamic imports. - runtime_permissions: Permissions, + /// The set permissions which are used for root modules (static imports). + root_permissions: Permissions, + /// The set of permissions which are used for dynamic imports. + dynamic_permissions: Permissions, /// A clone of the `program_state` file fetcher. file_fetcher: FileFetcher, } @@ -232,7 +233,8 @@ pub struct FetchHandler { impl FetchHandler { pub fn new( program_state: &Arc<ProgramState>, - runtime_permissions: Permissions, + root_permissions: Permissions, + dynamic_permissions: Permissions, ) -> Result<Self, AnyError> { let custom_root = env::var("DENO_DIR").map(String::into).ok(); let deno_dir = DenoDir::new(custom_root)?; @@ -241,7 +243,8 @@ impl FetchHandler { Ok(FetchHandler { disk_cache, - runtime_permissions, + root_permissions, + dynamic_permissions, file_fetcher, }) } @@ -258,9 +261,9 @@ impl SpecifierHandler for FetchHandler { // permissions need to be applied. Other static imports have all // permissions. let mut permissions = if is_dynamic { - self.runtime_permissions.clone() + self.dynamic_permissions.clone() } else { - Permissions::allow_all() + self.root_permissions.clone() }; let file_fetcher = self.file_fetcher.clone(); let disk_cache = self.disk_cache.clone(); @@ -603,7 +606,8 @@ pub mod tests { let fetch_handler = FetchHandler { disk_cache, - runtime_permissions: Permissions::default(), + root_permissions: Permissions::allow_all(), + dynamic_permissions: Permissions::default(), file_fetcher, }; diff --git a/cli/tests/dynamic_import/permissions_blob_local.ts b/cli/tests/dynamic_import/permissions_blob_local.ts new file mode 100644 index 000000000..571c72ca3 --- /dev/null +++ b/cli/tests/dynamic_import/permissions_blob_local.ts @@ -0,0 +1,4 @@ +// This file doesn't really exist, but it doesn't matter, a "PermissionsDenied" error should be thrown. +const code = `import "file:///local_file.ts";`; +const blob = new Blob([code]); +await import(URL.createObjectURL(blob)); diff --git a/cli/tests/dynamic_import/permissions_blob_local.ts.out b/cli/tests/dynamic_import/permissions_blob_local.ts.out new file mode 100644 index 000000000..d533d4903 --- /dev/null +++ b/cli/tests/dynamic_import/permissions_blob_local.ts.out @@ -0,0 +1,5 @@ +error: Uncaught (in promise) TypeError: Requires read access to "/local_file.ts", run again with the --allow-read flag + at blob:null/[WILDCARD]:1:0 +await import(URL.createObjectURL(blob)); +^ + at async file:///[WILDCARD]/cli/tests/dynamic_import/permissions_blob_local.ts:4:1 diff --git a/cli/tests/dynamic_import/permissions_blob_remote.ts b/cli/tests/dynamic_import/permissions_blob_remote.ts new file mode 100644 index 000000000..1e2c8c21a --- /dev/null +++ b/cli/tests/dynamic_import/permissions_blob_remote.ts @@ -0,0 +1,4 @@ +// This file doesn't really exist, but it doesn't matter, a "PermissionsDenied" error should be thrown. +const code = `import "https://example.com/some/file.ts";`; +const blob = new Blob([code]); +await import(URL.createObjectURL(blob)); diff --git a/cli/tests/dynamic_import/permissions_blob_remote.ts.out b/cli/tests/dynamic_import/permissions_blob_remote.ts.out new file mode 100644 index 000000000..7992e0855 --- /dev/null +++ b/cli/tests/dynamic_import/permissions_blob_remote.ts.out @@ -0,0 +1,5 @@ +error: Uncaught (in promise) TypeError: Requires net access to "example.com", run again with the --allow-net flag + at blob:null/[WILDCARD]:1:0 +await import(URL.createObjectURL(blob)); +^ + at async file:///[WILDCARD]/cli/tests/dynamic_import/permissions_blob_remote.ts:4:1 diff --git a/cli/tests/dynamic_import/permissions_data_local.ts b/cli/tests/dynamic_import/permissions_data_local.ts new file mode 100644 index 000000000..04b3432eb --- /dev/null +++ b/cli/tests/dynamic_import/permissions_data_local.ts @@ -0,0 +1,3 @@ +// This file doesn't really exist, but it doesn't matter, a "PermissionsDenied" error should be thrown. +const code = `import "file:///local_file.ts";`; +await import(`data:application/javascript;base64,${btoa(code)}`); diff --git a/cli/tests/dynamic_import/permissions_data_local.ts.out b/cli/tests/dynamic_import/permissions_data_local.ts.out new file mode 100644 index 000000000..0b3ac7779 --- /dev/null +++ b/cli/tests/dynamic_import/permissions_data_local.ts.out @@ -0,0 +1,5 @@ +error: Uncaught (in promise) TypeError: Requires read access to "/local_file.ts", run again with the --allow-read flag + at data:application/javascript;base64,aW1wb3J0ICJmaWxlOi8vL2xvY2FsX2ZpbGUudHMiOw==:1:0 +await import(`data:application/javascript;base64,${btoa(code)}`); +^ + at async file:///[WILDCARD]/cli/tests/dynamic_import/permissions_data_local.ts:3:1 diff --git a/cli/tests/dynamic_import/permissions_data_remote.ts b/cli/tests/dynamic_import/permissions_data_remote.ts new file mode 100644 index 000000000..b0a9540c3 --- /dev/null +++ b/cli/tests/dynamic_import/permissions_data_remote.ts @@ -0,0 +1,3 @@ +// This file doesn't really exist, but it doesn't matter, a "PermissionsDenied" error should be thrown. +const code = `import "https://example.com/some/file.ts";`; +await import(`data:application/javascript;base64,${btoa(code)}`); diff --git a/cli/tests/dynamic_import/permissions_data_remote.ts.out b/cli/tests/dynamic_import/permissions_data_remote.ts.out new file mode 100644 index 000000000..6bb137091 --- /dev/null +++ b/cli/tests/dynamic_import/permissions_data_remote.ts.out @@ -0,0 +1,5 @@ +error: Uncaught (in promise) TypeError: Requires net access to "example.com", run again with the --allow-net flag + at data:application/javascript;base64,aW1wb3J0ICJodHRwczovL2V4YW1wbGUuY29tL3NvbWUvZmlsZS50cyI7:1:0 +await import(`data:application/javascript;base64,${btoa(code)}`); +^ + at async file:///[WILDCARD]/cli/tests/dynamic_import/permissions_data_remote.ts:3:1 diff --git a/cli/tests/dynamic_import/permissions_remote_remote.ts b/cli/tests/dynamic_import/permissions_remote_remote.ts new file mode 100644 index 000000000..99de3f46f --- /dev/null +++ b/cli/tests/dynamic_import/permissions_remote_remote.ts @@ -0,0 +1,3 @@ +await import( + "http://localhost:4545/cli/tests/dynamic_import/static_remote.ts" +); diff --git a/cli/tests/dynamic_import/permissions_remote_remote.ts.out b/cli/tests/dynamic_import/permissions_remote_remote.ts.out new file mode 100644 index 000000000..ae8113899 --- /dev/null +++ b/cli/tests/dynamic_import/permissions_remote_remote.ts.out @@ -0,0 +1,5 @@ +error: Uncaught (in promise) TypeError: Requires net access to "example.com", run again with the --allow-net flag + at http://localhost:4545/cli/tests/dynamic_import/static_remote.ts:2:0 +await import( +^ + at async file:///[WILDCARD]/cli/tests/dynamic_import/permissions_remote_remote.ts:1:1 diff --git a/cli/tests/dynamic_import/static_remote.ts b/cli/tests/dynamic_import/static_remote.ts new file mode 100644 index 000000000..2d6e820fd --- /dev/null +++ b/cli/tests/dynamic_import/static_remote.ts @@ -0,0 +1,2 @@ +// This file doesn't really exist, but it doesn't matter, a "PermissionsDenied" error should be thrown. +import "https://example.com/some/file.ts"; diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs index fe40e243b..19a1a8952 100644 --- a/cli/tests/integration_tests.rs +++ b/cli/tests/integration_tests.rs @@ -3096,6 +3096,41 @@ console.log("finish"); exit_code: 1, }); + itest!(dynamic_import_permissions_remote_remote { + args: "run --quiet --reload --allow-net=localhost:4545 dynamic_import/permissions_remote_remote.ts", + output: "dynamic_import/permissions_remote_remote.ts.out", + http_server: true, + exit_code: 1, + }); + + itest!(dynamic_import_permissions_data_remote { + args: "run --quiet --reload --allow-net=localhost:4545 dynamic_import/permissions_data_remote.ts", + output: "dynamic_import/permissions_data_remote.ts.out", + http_server: true, + exit_code: 1, + }); + + itest!(dynamic_import_permissions_blob_remote { + args: "run --quiet --reload --allow-net=localhost:4545 dynamic_import/permissions_blob_remote.ts", + output: "dynamic_import/permissions_blob_remote.ts.out", + http_server: true, + exit_code: 1, + }); + + itest!(dynamic_import_permissions_data_local { + args: "run --quiet --reload --allow-net=localhost:4545 dynamic_import/permissions_data_local.ts", + output: "dynamic_import/permissions_data_local.ts.out", + http_server: true, + exit_code: 1, + }); + + itest!(dynamic_import_permissions_blob_local { + args: "run --quiet --reload --allow-net=localhost:4545 dynamic_import/permissions_blob_local.ts", + output: "dynamic_import/permissions_blob_local.ts.out", + http_server: true, + exit_code: 1, + }); + itest!(js_import_detect { args: "run --quiet --reload js_import_detect.ts", output: "js_import_detect.ts.out", @@ -3466,6 +3501,48 @@ console.log("finish"); exit_code: 1, }); + itest!(worker_permissions_remote_remote { + args: "run --quiet --reload --allow-net=localhost:4545 workers/permissions_remote_remote.ts", + output: "workers/permissions_remote_remote.ts.out", + http_server: true, + exit_code: 1, + }); + + itest!(worker_permissions_dynamic_remote { + args: "run --quiet --reload --allow-net --unstable workers/permissions_dynamic_remote.ts", + output: "workers/permissions_dynamic_remote.ts.out", + http_server: true, + exit_code: 1, + }); + + itest!(worker_permissions_data_remote { + args: "run --quiet --reload --allow-net=localhost:4545 workers/permissions_data_remote.ts", + output: "workers/permissions_data_remote.ts.out", + http_server: true, + exit_code: 1, + }); + + itest!(worker_permissions_blob_remote { + args: "run --quiet --reload --allow-net=localhost:4545 workers/permissions_blob_remote.ts", + output: "workers/permissions_blob_remote.ts.out", + http_server: true, + exit_code: 1, + }); + + itest!(worker_permissions_data_local { + args: "run --quiet --reload --allow-net=localhost:4545 workers/permissions_data_local.ts", + output: "workers/permissions_data_local.ts.out", + http_server: true, + exit_code: 1, + }); + + itest!(worker_permissions_blob_local { + args: "run --quiet --reload --allow-net=localhost:4545 workers/permissions_blob_local.ts", + output: "workers/permissions_blob_local.ts.out", + http_server: true, + exit_code: 1, + }); + itest!(exit_error42 { exit_code: 42, args: "run --quiet --reload exit_error42.ts", @@ -3946,7 +4023,7 @@ console.log("finish"); }); itest!(import_blob_url_imports { - args: "run --quiet --reload import_blob_url_imports.ts", + args: "run --quiet --reload --allow-net=localhost:4545 import_blob_url_imports.ts", output: "import_blob_url_imports.ts.out", http_server: true, }); diff --git a/cli/tests/workers/dynamic_remote.ts b/cli/tests/workers/dynamic_remote.ts new file mode 100644 index 000000000..381c7f374 --- /dev/null +++ b/cli/tests/workers/dynamic_remote.ts @@ -0,0 +1,2 @@ +// This file doesn't really exist, but it doesn't matter, a "PermissionsDenied" error should be thrown. +await import("https://example.com/some/file.ts"); diff --git a/cli/tests/workers/parent_read_check_granular_worker.js b/cli/tests/workers/parent_read_check_granular_worker.js index 474b8a61b..1391190cd 100644 --- a/cli/tests/workers/parent_read_check_granular_worker.js +++ b/cli/tests/workers/parent_read_check_granular_worker.js @@ -1,5 +1,3 @@ -import { fromFileUrl } from "../../../test_util/std/path/mod.ts"; - const worker = new Worker( new URL("./read_check_granular_worker.js", import.meta.url).href, { @@ -31,7 +29,7 @@ worker.onmessage = ({ data: childResponse }) => { onmessage = async ({ data }) => { const { state } = await Deno.permissions.query({ name: "read", - path: fromFileUrl(new URL(data.route, import.meta.url)), + path: data.path, }); messages[data.index] = state === "granted"; diff --git a/cli/tests/workers/permissions_blob_local.ts b/cli/tests/workers/permissions_blob_local.ts new file mode 100644 index 000000000..e75557912 --- /dev/null +++ b/cli/tests/workers/permissions_blob_local.ts @@ -0,0 +1,4 @@ +// This file doesn't really exist, but it doesn't matter, a "PermissionsDenied" error should be thrown. +const code = `import "file:///local_file.ts";`; +const blob = new Blob([code]); +new Worker(URL.createObjectURL(blob), { type: "module" }); diff --git a/cli/tests/workers/permissions_blob_local.ts.out b/cli/tests/workers/permissions_blob_local.ts.out new file mode 100644 index 000000000..7ccb56e1d --- /dev/null +++ b/cli/tests/workers/permissions_blob_local.ts.out @@ -0,0 +1,4 @@ +error: Uncaught (in worker "") Requires read access to "/local_file.ts", run again with the --allow-read flag + at blob:null/[WILDCARD]:1:0 +error: Uncaught (in promise) Error: Unhandled error event reached main worker. + at Worker.#poll (deno:runtime/js/11_workers.js:246:23) diff --git a/cli/tests/workers/permissions_blob_remote.ts b/cli/tests/workers/permissions_blob_remote.ts new file mode 100644 index 000000000..4808bc57b --- /dev/null +++ b/cli/tests/workers/permissions_blob_remote.ts @@ -0,0 +1,4 @@ +// This file doesn't really exist, but it doesn't matter, a "PermissionsDenied" error should be thrown. +const code = `import "https://example.com/some/file.ts";`; +const blob = new Blob([code]); +new Worker(URL.createObjectURL(blob), { type: "module" }); diff --git a/cli/tests/workers/permissions_blob_remote.ts.out b/cli/tests/workers/permissions_blob_remote.ts.out new file mode 100644 index 000000000..c89f7b41c --- /dev/null +++ b/cli/tests/workers/permissions_blob_remote.ts.out @@ -0,0 +1,4 @@ +error: Uncaught (in worker "") Requires net access to "example.com", run again with the --allow-net flag + at blob:null/[WILDCARD]:1:0 +error: Uncaught (in promise) Error: Unhandled error event reached main worker. + at Worker.#poll (deno:runtime/js/11_workers.js:246:23) diff --git a/cli/tests/workers/permissions_data_local.ts b/cli/tests/workers/permissions_data_local.ts new file mode 100644 index 000000000..938a76add --- /dev/null +++ b/cli/tests/workers/permissions_data_local.ts @@ -0,0 +1,5 @@ +// This file doesn't really exist, but it doesn't matter, a "PermissionsDenied" error should be thrown. +const code = `import "file:///local_file.ts";`; +new Worker(`data:application/javascript;base64,${btoa(code)}`, { + type: "module", +}); diff --git a/cli/tests/workers/permissions_data_local.ts.out b/cli/tests/workers/permissions_data_local.ts.out new file mode 100644 index 000000000..e282bb5aa --- /dev/null +++ b/cli/tests/workers/permissions_data_local.ts.out @@ -0,0 +1,4 @@ +error: Uncaught (in worker "") Requires read access to "/local_file.ts", run again with the --allow-read flag + at data:application/javascript;base64,aW1wb3J0ICJmaWxlOi8vL2xvY2FsX2ZpbGUudHMiOw==:1:0 +error: Uncaught (in promise) Error: Unhandled error event reached main worker. + at Worker.#poll (deno:runtime/js/11_workers.js:246:23) diff --git a/cli/tests/workers/permissions_data_remote.ts b/cli/tests/workers/permissions_data_remote.ts new file mode 100644 index 000000000..b37bd661d --- /dev/null +++ b/cli/tests/workers/permissions_data_remote.ts @@ -0,0 +1,5 @@ +// This file doesn't really exist, but it doesn't matter, a "PermissionsDenied" error should be thrown. +const code = `import "https://example.com/some/file.ts";`; +new Worker(`data:application/javascript;base64,${btoa(code)}`, { + type: "module", +}); diff --git a/cli/tests/workers/permissions_data_remote.ts.out b/cli/tests/workers/permissions_data_remote.ts.out new file mode 100644 index 000000000..2c4080672 --- /dev/null +++ b/cli/tests/workers/permissions_data_remote.ts.out @@ -0,0 +1,4 @@ +error: Uncaught (in worker "") Requires net access to "example.com", run again with the --allow-net flag + at data:application/javascript;base64,aW1wb3J0ICJodHRwczovL2V4YW1wbGUuY29tL3NvbWUvZmlsZS50cyI7:1:0 +error: Uncaught (in promise) Error: Unhandled error event reached main worker. + at Worker.#poll (deno:runtime/js/11_workers.js:246:23) diff --git a/cli/tests/workers/permissions_dynamic_remote.ts b/cli/tests/workers/permissions_dynamic_remote.ts new file mode 100644 index 000000000..a5d293e16 --- /dev/null +++ b/cli/tests/workers/permissions_dynamic_remote.ts @@ -0,0 +1,11 @@ +new Worker( + "http://localhost:4545/cli/tests/workers/dynamic_remote.ts", + { + type: "module", + deno: { + permissions: { + net: false, + }, + }, + }, +); diff --git a/cli/tests/workers/permissions_dynamic_remote.ts.out b/cli/tests/workers/permissions_dynamic_remote.ts.out new file mode 100644 index 000000000..3bfb16205 --- /dev/null +++ b/cli/tests/workers/permissions_dynamic_remote.ts.out @@ -0,0 +1,10 @@ +error: Uncaught (in worker "") (in promise) TypeError: Requires net access to "example.com", run again with the --allow-net flag +await import("https://example.com/some/file.ts"); +^ + at async http://localhost:4545/cli/tests/workers/dynamic_remote.ts:2:1 +error: Uncaught (in worker "") TypeError: Requires net access to "example.com", run again with the --allow-net flag +await import("https://example.com/some/file.ts"); +^ + at async http://localhost:4545/cli/tests/workers/dynamic_remote.ts:2:1 +error: Uncaught (in promise) Error: Unhandled error event reached main worker. + at Worker.#poll (deno:runtime/js/11_workers.js:246:23) diff --git a/cli/tests/workers/permissions_remote_remote.ts b/cli/tests/workers/permissions_remote_remote.ts new file mode 100644 index 000000000..b1f954a31 --- /dev/null +++ b/cli/tests/workers/permissions_remote_remote.ts @@ -0,0 +1,3 @@ +new Worker("http://localhost:4545/cli/tests/workers/static_remote.ts", { + type: "module", +}); diff --git a/cli/tests/workers/permissions_remote_remote.ts.out b/cli/tests/workers/permissions_remote_remote.ts.out new file mode 100644 index 000000000..714150a3a --- /dev/null +++ b/cli/tests/workers/permissions_remote_remote.ts.out @@ -0,0 +1,4 @@ +error: Uncaught (in worker "") Requires net access to "example.com", run again with the --allow-net flag + at http://localhost:4545/cli/tests/workers/static_remote.ts:2:0 +error: Uncaught (in promise) Error: Unhandled error event reached main worker. + at Worker.#poll (deno:runtime/js/11_workers.js:246:23) diff --git a/cli/tests/workers/read_check_granular_worker.js b/cli/tests/workers/read_check_granular_worker.js index d1a205391..25f2058b3 100644 --- a/cli/tests/workers/read_check_granular_worker.js +++ b/cli/tests/workers/read_check_granular_worker.js @@ -1,9 +1,7 @@ -import { fromFileUrl } from "../../../test_util/std/path/mod.ts"; - onmessage = async ({ data }) => { const { state } = await Deno.permissions.query({ name: "read", - path: fromFileUrl(new URL(data.route, import.meta.url)), + path: data.path, }); postMessage({ diff --git a/cli/tests/workers/static_remote.ts b/cli/tests/workers/static_remote.ts new file mode 100644 index 000000000..2d6e820fd --- /dev/null +++ b/cli/tests/workers/static_remote.ts @@ -0,0 +1,2 @@ +// This file doesn't really exist, but it doesn't matter, a "PermissionsDenied" error should be thrown. +import "https://example.com/some/file.ts"; diff --git a/cli/tests/workers/test.ts b/cli/tests/workers/test.ts index 41988d204..954737b3a 100644 --- a/cli/tests/workers/test.ts +++ b/cli/tests/workers/test.ts @@ -8,6 +8,7 @@ import { assertThrows, } from "../../../test_util/std/testing/asserts.ts"; import { deferred } from "../../../test_util/std/async/deferred.ts"; +import { fromFileUrl } from "../../../test_util/std/path/mod.ts"; Deno.test({ name: "worker terminate", @@ -476,8 +477,16 @@ Deno.test("Worker limit children permissions granularly", async function () { //Routes are relative to the spawned worker location const routes = [ - { permission: false, route: "read_check_granular_worker.js" }, - { permission: true, route: "read_check_worker.js" }, + { + permission: false, + path: fromFileUrl( + new URL("read_check_granular_worker.js", import.meta.url), + ), + }, + { + permission: true, + path: fromFileUrl(new URL("read_check_worker.js", import.meta.url)), + }, ]; let checked = 0; @@ -490,10 +499,10 @@ Deno.test("Worker limit children permissions granularly", async function () { } }; - routes.forEach(({ route }, index) => + routes.forEach(({ path }, index) => worker.postMessage({ index, - route, + path, }) ); @@ -553,12 +562,14 @@ Deno.test("Nested worker limit children permissions granularly", async function { childHasPermission: false, parentHasPermission: true, - route: "read_check_granular_worker.js", + path: fromFileUrl( + new URL("read_check_granular_worker.js", import.meta.url), + ), }, { childHasPermission: false, parentHasPermission: false, - route: "read_check_worker.js", + path: fromFileUrl(new URL("read_check_worker.js", import.meta.url)), }, ]; @@ -579,10 +590,10 @@ Deno.test("Nested worker limit children permissions granularly", async function }; // Index needed cause requests will be handled asynchronously - routes.forEach(({ route }, index) => + routes.forEach(({ path }, index) => worker.postMessage({ index, - route, + path, }) ); diff --git a/cli/tools/coverage.rs b/cli/tools/coverage.rs index 9a197eabd..23b4a4fb6 100644 --- a/cli/tools/coverage.rs +++ b/cli/tools/coverage.rs @@ -635,6 +635,7 @@ pub async fn cover_files( module_specifier.clone(), TypeLib::UnstableDenoWindow, Permissions::allow_all(), + Permissions::allow_all(), false, program_state.maybe_import_map.clone(), ) diff --git a/cli/tools/doc.rs b/cli/tools/doc.rs index 938944f2a..5794b494f 100644 --- a/cli/tools/doc.rs +++ b/cli/tools/doc.rs @@ -117,6 +117,7 @@ pub async fn print_docs( let handler = Arc::new(Mutex::new(FetchHandler::new( &program_state, Permissions::allow_all(), + Permissions::allow_all(), )?)); let mut builder = module_graph::GraphBuilder::new( handler, diff --git a/cli/tools/test_runner.rs b/cli/tools/test_runner.rs index fdb4be664..6b2eab36b 100644 --- a/cli/tools/test_runner.rs +++ b/cli/tools/test_runner.rs @@ -403,6 +403,7 @@ pub async fn run_tests( .prepare_module_graph( test_programs.clone(), lib.clone(), + Permissions::allow_all(), permissions.clone(), program_state.maybe_import_map.clone(), ) @@ -413,6 +414,7 @@ pub async fn run_tests( .prepare_module_graph( test_modules.clone(), lib.clone(), + Permissions::allow_all(), permissions.clone(), program_state.maybe_import_map.clone(), ) |