summaryrefslogtreecommitdiff
path: root/cli/module_loader.rs
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2023-01-10 14:35:44 +0100
committerGitHub <noreply@github.com>2023-01-10 14:35:44 +0100
commit636352e0ca1e611c7673f2ab68538e1ddb2dc5b7 (patch)
treec250c7a74917cef683999e06283ea9f7182f372c /cli/module_loader.rs
parent45768f0e832e54d61ddb5a62d62239aef0e597b5 (diff)
fix(npm): allow to read package.json if permissions are granted (#17209)
This commit changes signature of "deno_core::ModuleLoader::resolve" to pass an enum indicating whether or not we're resolving a specifier for dynamic import. Additionally "CliModuleLoader" was changes to store both "parent permissions" (or "root permissions") as well as "dynamic permissions" that allow to check for permissions in top-level module load an dynamic imports. Then all code paths that have anything to do with Node/npm compat are now checking for permissions which are passed from module loader instance associated with given worker.
Diffstat (limited to 'cli/module_loader.rs')
-rw-r--r--cli/module_loader.rs58
1 files changed, 40 insertions, 18 deletions
diff --git a/cli/module_loader.rs b/cli/module_loader.rs
index d452c30cf..d507a5b15 100644
--- a/cli/module_loader.rs
+++ b/cli/module_loader.rs
@@ -20,6 +20,7 @@ use deno_core::ModuleSource;
use deno_core::ModuleSpecifier;
use deno_core::ModuleType;
use deno_core::OpState;
+use deno_core::ResolutionKind;
use deno_core::SourceMapGetter;
use deno_runtime::permissions::PermissionsContainer;
use std::cell::RefCell;
@@ -36,28 +37,38 @@ struct ModuleCodeSource {
pub struct CliModuleLoader {
pub lib: TsTypeLib,
/// 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.
+ /// worker. These are "allow all" for main worker, and parent thread
+ /// permissions for Web Worker.
pub root_permissions: PermissionsContainer,
+ /// Permissions used to resolve dynamic imports, these get passed as
+ /// "root permissions" for Web Worker.
+ dynamic_permissions: PermissionsContainer,
pub ps: ProcState,
}
impl CliModuleLoader {
- pub fn new(ps: ProcState) -> Rc<Self> {
+ pub fn new(
+ ps: ProcState,
+ root_permissions: PermissionsContainer,
+ dynamic_permissions: PermissionsContainer,
+ ) -> Rc<Self> {
Rc::new(CliModuleLoader {
lib: ps.options.ts_type_lib_window(),
- root_permissions: PermissionsContainer::allow_all(),
+ root_permissions,
+ dynamic_permissions,
ps,
})
}
pub fn new_for_worker(
ps: ProcState,
- permissions: PermissionsContainer,
+ root_permissions: PermissionsContainer,
+ dynamic_permissions: PermissionsContainer,
) -> Rc<Self> {
Rc::new(CliModuleLoader {
lib: ps.options.ts_type_lib_worker(),
- root_permissions: permissions,
+ root_permissions,
+ dynamic_permissions,
ps,
})
}
@@ -138,6 +149,7 @@ impl CliModuleLoader {
&self,
specifier: &ModuleSpecifier,
maybe_referrer: Option<ModuleSpecifier>,
+ is_dynamic: bool,
) -> Result<ModuleSource, AnyError> {
let code_source = if self.ps.npm_resolver.in_npm_package(specifier) {
let file_path = specifier.to_file_path().unwrap();
@@ -152,6 +164,11 @@ impl CliModuleLoader {
})?;
let code = if self.ps.cjs_resolutions.lock().contains(specifier) {
+ let mut permissions = if is_dynamic {
+ self.dynamic_permissions.clone()
+ } else {
+ self.root_permissions.clone()
+ };
// translate cjs to esm if it's cjs and inject node globals
node::translate_cjs_to_esm(
&self.ps.file_fetcher,
@@ -160,6 +177,7 @@ impl CliModuleLoader {
MediaType::Cjs,
&self.ps.npm_resolver,
&self.ps.node_analysis_cache,
+ &mut permissions,
)?
} else {
// only inject node globals for esm
@@ -203,28 +221,35 @@ impl ModuleLoader for CliModuleLoader {
&self,
specifier: &str,
referrer: &str,
- _is_main: bool,
+ kind: ResolutionKind,
) -> Result<ModuleSpecifier, AnyError> {
- self.ps.resolve(specifier, referrer)
+ let mut permissions = if matches!(kind, ResolutionKind::DynamicImport) {
+ self.dynamic_permissions.clone()
+ } else {
+ self.root_permissions.clone()
+ };
+ self.ps.resolve(specifier, referrer, &mut permissions)
}
fn load(
&self,
specifier: &ModuleSpecifier,
maybe_referrer: Option<ModuleSpecifier>,
- _is_dynamic: bool,
+ is_dynamic: bool,
) -> Pin<Box<deno_core::ModuleSourceFuture>> {
// NOTE: this block is async only because of `deno_core` interface
// requirements; module was already loaded when constructing module graph
// during call to `prepare_load` so we can load it synchronously.
- Box::pin(deno_core::futures::future::ready(
- self.load_sync(specifier, maybe_referrer),
- ))
+ Box::pin(deno_core::futures::future::ready(self.load_sync(
+ specifier,
+ maybe_referrer,
+ is_dynamic,
+ )))
}
fn prepare_load(
&self,
- op_state: Rc<RefCell<OpState>>,
+ _op_state: Rc<RefCell<OpState>>,
specifier: &ModuleSpecifier,
_maybe_referrer: Option<String>,
is_dynamic: bool,
@@ -236,18 +261,15 @@ impl ModuleLoader for CliModuleLoader {
let specifier = specifier.clone();
let ps = self.ps.clone();
- let state = op_state.borrow();
- let dynamic_permissions = state.borrow::<PermissionsContainer>().clone();
+ let dynamic_permissions = self.dynamic_permissions.clone();
let root_permissions = if is_dynamic {
- dynamic_permissions.clone()
+ self.dynamic_permissions.clone()
} else {
self.root_permissions.clone()
};
let lib = self.lib;
- drop(state);
-
async move {
ps.prepare_module_load(
vec![specifier],