summaryrefslogtreecommitdiff
path: root/runtime/permissions.rs
diff options
context:
space:
mode:
authorDavid Sherret <dsherret@users.noreply.github.com>2022-04-18 09:00:38 -0400
committerGitHub <noreply@github.com>2022-04-18 09:00:38 -0400
commit7919dc902d3664bb8600be884ec775f44fd37389 (patch)
tree363541a85729531416bf4d3f6ada28889cdee800 /runtime/permissions.rs
parent9c5928b5aa3716f7441694da24982cecacb7a061 (diff)
fix(permissions): fallback to denied access if the permission prompt fails (#14235)
Diffstat (limited to 'runtime/permissions.rs')
-rw-r--r--runtime/permissions.rs57
1 files changed, 34 insertions, 23 deletions
diff --git a/runtime/permissions.rs b/runtime/permissions.rs
index 095e67467..be6c0c188 100644
--- a/runtime/permissions.rs
+++ b/runtime/permissions.rs
@@ -1885,13 +1885,15 @@ fn permission_prompt(message: &str, name: &str) -> bool {
};
#[cfg(unix)]
- fn clear_stdin() {
+ fn clear_stdin() -> Result<(), AnyError> {
let r = unsafe { libc::tcflush(0, libc::TCIFLUSH) };
assert_eq!(r, 0);
+ Ok(())
}
#[cfg(not(unix))]
- fn clear_stdin() {
+ fn clear_stdin() -> Result<(), AnyError> {
+ use deno_core::anyhow::bail;
use winapi::shared::minwindef::TRUE;
use winapi::shared::minwindef::UINT;
use winapi::shared::minwindef::WORD;
@@ -1911,31 +1913,34 @@ fn permission_prompt(message: &str, name: &str) -> bool {
unsafe {
let stdin = GetStdHandle(STD_INPUT_HANDLE);
// emulate an enter key press to clear any line buffered console characters
- emulate_enter_key_press(stdin);
+ emulate_enter_key_press(stdin)?;
// read the buffered line or enter key press
- read_stdin_line();
+ read_stdin_line()?;
// check if our emulated key press was executed
- if is_input_buffer_empty(stdin) {
+ if is_input_buffer_empty(stdin)? {
// if so, move the cursor up to prevent a blank line
- move_cursor_up();
+ move_cursor_up()?;
} else {
// the emulated key press is still pending, so a buffered line was read
// and we can flush the emulated key press
- flush_input_buffer(stdin);
+ flush_input_buffer(stdin)?;
}
}
- unsafe fn flush_input_buffer(stdin: HANDLE) {
+ return Ok(());
+
+ unsafe fn flush_input_buffer(stdin: HANDLE) -> Result<(), AnyError> {
let success = FlushConsoleInputBuffer(stdin);
if success != TRUE {
- panic!(
- "Error flushing console input buffer: {}",
+ bail!(
+ "Could not flush the console input buffer: {}",
std::io::Error::last_os_error()
)
}
+ Ok(())
}
- unsafe fn emulate_enter_key_press(stdin: HANDLE) {
+ unsafe fn emulate_enter_key_press(stdin: HANDLE) -> Result<(), AnyError> {
// https://github.com/libuv/libuv/blob/a39009a5a9252a566ca0704d02df8dabc4ce328f/src/win/tty.c#L1121-L1131
let mut input_record: INPUT_RECORD = std::mem::zeroed();
input_record.EventType = KEY_EVENT;
@@ -1951,42 +1956,48 @@ fn permission_prompt(message: &str, name: &str) -> bool {
let success =
WriteConsoleInputW(stdin, &input_record, 1, &mut record_written);
if success != TRUE {
- panic!(
- "Error emulating enter key press: {}",
+ bail!(
+ "Could not emulate enter key press: {}",
std::io::Error::last_os_error()
- )
+ );
}
+ Ok(())
}
- unsafe fn is_input_buffer_empty(stdin: HANDLE) -> bool {
+ unsafe fn is_input_buffer_empty(stdin: HANDLE) -> Result<bool, AnyError> {
let mut buffer = Vec::with_capacity(1);
let mut events_read = 0;
let success =
PeekConsoleInputW(stdin, buffer.as_mut_ptr(), 1, &mut events_read);
if success != TRUE {
- panic!(
- "Error peeking console input buffer: {}",
+ bail!(
+ "Could not peek the console input buffer: {}",
std::io::Error::last_os_error()
)
}
- events_read == 0
+ Ok(events_read == 0)
}
- fn move_cursor_up() {
+ fn move_cursor_up() -> Result<(), AnyError> {
use std::io::Write;
- write!(std::io::stderr(), "\x1B[1A").expect("expected to move cursor up");
+ write!(std::io::stderr(), "\x1B[1A")?;
+ Ok(())
}
- fn read_stdin_line() {
+ fn read_stdin_line() -> Result<(), AnyError> {
let mut input = String::new();
let stdin = std::io::stdin();
- stdin.read_line(&mut input).expect("expected to read line");
+ stdin.read_line(&mut input)?;
+ Ok(())
}
}
// For security reasons we must consume everything in stdin so that previously
// buffered data cannot effect the prompt.
- clear_stdin();
+ if let Err(err) = clear_stdin() {
+ eprintln!("Error clearing stdin for permission prompt. {:#}", err);
+ return false; // don't grant permission if this fails
+ }
let opts = "[y/n (y = yes allow, n = no deny)] ";
let msg = format!(