From f8d5f5b80e27c4d5eacd667072e993ebee819ff2 Mon Sep 17 00:00:00 2001 From: Nayeem Rahman Date: Thu, 16 Jan 2020 19:47:02 +0000 Subject: [PATCH] fix: Resolve read/write whitelists from CWD (#3684) --- cli/flags.rs | 37 ++++++++++++++++++++++++++++++------- cli/ops/permissions.rs | 21 +++++++++++++++++---- 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/cli/flags.rs b/cli/flags.rs index f2a3ffc368..4766fbe5fb 100644 --- a/cli/flags.rs +++ b/cli/flags.rs @@ -1,4 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. +use crate::fs::resolve_from_cwd; use clap::App; use clap::AppSettings; use clap::Arg; @@ -392,6 +393,20 @@ fn lock_args_parse(flags: &mut DenoFlags, matches: &clap::ArgMatches) { } } +fn resolve_fs_whitelist(whitelist: &[String]) -> Vec { + whitelist + .iter() + .map(|raw_path| { + resolve_from_cwd(&raw_path) + .unwrap() + .0 + .to_str() + .unwrap() + .to_owned() + }) + .collect::>() +} + // Shared between the run and test subcommands. They both take similar options. fn run_test_args_parse(flags: &mut DenoFlags, matches: &clap::ArgMatches) { reload_arg_parse(flags, matches); @@ -406,7 +421,7 @@ fn run_test_args_parse(flags: &mut DenoFlags, matches: &clap::ArgMatches) { let read_wl = matches.values_of("allow-read").unwrap(); let raw_read_whitelist: Vec = read_wl.map(std::string::ToString::to_string).collect(); - flags.read_whitelist = raw_read_whitelist; + flags.read_whitelist = resolve_fs_whitelist(&raw_read_whitelist); debug!("read whitelist: {:#?}", &flags.read_whitelist); } else { flags.allow_read = true; @@ -415,9 +430,10 @@ fn run_test_args_parse(flags: &mut DenoFlags, matches: &clap::ArgMatches) { if matches.is_present("allow-write") { if matches.value_of("allow-write").is_some() { let write_wl = matches.values_of("allow-write").unwrap(); - let raw_write_whitelist = + let raw_write_whitelist: Vec = write_wl.map(std::string::ToString::to_string).collect(); - flags.write_whitelist = raw_write_whitelist; + flags.write_whitelist = + resolve_fs_whitelist(raw_write_whitelist.as_slice()); debug!("write whitelist: {:#?}", &flags.write_whitelist); } else { flags.allow_write = true; @@ -1223,6 +1239,7 @@ fn arg_hacks(mut args: Vec) -> Vec { #[cfg(test)] mod tests { use super::*; + use std::env::current_dir; #[test] fn arg_hacks_test() { @@ -1561,14 +1578,17 @@ mod tests { let r = flags_from_vec_safe(svec![ "deno", "run", - format!("--allow-read={}", &temp_dir_path), + format!("--allow-read=.,{}", &temp_dir_path), "script.ts" ]); assert_eq!( r.unwrap(), DenoFlags { allow_read: false, - read_whitelist: svec![&temp_dir_path], + read_whitelist: svec![ + current_dir().unwrap().to_str().unwrap().to_owned(), + &temp_dir_path + ], argv: svec!["deno", "script.ts"], subcommand: DenoSubcommand::Run, ..DenoFlags::default() @@ -1585,14 +1605,17 @@ mod tests { let r = flags_from_vec_safe(svec![ "deno", "run", - format!("--allow-write={}", &temp_dir_path), + format!("--allow-write=.,{}", &temp_dir_path), "script.ts" ]); assert_eq!( r.unwrap(), DenoFlags { allow_write: false, - write_whitelist: svec![&temp_dir_path], + write_whitelist: svec![ + current_dir().unwrap().to_str().unwrap().to_owned(), + &temp_dir_path + ], argv: svec!["deno", "script.ts"], subcommand: DenoSubcommand::Run, ..DenoFlags::default() diff --git a/cli/ops/permissions.rs b/cli/ops/permissions.rs index 2e282b1814..6a0186acc9 100644 --- a/cli/ops/permissions.rs +++ b/cli/ops/permissions.rs @@ -1,6 +1,7 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. use super::dispatch_json::{Deserialize, JsonOp, Value}; use crate::deno_error::type_error; +use crate::fs as deno_fs; use crate::ops::json_op; use crate::state::ThreadSafeState; use deno_core::*; @@ -27,6 +28,15 @@ struct PermissionArgs { path: Option, } +fn resolve_path(path: &str) -> String { + deno_fs::resolve_from_cwd(path) + .unwrap() + .0 + .to_str() + .unwrap() + .to_string() +} + pub fn op_query_permission( state: &ThreadSafeState, args: Value, @@ -34,10 +44,11 @@ pub fn op_query_permission( ) -> Result { let args: PermissionArgs = serde_json::from_value(args)?; let permissions = state.permissions.lock().unwrap(); + let resolved_path = args.path.as_ref().map(String::as_str).map(resolve_path); let perm = permissions.get_permission_state( &args.name, &args.url.as_ref().map(String::as_str), - &args.path.as_ref().map(String::as_str), + &resolved_path.as_ref().map(String::as_str), )?; Ok(JsonOp::Sync(json!({ "state": perm.to_string() }))) } @@ -59,10 +70,11 @@ pub fn op_revoke_permission( "hrtime" => permissions.allow_hrtime.revoke(), _ => {} }; + let resolved_path = args.path.as_ref().map(String::as_str).map(resolve_path); let perm = permissions.get_permission_state( &args.name, &args.url.as_ref().map(String::as_str), - &args.path.as_ref().map(String::as_str), + &resolved_path.as_ref().map(String::as_str), )?; Ok(JsonOp::Sync(json!({ "state": perm.to_string() }))) } @@ -74,13 +86,14 @@ pub fn op_request_permission( ) -> Result { let args: PermissionArgs = serde_json::from_value(args)?; let mut permissions = state.permissions.lock().unwrap(); + let resolved_path = args.path.as_ref().map(String::as_str).map(resolve_path); let perm = match args.name.as_ref() { "run" => Ok(permissions.request_run()), "read" => { - Ok(permissions.request_read(&args.path.as_ref().map(String::as_str))) + Ok(permissions.request_read(&resolved_path.as_ref().map(String::as_str))) } "write" => { - Ok(permissions.request_write(&args.path.as_ref().map(String::as_str))) + Ok(permissions.request_write(&resolved_path.as_ref().map(String::as_str))) } "net" => permissions.request_net(&args.url.as_ref().map(String::as_str)), "env" => Ok(permissions.request_env()),