summaryrefslogtreecommitdiff
path: root/cli/ops.rs
diff options
context:
space:
mode:
authorandy finch <andyfinch7@gmail.com>2019-05-08 19:20:30 -0400
committerRyan Dahl <ry@tinyclouds.org>2019-05-08 19:20:30 -0400
commit2edee3367dc9003b721cf87ca57e820c7acf7b25 (patch)
tree4bc91161188344d61b7e20107701c7e2af6b4ae1 /cli/ops.rs
parentac8c6fec5bb2be97c8dbdb2286d2688575a593f2 (diff)
First pass at permissions whitelist (#2129)
Diffstat (limited to 'cli/ops.rs')
-rw-r--r--cli/ops.rs140
1 files changed, 97 insertions, 43 deletions
diff --git a/cli/ops.rs b/cli/ops.rs
index 7b9500ef8..a1d6e0c48 100644
--- a/cli/ops.rs
+++ b/cli/ops.rs
@@ -2,6 +2,7 @@
use atty;
use crate::ansi;
use crate::compiler::get_compiler_config;
+use crate::deno_dir;
use crate::dispatch_minimal::dispatch_minimal;
use crate::dispatch_minimal::parse_min_record;
use crate::errors;
@@ -43,7 +44,6 @@ use std;
use std::convert::From;
use std::fs;
use std::net::Shutdown;
-use std::path::Path;
use std::path::PathBuf;
use std::process::Command;
use std::time::{Duration, Instant, UNIX_EPOCH};
@@ -241,6 +241,14 @@ pub fn op_selector_std(inner_type: msg::Any) -> Option<OpCreator> {
}
}
+fn resolve_path(path: &str) -> Result<(PathBuf, String), DenoError> {
+ let url = deno_dir::resolve_file_url(path.to_string(), ".".to_string())
+ .map_err(DenoError::from)?;
+ let path = url.to_file_path().unwrap();
+ let path_string = path.to_str().unwrap().to_string();
+ Ok((path, path_string))
+}
+
// Returns a milliseconds and nanoseconds subsec
// since the start time of the deno runtime.
// If the High precision flag is not set, the
@@ -697,7 +705,11 @@ fn op_fetch(
}
let req = maybe_req.unwrap();
- if let Err(e) = state.check_net(url) {
+ let url_ = match url::Url::parse(url) {
+ Err(err) => return odd_future(DenoError::from(err)),
+ Ok(v) => v,
+ };
+ if let Err(e) = state.check_net_url(url_) {
return odd_future(e);
}
@@ -816,17 +828,20 @@ fn op_mkdir(
) -> Box<OpWithError> {
assert!(data.is_none());
let inner = base.inner_as_mkdir().unwrap();
- let path = String::from(inner.path().unwrap());
+ let (path, path_) = match resolve_path(inner.path().unwrap()) {
+ Err(err) => return odd_future(err),
+ Ok(v) => v,
+ };
let recursive = inner.recursive();
let mode = inner.mode();
- if let Err(e) = state.check_write(&path) {
+ if let Err(e) = state.check_write(&path_) {
return odd_future(e);
}
blocking(base.sync(), move || {
- debug!("op_mkdir {}", path);
- deno_fs::mkdir(Path::new(&path), mode, recursive)?;
+ debug!("op_mkdir {}", path_);
+ deno_fs::mkdir(&path, mode, recursive)?;
Ok(empty_buf())
})
}
@@ -839,15 +854,17 @@ fn op_chmod(
assert!(data.is_none());
let inner = base.inner_as_chmod().unwrap();
let _mode = inner.mode();
- let path = String::from(inner.path().unwrap());
+ let (path, path_) = match resolve_path(inner.path().unwrap()) {
+ Err(err) => return odd_future(err),
+ Ok(v) => v,
+ };
- if let Err(e) = state.check_write(&path) {
+ if let Err(e) = state.check_write(&path_) {
return odd_future(e);
}
blocking(base.sync(), move || {
- debug!("op_chmod {}", &path);
- let path = PathBuf::from(&path);
+ debug!("op_chmod {}", &path_);
// Still check file/dir exists on windows
let _metadata = fs::metadata(&path)?;
// Only work in unix
@@ -902,8 +919,10 @@ fn op_open(
assert!(data.is_none());
let cmd_id = base.cmd_id();
let inner = base.inner_as_open().unwrap();
- let filename_str = inner.filename().unwrap();
- let filename = PathBuf::from(&filename_str);
+ let (filename, filename_) = match resolve_path(inner.filename().unwrap()) {
+ Err(err) => return odd_future(err),
+ Ok(v) => v,
+ };
let mode = inner.mode().unwrap();
let mut open_options = tokio::fs::OpenOptions::new();
@@ -944,20 +963,20 @@ fn op_open(
match mode {
"r" => {
- if let Err(e) = state.check_read(&filename_str) {
+ if let Err(e) = state.check_read(&filename_) {
return odd_future(e);
}
}
"w" | "a" | "x" => {
- if let Err(e) = state.check_write(&filename_str) {
+ if let Err(e) = state.check_write(&filename_) {
return odd_future(e);
}
}
&_ => {
- if let Err(e) = state.check_read(&filename_str) {
+ if let Err(e) = state.check_read(&filename_) {
return odd_future(e);
}
- if let Err(e) = state.check_write(&filename_str) {
+ if let Err(e) = state.check_write(&filename_) {
return odd_future(e);
}
}
@@ -1146,11 +1165,13 @@ fn op_remove(
) -> Box<OpWithError> {
assert!(data.is_none());
let inner = base.inner_as_remove().unwrap();
- let path_ = inner.path().unwrap();
- let path = PathBuf::from(path_);
+ let (path, path_) = match resolve_path(inner.path().unwrap()) {
+ Err(err) => return odd_future(err),
+ Ok(v) => v,
+ };
let recursive = inner.recursive();
- if let Err(e) = state.check_write(path.to_str().unwrap()) {
+ if let Err(e) = state.check_write(&path_) {
return odd_future(e);
}
@@ -1175,10 +1196,14 @@ fn op_copy_file(
) -> Box<OpWithError> {
assert!(data.is_none());
let inner = base.inner_as_copy_file().unwrap();
- let from_ = inner.from().unwrap();
- let from = PathBuf::from(from_);
- let to_ = inner.to().unwrap();
- let to = PathBuf::from(to_);
+ let (from, from_) = match resolve_path(inner.from().unwrap()) {
+ Err(err) => return odd_future(err),
+ Ok(v) => v,
+ };
+ let (to, to_) = match resolve_path(inner.to().unwrap()) {
+ Err(err) => return odd_future(err),
+ Ok(v) => v,
+ };
if let Err(e) = state.check_read(&from_) {
return odd_future(e);
@@ -1258,8 +1283,10 @@ fn op_stat(
assert!(data.is_none());
let inner = base.inner_as_stat().unwrap();
let cmd_id = base.cmd_id();
- let filename_ = inner.filename().unwrap();
- let filename = PathBuf::from(filename_);
+ let (filename, filename_) = match resolve_path(inner.filename().unwrap()) {
+ Err(err) => return odd_future(err),
+ Ok(v) => v,
+ };
let lstat = inner.lstat();
if let Err(e) = state.check_read(&filename_) {
@@ -1275,6 +1302,8 @@ fn op_stat(
fs::metadata(&filename)?
};
+ let filename_str = builder.create_string(&filename_);
+
let inner = msg::StatRes::create(
builder,
&msg::StatResArgs {
@@ -1286,6 +1315,7 @@ fn op_stat(
created: to_seconds!(metadata.created()),
mode: get_mode(&metadata.permissions()),
has_mode: cfg!(target_family = "unix"),
+ path: Some(filename_str),
..Default::default()
},
);
@@ -1310,16 +1340,19 @@ fn op_read_dir(
assert!(data.is_none());
let inner = base.inner_as_read_dir().unwrap();
let cmd_id = base.cmd_id();
- let path = String::from(inner.path().unwrap());
+ let (path, path_) = match resolve_path(inner.path().unwrap()) {
+ Err(err) => return odd_future(err),
+ Ok(v) => v,
+ };
- if let Err(e) = state.check_read(&path) {
+ if let Err(e) = state.check_read(&path_) {
return odd_future(e);
}
blocking(base.sync(), move || -> OpResult {
- debug!("op_read_dir {}", path);
+ debug!("op_read_dir {}", path.display());
let builder = &mut FlatBufferBuilder::new();
- let entries: Vec<_> = fs::read_dir(Path::new(&path))?
+ let entries: Vec<_> = fs::read_dir(path)?
.map(|entry| {
let entry = entry.unwrap();
let metadata = entry.metadata().unwrap();
@@ -1370,9 +1403,15 @@ fn op_rename(
) -> Box<OpWithError> {
assert!(data.is_none());
let inner = base.inner_as_rename().unwrap();
- let oldpath = PathBuf::from(inner.oldpath().unwrap());
- let newpath_ = inner.newpath().unwrap();
- let newpath = PathBuf::from(newpath_);
+ let (oldpath, _) = match resolve_path(inner.oldpath().unwrap()) {
+ Err(err) => return odd_future(err),
+ Ok(v) => v,
+ };
+ let (newpath, newpath_) = match resolve_path(inner.newpath().unwrap()) {
+ Err(err) => return odd_future(err),
+ Ok(v) => v,
+ };
+
if let Err(e) = state.check_write(&newpath_) {
return odd_future(e);
}
@@ -1390,9 +1429,14 @@ fn op_link(
) -> Box<OpWithError> {
assert!(data.is_none());
let inner = base.inner_as_link().unwrap();
- let oldname = PathBuf::from(inner.oldname().unwrap());
- let newname_ = inner.newname().unwrap();
- let newname = PathBuf::from(newname_);
+ let (oldname, _) = match resolve_path(inner.oldname().unwrap()) {
+ Err(err) => return odd_future(err),
+ Ok(v) => v,
+ };
+ let (newname, newname_) = match resolve_path(inner.newname().unwrap()) {
+ Err(err) => return odd_future(err),
+ Ok(v) => v,
+ };
if let Err(e) = state.check_write(&newname_) {
return odd_future(e);
@@ -1412,9 +1456,14 @@ fn op_symlink(
) -> Box<OpWithError> {
assert!(data.is_none());
let inner = base.inner_as_symlink().unwrap();
- let oldname = PathBuf::from(inner.oldname().unwrap());
- let newname_ = inner.newname().unwrap();
- let newname = PathBuf::from(newname_);
+ let (oldname, _) = match resolve_path(inner.oldname().unwrap()) {
+ Err(err) => return odd_future(err),
+ Ok(v) => v,
+ };
+ let (newname, newname_) = match resolve_path(inner.newname().unwrap()) {
+ Err(err) => return odd_future(err),
+ Ok(v) => v,
+ };
if let Err(e) = state.check_write(&newname_) {
return odd_future(e);
@@ -1442,8 +1491,10 @@ fn op_read_link(
assert!(data.is_none());
let inner = base.inner_as_readlink().unwrap();
let cmd_id = base.cmd_id();
- let name_ = inner.name().unwrap();
- let name = PathBuf::from(name_);
+ let (name, name_) = match resolve_path(inner.name().unwrap()) {
+ Err(err) => return odd_future(err),
+ Ok(v) => v,
+ };
if let Err(e) = state.check_read(&name_) {
return odd_future(e);
@@ -1547,15 +1598,18 @@ fn op_truncate(
assert!(data.is_none());
let inner = base.inner_as_truncate().unwrap();
- let filename = String::from(inner.name().unwrap());
+ let (filename, filename_) = match resolve_path(inner.name().unwrap()) {
+ Err(err) => return odd_future(err),
+ Ok(v) => v,
+ };
let len = inner.len();
- if let Err(e) = state.check_write(&filename) {
+ if let Err(e) = state.check_write(&filename_) {
return odd_future(e);
}
blocking(base.sync(), move || {
- debug!("op_truncate {} {}", filename, len);
+ debug!("op_truncate {} {}", filename_, len);
let f = fs::OpenOptions::new().write(true).open(&filename)?;
f.set_len(u64::from(len))?;
Ok(empty_buf())