diff --git a/cli/js/fetch_test.ts b/cli/js/fetch_test.ts index 2912d5d2debe11..54bec46bed9d5e 100644 --- a/cli/js/fetch_test.ts +++ b/cli/js/fetch_test.ts @@ -9,6 +9,17 @@ import { fail } from "./test_util.ts"; +testPerm({ net: true }, async function fetchProtocolError(): Promise { + let err; + try { + await fetch("file:///"); + } catch (err_) { + err = err_; + } + assert(err instanceof TypeError); + assertStrContains(err.message, "not supported"); +}); + testPerm({ net: true }, async function fetchConnectionError(): Promise { let err; try { diff --git a/cli/ops/fetch.rs b/cli/ops/fetch.rs index 580fd993ae61ac..9758732c7d51b1 100644 --- a/cli/ops/fetch.rs +++ b/cli/ops/fetch.rs @@ -1,6 +1,8 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. use super::dispatch_json::{Deserialize, JsonOp, Value}; use super::io::StreamResource; +use crate::deno_error::DenoError; +use crate::deno_error::ErrorKind; use crate::http_util::{create_http_client, HttpBody}; use crate::ops::json_op; use crate::state::State; @@ -40,6 +42,19 @@ pub fn op_fetch( }; let url_ = url::Url::parse(&url).map_err(ErrBox::from)?; + + // Check scheme before asking for net permission + let scheme = url_.scheme(); + if scheme != "http" && scheme != "https" { + return Err( + DenoError::new( + ErrorKind::TypeError, + format!("scheme '{}' not supported", scheme), + ) + .into(), + ); + } + state.check_net_url(&url_)?; let mut request = client.request(method, url_); diff --git a/cli/permissions.rs b/cli/permissions.rs index 868f0e009042bd..950bec400a97cf 100644 --- a/cli/permissions.rs +++ b/cli/permissions.rs @@ -1,5 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. use crate::deno_error::{other_error, permission_denied_msg}; +use crate::deno_error::{DenoError, ErrorKind}; use crate::flags::DenoFlags; use ansi_term::Style; #[cfg(not(test))] @@ -193,8 +194,11 @@ impl DenoPermissions { } pub fn check_net_url(&self, url: &url::Url) -> Result<(), ErrBox> { + let host = url.host_str().ok_or_else(|| { + DenoError::new(ErrorKind::URIError, "missing host".to_owned()) + })?; self - .get_state_net(&format!("{}", url.host().unwrap()), url.port()) + .get_state_net(host, url.port()) .check(&format!("network access to \"{}\"", url), "--allow-net") }