mirror of
https://github.com/nushell/nushell
synced 2024-11-15 01:17:07 +00:00
Limit open streaming to non-files, and files > 32mb (#2570)
This commit is contained in:
parent
6eb4a0e87b
commit
dd27aaef1b
1 changed files with 49 additions and 14 deletions
|
@ -682,21 +682,56 @@ impl Shell for FilesystemShell {
|
||||||
name: Span,
|
name: Span,
|
||||||
with_encoding: Option<&'static Encoding>,
|
with_encoding: Option<&'static Encoding>,
|
||||||
) -> Result<BoxStream<'static, Result<StringOrBinary, ShellError>>, ShellError> {
|
) -> Result<BoxStream<'static, Result<StringOrBinary, ShellError>>, ShellError> {
|
||||||
let f = std::fs::File::open(&path).map_err(|e| {
|
let metadata = std::fs::metadata(&path);
|
||||||
ShellError::labeled_error(
|
|
||||||
format!("Error opening file: {:?}", e),
|
|
||||||
"Error opening file",
|
|
||||||
name,
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
let async_reader = futures::io::AllowStdIo::new(f);
|
|
||||||
let sob_stream = FramedRead::new(async_reader, MaybeTextCodec::new(with_encoding))
|
|
||||||
.map_err(|e| {
|
|
||||||
ShellError::unexpected(format!("AsyncRead failed in open function: {:?}", e))
|
|
||||||
})
|
|
||||||
.into_stream();
|
|
||||||
|
|
||||||
Ok(sob_stream.boxed())
|
let read_full = if let Ok(metadata) = metadata {
|
||||||
|
// Arbitrarily capping the file at 32 megs, so we don't try to read large files in all at once
|
||||||
|
metadata.is_file() && metadata.len() < (1024 * 1024 * 32)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
|
if read_full {
|
||||||
|
use futures_codec::Decoder;
|
||||||
|
|
||||||
|
// We should, in theory, be able to read in the whole file as one chunk
|
||||||
|
let buffer = std::fs::read(&path).map_err(|e| {
|
||||||
|
ShellError::labeled_error(
|
||||||
|
format!("Error opening file: {:?}", e),
|
||||||
|
"Error opening file",
|
||||||
|
name,
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let mut bytes_mut = bytes::BytesMut::from(&buffer[..]);
|
||||||
|
|
||||||
|
let mut codec = MaybeTextCodec::new(with_encoding);
|
||||||
|
|
||||||
|
match codec.decode(&mut bytes_mut).map_err(|e| {
|
||||||
|
ShellError::unexpected(format!("AsyncRead failed in open function: {:?}", e))
|
||||||
|
})? {
|
||||||
|
Some(sb) => Ok(futures::stream::iter(vec![Ok(sb)].into_iter()).boxed()),
|
||||||
|
None => Ok(futures::stream::iter(vec![].into_iter()).boxed()),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We don't know that this is a finite file, so treat it as a stream
|
||||||
|
|
||||||
|
let f = std::fs::File::open(&path).map_err(|e| {
|
||||||
|
ShellError::labeled_error(
|
||||||
|
format!("Error opening file: {:?}", e),
|
||||||
|
"Error opening file",
|
||||||
|
name,
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
let async_reader = futures::io::AllowStdIo::new(f);
|
||||||
|
let sob_stream = FramedRead::new(async_reader, MaybeTextCodec::new(with_encoding))
|
||||||
|
.map_err(|e| {
|
||||||
|
ShellError::unexpected(format!("AsyncRead failed in open function: {:?}", e))
|
||||||
|
})
|
||||||
|
.into_stream();
|
||||||
|
|
||||||
|
Ok(sob_stream.boxed())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn save(
|
fn save(
|
||||||
|
|
Loading…
Reference in a new issue