summaryrefslogtreecommitdiff
path: root/runtime/ops
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/ops')
-rw-r--r--runtime/ops/fs.rs16
1 files changed, 14 insertions, 2 deletions
diff --git a/runtime/ops/fs.rs b/runtime/ops/fs.rs
index 501c2ac5f..99b37916d 100644
--- a/runtime/ops/fs.rs
+++ b/runtime/ops/fs.rs
@@ -21,6 +21,7 @@ use deno_crypto::rand::Rng;
use log::debug;
use serde::Deserialize;
use serde::Serialize;
+use std::borrow::Cow;
use std::cell::RefCell;
use std::convert::From;
use std::env::{current_dir, set_current_dir, temp_dir};
@@ -2032,7 +2033,7 @@ fn op_readfile_text_sync(
let permissions = state.borrow_mut::<Permissions>();
let path = Path::new(&path);
permissions.read.check(path)?;
- Ok(std::fs::read_to_string(path)?)
+ Ok(string_from_utf8_lossy(std::fs::read(path)?))
}
#[op]
@@ -2075,7 +2076,7 @@ async fn op_readfile_text_async(
}
let fut = tokio::task::spawn_blocking(move || {
let path = Path::new(&path);
- Ok(String::from_utf8(std::fs::read(path)?)?)
+ Ok(string_from_utf8_lossy(std::fs::read(path)?))
});
if let Some(cancel_rid) = cancel_rid {
let cancel_handle = state
@@ -2088,3 +2089,14 @@ async fn op_readfile_text_async(
}
fut.await?
}
+
+// Like String::from_utf8_lossy but operates on owned values
+fn string_from_utf8_lossy(buf: Vec<u8>) -> String {
+ match String::from_utf8_lossy(&buf) {
+ // buf contained non-utf8 chars than have been patched
+ Cow::Owned(s) => s,
+ // SAFETY: if Borrowed then the buf only contains utf8 chars,
+ // we do this instead of .into_owned() to avoid copying the input buf
+ Cow::Borrowed(_) => unsafe { String::from_utf8_unchecked(buf) },
+ }
+}