From 5363f350887b1e5b5dd21a86f88c8af9d7fea6da Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:18:25 +0200 Subject: Merging upstream version 1.67.1+dfsg1. Signed-off-by: Daniel Baumann --- vendor/tempfile/.cargo-checksum.json | 2 +- vendor/tempfile/Cargo.toml | 26 ++++++++++-------- vendor/tempfile/NEWS | 15 +++++++++++ vendor/tempfile/README.md | 3 +-- vendor/tempfile/src/dir.rs | 31 +++++++++++++-------- vendor/tempfile/src/file/imp/mod.rs | 4 +-- vendor/tempfile/src/file/imp/unix.rs | 41 ++++++++++++++++++++-------- vendor/tempfile/src/file/mod.rs | 30 +++++++++++++++------ vendor/tempfile/src/lib.rs | 41 ++++++++++++++++++++++++++-- vendor/tempfile/src/spooled.rs | 42 ++++++++++++++++------------- vendor/tempfile/src/util.rs | 17 ++++-------- vendor/tempfile/tests/namedtempfile.rs | 49 ++++++++++++++++++++++++++++++++-- vendor/tempfile/tests/tempfile.rs | 2 ++ 13 files changed, 223 insertions(+), 80 deletions(-) (limited to 'vendor/tempfile') diff --git a/vendor/tempfile/.cargo-checksum.json b/vendor/tempfile/.cargo-checksum.json index 23317fe66..26f8560bc 100644 --- a/vendor/tempfile/.cargo-checksum.json +++ b/vendor/tempfile/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"f6fe37104892c596e599d429d38ed5c59ea4cda7f2ed3ab15e50bd15b85dcc80","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"8b427f5bc501764575e52ba4f9d95673cf8f6d80a86d0d06599852e1a9a20a36","NEWS":"b7f16a3c82513cfe6aca7f22cf3057114e0e4d3c65172dac19b6fd0c7ca5cf58","README.md":"266c55fcd9262b9ade8d8e9b705e8ad40db7df1d422be70f80d1e8ba133f1eab","src/dir.rs":"67f56aac82deefef56e3dc1366d2df1e5c6792103031119655088eb49c38f4c4","src/error.rs":"cc7d8eace0fff11cb342158d2885d5637bfb14b24ef30755e808554772039c5f","src/file/imp/mod.rs":"bec50fb99c14cb4a49402bdbb7c5e6b5b8ff785b06b6fcb13267f35df8f3c8c2","src/file/imp/other.rs":"99c8f9f3251199fc31e7b88810134712e5725fb6fa14648696ed5cbea980fc5b","src/file/imp/unix.rs":"afc860978e362b1266b40722181fc3a509af72ce942a1b2dcd38ef1776897af3","src/file/imp/windows.rs":"03d81d71c404f0d448e1162825d6fbd57a78b4af8d4dc5287ec2e7c5a873d7cc","src/file/mod.rs":"361397d93831d0d9ba9a234781017de77a7b94b88f0cab2439420d2797c9c229","src/lib.rs":"214ccbdd7de0196f2c76daf604ee0cf6b7ddd0478825aab8b4b32c000dcf817a","src/spooled.rs":"34f5305923de710c58228d68c143133a11843e7ad5029ee31448ab4ab6172b74","src/util.rs":"73d971b603f9f997ab62e743c76891a9478bdce6e1898e70185f1fe66ded74ad","tests/namedtempfile.rs":"07ad89e54c9ce79d6b85d37d367d9687ec6f2cabc6cc44cdefd42731056afd6a","tests/spooled.rs":"29e797d486d867cb6ac46d4cf126eb5868a069a4070c3f50ffa02fbb0b887934","tests/tempdir.rs":"771d555d4eaa410207d212eb3744e016e0b5a22f1f1b7199636a4fac5daaf952","tests/tempfile.rs":"a1dacfd9b1ee3c40fdde5131b33995f3cfd62a212455c8664a98c735b9954ee6"},"package":"dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"} \ No newline at end of file +{"files":{"Cargo.toml":"685243e302f6e014de9c8e9b95596e5f63c7bf7fde42e8e66a41a6bc7fd5e803","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"8b427f5bc501764575e52ba4f9d95673cf8f6d80a86d0d06599852e1a9a20a36","NEWS":"4255c86ac140a4d08423cd05cbd0aa42ff796bb4b38579dd19cde289ee3baecd","README.md":"db6717cbd0b3cbbce5f3cdb8a80d8f2d90b1be251b4c1c647557ae0f78ec9748","src/dir.rs":"4499ff439b740f8d2f01458664e2bf72bbfdd1206226780c6a91fb309ef15707","src/error.rs":"cc7d8eace0fff11cb342158d2885d5637bfb14b24ef30755e808554772039c5f","src/file/imp/mod.rs":"f6da9fcd93f11889670a251fdd8231b5f4614e5a971b7b183f52b44af68568d5","src/file/imp/other.rs":"99c8f9f3251199fc31e7b88810134712e5725fb6fa14648696ed5cbea980fc5b","src/file/imp/unix.rs":"cf8eeceecfddc37c9eaf95a1ebe088314dc468f07fe357961d80817eef619ca4","src/file/imp/windows.rs":"03d81d71c404f0d448e1162825d6fbd57a78b4af8d4dc5287ec2e7c5a873d7cc","src/file/mod.rs":"bda4ee3998106089a4c0ccbc8e46dc22b7d3aec427487fd4e414fb132b378736","src/lib.rs":"e2b0df7e17cc6680a5bb0829d0433f069c6bf9eede2007d21e3b01a595df41a8","src/spooled.rs":"51fa1d7639027234e257d343a5d3c95f2e47899ba6a24f0abec8d4d729eba6d6","src/util.rs":"2bd80ee69009e7e36b596d0105bb00184cff04e899e9fcce2e4cc21f23dda073","tests/namedtempfile.rs":"0031cb33ae6faf45be103869b4d98af63bef4040dc489b323212eb7a7ef72a9a","tests/spooled.rs":"29e797d486d867cb6ac46d4cf126eb5868a069a4070c3f50ffa02fbb0b887934","tests/tempdir.rs":"771d555d4eaa410207d212eb3744e016e0b5a22f1f1b7199636a4fac5daaf952","tests/tempfile.rs":"92078a1e20a39af77c1daa9a422345d20c41584dd2010b4829911c8741d1c628"},"package":"5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"} \ No newline at end of file diff --git a/vendor/tempfile/Cargo.toml b/vendor/tempfile/Cargo.toml index 036714356..253f8667b 100644 --- a/vendor/tempfile/Cargo.toml +++ b/vendor/tempfile/Cargo.toml @@ -3,17 +3,16 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g., crates.io) dependencies +# to registry (e.g., crates.io) dependencies. # -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. [package] edition = "2018" name = "tempfile" -version = "3.2.0" +version = "3.3.0" authors = ["Steven Allen ", "The Rust Project Developers", "Ashley Mannix ", "Jason White "] exclude = ["/.travis.yml", "/appveyor.yml"] description = "A library for managing temporary files and directories." @@ -25,15 +24,20 @@ repository = "https://github.com/Stebalien/tempfile" [dependencies.cfg-if] version = "1" -[dependencies.rand] -version = "0.8" +[dependencies.fastrand] +version = "1.6.0" [dependencies.remove_dir_all] version = "0.5" -[target."cfg(target_os = \"redox\")".dependencies.redox_syscall] -version = "0.2" -[target."cfg(unix)".dependencies.libc] +[dev-dependencies.doc-comment] +version = "0.3" + +[features] +nightly = [] +[target."cfg(any(unix, target_os = \"wasi\"))".dependencies.libc] version = "0.2.27" +[target."cfg(target_os = \"redox\")".dependencies.redox_syscall] +version = "0.2.9" [target."cfg(windows)".dependencies.winapi] version = "0.3" features = ["fileapi", "handleapi", "winbase"] diff --git a/vendor/tempfile/NEWS b/vendor/tempfile/NEWS index 6c83656e7..c28442426 100644 --- a/vendor/tempfile/NEWS +++ b/vendor/tempfile/NEWS @@ -1,3 +1,18 @@ +3.3.0 +===== + +Features: + +* Replace rand with fastrand for a significantly smaller dependency tree. Cryptographic randomness + isn't necessary for temporary file names, and isn't all that helpful either. +* Add limited WASI support. +* Add a function to extract the inner data from a `SpooledTempFile`. + +Bug Fixes: + +* Make it possible to persist unnamed temporary files on linux by removing the `O_EXCL` flag. +* Fix redox minimum crate version. + 3.2.0 ===== diff --git a/vendor/tempfile/README.md b/vendor/tempfile/README.md index 5b8fb3829..1dba3a01d 100644 --- a/vendor/tempfile/README.md +++ b/vendor/tempfile/README.md @@ -2,8 +2,7 @@ tempfile ======== [![Crate](https://img.shields.io/crates/v/tempfile.svg)](https://crates.io/crates/tempfile) -[![Build Status](https://travis-ci.org/Stebalien/tempfile.svg?branch=master)](https://travis-ci.org/Stebalien/tempfile) -[![Build status](https://ci.appveyor.com/api/projects/status/5q00b8rvvg46i5tf/branch/master?svg=true)](https://ci.appveyor.com/project/Stebalien/tempfile/branch/master) +[![Build Status](https://github.com/Stebalien/tempfile/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/Stebalien/tempfile/actions/workflows/ci.yml?query=branch%3Amaster) A secure, cross-platform, temporary file library for Rust. In addition to creating temporary files, this library also allows users to securely open multiple diff --git a/vendor/tempfile/src/dir.rs b/vendor/tempfile/src/dir.rs index d6307627f..d5a944b6f 100644 --- a/vendor/tempfile/src/dir.rs +++ b/vendor/tempfile/src/dir.rs @@ -9,6 +9,7 @@ // except according to those terms. use remove_dir_all::remove_dir_all; +use std::mem; use std::path::{self, Path, PathBuf}; use std::{fmt, fs, io}; @@ -192,7 +193,7 @@ pub fn tempdir_in>(dir: P) -> io::Result { /// [`std::fs`]: http://doc.rust-lang.org/std/fs/index.html /// [`std::process::exit()`]: http://doc.rust-lang.org/std/process/fn.exit.html pub struct TempDir { - path: Option, + path: Box, } impl TempDir { @@ -292,7 +293,7 @@ impl TempDir { /// # } /// ``` pub fn path(&self) -> &path::Path { - self.path.as_ref().unwrap() + self.path.as_ref() } /// Persist the temporary directory to disk, returning the [`PathBuf`] where it is located. @@ -322,8 +323,13 @@ impl TempDir { /// # Ok(()) /// # } /// ``` - pub fn into_path(mut self) -> PathBuf { - self.path.take().unwrap() + pub fn into_path(self) -> PathBuf { + // Prevent the Drop impl from being called. + let mut this = mem::ManuallyDrop::new(self); + + // replace this.path with an empty Box, since an empty Box does not + // allocate any heap memory. + mem::replace(&mut this.path, PathBuf::new().into_boxed_path()).into() } /// Closes and removes the temporary directory, returning a `Result`. @@ -369,8 +375,12 @@ impl TempDir { pub fn close(mut self) -> io::Result<()> { let result = remove_dir_all(self.path()).with_err_path(|| self.path()); - // Prevent the Drop impl from removing the dir a second time. - self.path = None; + // Set self.path to empty Box to release the memory, since an empty + // Box does not allocate any heap memory. + self.path = PathBuf::new().into_boxed_path(); + + // Prevent the Drop impl from being called. + mem::forget(self); result } @@ -392,15 +402,14 @@ impl fmt::Debug for TempDir { impl Drop for TempDir { fn drop(&mut self) { - // Path is `None` if `close()` or `into_path()` has been called. - if let Some(ref p) = self.path { - let _ = remove_dir_all(p); - } + let _ = remove_dir_all(self.path()); } } pub(crate) fn create(path: PathBuf) -> io::Result { fs::create_dir(&path) .with_err_path(|| &path) - .map(|_| TempDir { path: Some(path) }) + .map(|_| TempDir { + path: path.into_boxed_path(), + }) } diff --git a/vendor/tempfile/src/file/imp/mod.rs b/vendor/tempfile/src/file/imp/mod.rs index 31e872886..fbb2bbf63 100644 --- a/vendor/tempfile/src/file/imp/mod.rs +++ b/vendor/tempfile/src/file/imp/mod.rs @@ -1,5 +1,5 @@ -cfg_if! { - if #[cfg(any(unix, target_os = "redox"))] { +cfg_if::cfg_if! { + if #[cfg(any(unix, target_os = "redox", target_os = "wasi"))] { mod unix; pub use self::unix::*; } else if #[cfg(windows)] { diff --git a/vendor/tempfile/src/file/imp/unix.rs b/vendor/tempfile/src/file/imp/unix.rs index 35b1ddb1e..480743cf7 100644 --- a/vendor/tempfile/src/file/imp/unix.rs +++ b/vendor/tempfile/src/file/imp/unix.rs @@ -2,10 +2,18 @@ use std::env; use std::ffi::{CString, OsStr}; use std::fs::{self, File, OpenOptions}; use std::io; -use std::os::unix::ffi::OsStrExt; -use std::os::unix::fs::{MetadataExt, OpenOptionsExt}; -use std::path::Path; +cfg_if::cfg_if! { + if #[cfg(not(target_os = "wasi"))] { + use std::os::unix::ffi::OsStrExt; + use std::os::unix::fs::{MetadataExt, OpenOptionsExt}; + } else { + use std::os::wasi::ffi::OsStrExt; + #[cfg(feature = "nightly")] + use std::os::wasi::fs::MetadataExt; + } +} use crate::util; +use std::path::Path; #[cfg(not(target_os = "redox"))] use libc::{c_char, c_int, link, rename, unlink}; @@ -33,12 +41,14 @@ pub fn cstr(path: &Path) -> io::Result { } pub fn create_named(path: &Path, open_options: &mut OpenOptions) -> io::Result { - open_options - .read(true) - .write(true) - .create_new(true) - .mode(0o600) - .open(path) + open_options.read(true).write(true).create_new(true); + + #[cfg(not(target_os = "wasi"))] + { + open_options.mode(0o600); + } + + open_options.open(path) } fn create_unlinked(path: &Path) -> io::Result { @@ -60,11 +70,11 @@ fn create_unlinked(path: &Path) -> io::Result { #[cfg(target_os = "linux")] pub fn create(dir: &Path) -> io::Result { - use libc::{EISDIR, ENOENT, EOPNOTSUPP, O_EXCL, O_TMPFILE}; + use libc::{EISDIR, ENOENT, EOPNOTSUPP, O_TMPFILE}; OpenOptions::new() .read(true) .write(true) - .custom_flags(O_TMPFILE | O_EXCL) // do not mix with `create_new(true)` + .custom_flags(O_TMPFILE) // do not mix with `create_new(true)` .open(dir) .or_else(|e| { match e.raw_os_error() { @@ -90,6 +100,7 @@ fn create_unix(dir: &Path) -> io::Result { ) } +#[cfg(any(not(target_os = "wasi"), feature = "nightly"))] pub fn reopen(file: &File, path: &Path) -> io::Result { let new_file = OpenOptions::new().read(true).write(true).open(path)?; let old_meta = file.metadata()?; @@ -103,6 +114,14 @@ pub fn reopen(file: &File, path: &Path) -> io::Result { Ok(new_file) } +#[cfg(all(target_os = "wasi", not(feature = "nightly")))] +pub fn reopen(_file: &File, _path: &Path) -> io::Result { + return Err(io::Error::new( + io::ErrorKind::Other, + "this operation is supported on WASI only on nightly Rust (with `nightly` feature enabled)", + )); +} + #[cfg(not(target_os = "redox"))] pub fn persist(old_path: &Path, new_path: &Path, overwrite: bool) -> io::Result<()> { unsafe { diff --git a/vendor/tempfile/src/file/mod.rs b/vendor/tempfile/src/file/mod.rs index 31fdd4bed..b859ced79 100644 --- a/vendor/tempfile/src/file/mod.rs +++ b/vendor/tempfile/src/file/mod.rs @@ -138,7 +138,7 @@ impl error::Error for PathPersistError { /// /// When dropped, the temporary file is deleted. pub struct TempPath { - path: PathBuf, + path: Box, } impl TempPath { @@ -176,8 +176,8 @@ impl TempPath { /// # } /// ``` pub fn close(mut self) -> io::Result<()> { - let result = fs::remove_file(&self.path).with_err_path(|| &self.path); - self.path = PathBuf::new(); + let result = fs::remove_file(&self.path).with_err_path(|| &*self.path); + self.path = PathBuf::new().into_boxed_path(); mem::forget(self); result } @@ -231,7 +231,7 @@ impl TempPath { // Don't drop `self`. We don't want to try deleting the old // temporary file path. (It'll fail, but the failure is never // seen.) - self.path = PathBuf::new(); + self.path = PathBuf::new().into_boxed_path(); mem::forget(self); Ok(()) } @@ -293,7 +293,7 @@ impl TempPath { // Don't drop `self`. We don't want to try deleting the old // temporary file path. (It'll fail, but the failure is never // seen.) - self.path = PathBuf::new(); + self.path = PathBuf::new().into_boxed_path(); mem::forget(self); Ok(()) } @@ -341,9 +341,9 @@ impl TempPath { // Don't drop `self`. We don't want to try deleting the old // temporary file path. (It'll fail, but the failure is never // seen.) - let path = mem::replace(&mut self.path, PathBuf::new()); + let path = mem::replace(&mut self.path, PathBuf::new().into_boxed_path()); mem::forget(self); - Ok(path) + Ok(path.into()) } Err(e) => Err(PathPersistError { error: e, @@ -351,6 +351,18 @@ impl TempPath { }), } } + + /// Create a new TempPath from an existing path. This can be done even if no + /// file exists at the given path. + /// + /// This is mostly useful for interacting with libraries and external + /// components that provide files to be consumed or expect a path with no + /// existing file to be given. + pub fn from_path(path: impl Into) -> Self { + Self { + path: path.into().into_boxed_path(), + } + } } impl fmt::Debug for TempPath { @@ -953,7 +965,9 @@ pub(crate) fn create_named( imp::create_named(&path, open_options) .with_err_path(|| path.clone()) .map(|file| NamedTempFile { - path: TempPath { path }, + path: TempPath { + path: path.into_boxed_path(), + }, file, }) } diff --git a/vendor/tempfile/src/lib.rs b/vendor/tempfile/src/lib.rs index 51c2da09a..c38ca7b87 100644 --- a/vendor/tempfile/src/lib.rs +++ b/vendor/tempfile/src/lib.rs @@ -27,6 +27,42 @@ //! rely on file paths for _some_ operations. See the security documentation on //! the `NamedTempFile` type for more information. //! +//! ## Early drop pitfall +//! +//! Because `TempDir` and `NamedTempFile` rely on their destructors for cleanup, this can lead +//! to an unexpected early removal of the directory/file, usually when working with APIs which are +//! generic over `AsRef`. Consider the following example: +//! +//! ```no_run +//! # use tempfile::tempdir; +//! # use std::io; +//! # use std::process::Command; +//! # fn main() { +//! # if let Err(_) = run() { +//! # ::std::process::exit(1); +//! # } +//! # } +//! # fn run() -> Result<(), io::Error> { +//! // Create a directory inside of `std::env::temp_dir()`. +//! let temp_dir = tempdir()?; +//! +//! // Spawn the `touch` command inside the temporary directory and collect the exit status +//! // Note that `temp_dir` is **not** moved into `current_dir`, but passed as a reference +//! let exit_status = Command::new("touch").arg("tmp").current_dir(&temp_dir).status()?; +//! assert!(exit_status.success()); +//! +//! # Ok(()) +//! # } +//! ``` +//! +//! This works because a reference to `temp_dir` is passed to `current_dir`, resulting in the +//! destructor of `temp_dir` being run after the `Command` has finished execution. Moving the +//! `TempDir` into the `current_dir` call would result in the `TempDir` being converted into +//! an internal representation, with the original value being dropped and the directory thus +//! being deleted, before the command can be executed. +//! +//! The `touch` command would fail with an `No such file or directory` error. +//! //! ## Examples //! //! Create a temporary file and write some data into it: @@ -125,9 +161,10 @@ #![cfg_attr(test, deny(warnings))] #![deny(rust_2018_idioms)] #![allow(clippy::redundant_field_names)] +#![cfg_attr(feature = "nightly", feature(wasi_ext))] -#[macro_use] -extern crate cfg_if; +#[cfg(doctest)] +doc_comment::doctest!("../README.md"); const NUM_RETRIES: u32 = 1 << 31; const NUM_RAND_CHARS: usize = 6; diff --git a/vendor/tempfile/src/spooled.rs b/vendor/tempfile/src/spooled.rs index e6f750e58..ed6c16fb4 100644 --- a/vendor/tempfile/src/spooled.rs +++ b/vendor/tempfile/src/spooled.rs @@ -2,8 +2,9 @@ use crate::file::tempfile; use std::fs::File; use std::io::{self, Cursor, Read, Seek, SeekFrom, Write}; +/// A wrapper for the two states of a `SpooledTempFile`. #[derive(Debug)] -enum SpooledInner { +pub enum SpooledData { InMemory(Cursor>), OnDisk(File), } @@ -15,7 +16,7 @@ enum SpooledInner { #[derive(Debug)] pub struct SpooledTempFile { max_size: usize, - inner: SpooledInner, + inner: SpooledData, } /// Create a new spooled temporary file. @@ -66,15 +67,15 @@ impl SpooledTempFile { pub fn new(max_size: usize) -> SpooledTempFile { SpooledTempFile { max_size: max_size, - inner: SpooledInner::InMemory(Cursor::new(Vec::new())), + inner: SpooledData::InMemory(Cursor::new(Vec::new())), } } /// Returns true if the file has been rolled over to disk. pub fn is_rolled(&self) -> bool { match self.inner { - SpooledInner::InMemory(_) => false, - SpooledInner::OnDisk(_) => true, + SpooledData::InMemory(_) => false, + SpooledData::OnDisk(_) => true, } } @@ -83,11 +84,11 @@ impl SpooledTempFile { pub fn roll(&mut self) -> io::Result<()> { if !self.is_rolled() { let mut file = tempfile()?; - if let SpooledInner::InMemory(ref mut cursor) = self.inner { + if let SpooledData::InMemory(ref mut cursor) = self.inner { file.write_all(cursor.get_ref())?; file.seek(SeekFrom::Start(cursor.position()))?; } - self.inner = SpooledInner::OnDisk(file); + self.inner = SpooledData::OnDisk(file); } Ok(()) } @@ -97,20 +98,25 @@ impl SpooledTempFile { self.roll()?; // does nothing if already rolled over } match self.inner { - SpooledInner::InMemory(ref mut cursor) => { + SpooledData::InMemory(ref mut cursor) => { cursor.get_mut().resize(size as usize, 0); Ok(()) } - SpooledInner::OnDisk(ref mut file) => file.set_len(size), + SpooledData::OnDisk(ref mut file) => file.set_len(size), } } + + /// Consumes and returns the inner `SpooledData` type. + pub fn into_inner(self) -> SpooledData { + self.inner + } } impl Read for SpooledTempFile { fn read(&mut self, buf: &mut [u8]) -> io::Result { match self.inner { - SpooledInner::InMemory(ref mut cursor) => cursor.read(buf), - SpooledInner::OnDisk(ref mut file) => file.read(buf), + SpooledData::InMemory(ref mut cursor) => cursor.read(buf), + SpooledData::OnDisk(ref mut file) => file.read(buf), } } } @@ -119,7 +125,7 @@ impl Write for SpooledTempFile { fn write(&mut self, buf: &[u8]) -> io::Result { // roll over to file if necessary let mut rolling = false; - if let SpooledInner::InMemory(ref mut cursor) = self.inner { + if let SpooledData::InMemory(ref mut cursor) = self.inner { rolling = cursor.position() as usize + buf.len() > self.max_size; } if rolling { @@ -128,16 +134,16 @@ impl Write for SpooledTempFile { // write the bytes match self.inner { - SpooledInner::InMemory(ref mut cursor) => cursor.write(buf), - SpooledInner::OnDisk(ref mut file) => file.write(buf), + SpooledData::InMemory(ref mut cursor) => cursor.write(buf), + SpooledData::OnDisk(ref mut file) => file.write(buf), } } #[inline] fn flush(&mut self) -> io::Result<()> { match self.inner { - SpooledInner::InMemory(ref mut cursor) => cursor.flush(), - SpooledInner::OnDisk(ref mut file) => file.flush(), + SpooledData::InMemory(ref mut cursor) => cursor.flush(), + SpooledData::OnDisk(ref mut file) => file.flush(), } } } @@ -145,8 +151,8 @@ impl Write for SpooledTempFile { impl Seek for SpooledTempFile { fn seek(&mut self, pos: SeekFrom) -> io::Result { match self.inner { - SpooledInner::InMemory(ref mut cursor) => cursor.seek(pos), - SpooledInner::OnDisk(ref mut file) => file.seek(pos), + SpooledData::InMemory(ref mut cursor) => cursor.seek(pos), + SpooledData::OnDisk(ref mut file) => file.seek(pos), } } } diff --git a/vendor/tempfile/src/util.rs b/vendor/tempfile/src/util.rs index aa76bb256..8c91b9c69 100644 --- a/vendor/tempfile/src/util.rs +++ b/vendor/tempfile/src/util.rs @@ -1,23 +1,16 @@ -use rand::distributions::Alphanumeric; -use rand::{self, Rng}; +use fastrand; use std::ffi::{OsStr, OsString}; use std::path::{Path, PathBuf}; -use std::{io, str}; +use std::{io, iter::repeat_with}; use crate::error::IoResultExt; fn tmpname(prefix: &OsStr, suffix: &OsStr, rand_len: usize) -> OsString { let mut buf = OsString::with_capacity(prefix.len() + suffix.len() + rand_len); buf.push(prefix); - - // Push each character in one-by-one. Unfortunately, this is the only - // safe(ish) simple way to do this without allocating a temporary - // String/Vec. - unsafe { - rand::thread_rng() - .sample_iter(&Alphanumeric) - .take(rand_len) - .for_each(|b| buf.push(str::from_utf8_unchecked(&[b as u8]))) + let mut char_buf = [0u8; 4]; + for c in repeat_with(fastrand::alphanumeric).take(rand_len) { + buf.push(c.encode_utf8(&mut char_buf)); } buf.push(suffix); buf diff --git a/vendor/tempfile/tests/namedtempfile.rs b/vendor/tempfile/tests/namedtempfile.rs index a489d56db..d2c7da22b 100644 --- a/vendor/tempfile/tests/namedtempfile.rs +++ b/vendor/tempfile/tests/namedtempfile.rs @@ -1,10 +1,11 @@ #![deny(rust_2018_idioms)] use std::env; +use std::ffi::{OsStr, OsString}; use std::fs::File; use std::io::{Read, Seek, SeekFrom, Write}; -use std::path::Path; -use tempfile::{Builder, NamedTempFile}; +use std::path::{Path, PathBuf}; +use tempfile::{tempdir, Builder, NamedTempFile, TempPath}; fn exists>(path: P) -> bool { std::fs::metadata(path.as_ref()).is_ok() @@ -216,6 +217,50 @@ fn test_temppath_persist_noclobber() { std::fs::remove_file(&persist_path).unwrap(); } +#[test] +fn temp_path_from_existing() { + let tmp_dir = tempdir().unwrap(); + let tmp_file_path_1 = tmp_dir.path().join("testfile1"); + let tmp_file_path_2 = tmp_dir.path().join("testfile2"); + + File::create(&tmp_file_path_1).unwrap(); + assert!(tmp_file_path_1.exists(), "Test file 1 hasn't been created"); + + File::create(&tmp_file_path_2).unwrap(); + assert!(tmp_file_path_2.exists(), "Test file 2 hasn't been created"); + + let tmp_path = TempPath::from_path(&tmp_file_path_1); + assert!( + tmp_file_path_1.exists(), + "Test file has been deleted before dropping TempPath" + ); + + drop(tmp_path); + assert!( + !tmp_file_path_1.exists(), + "Test file exists after dropping TempPath" + ); + assert!( + tmp_file_path_2.exists(), + "Test file 2 has been deleted before dropping TempDir" + ); +} + +#[test] +#[allow(unreachable_code)] +fn temp_path_from_argument_types() { + // This just has to compile + return; + + TempPath::from_path(""); + TempPath::from_path(String::new()); + TempPath::from_path(OsStr::new("")); + TempPath::from_path(OsString::new()); + TempPath::from_path(Path::new("")); + TempPath::from_path(PathBuf::new()); + TempPath::from_path(PathBuf::new().into_boxed_path()); +} + #[test] fn test_write_after_close() { let path = NamedTempFile::new().unwrap().into_temp_path(); diff --git a/vendor/tempfile/tests/tempfile.rs b/vendor/tempfile/tests/tempfile.rs index 065dccbe1..f4dddb290 100644 --- a/vendor/tempfile/tests/tempfile.rs +++ b/vendor/tempfile/tests/tempfile.rs @@ -26,6 +26,8 @@ fn test_cleanup() { assert!(num_files == 0); } +// Only run this test on Linux. MacOS doesn't like us creating so many files, apparently. +#[cfg(target_os = "linux")] #[test] fn test_pathological_cleaner() { let tmpdir = tempfile::tempdir().unwrap(); -- cgit v1.2.3