From 7cb860821a6798dc6d870bfecf7860e0de2604a9 Mon Sep 17 00:00:00 2001 From: Matthew Brown Date: Wed, 21 May 2025 01:58:38 -0400 Subject: [PATCH 1/4] Remove `os_string_truncate` usage from `path::normalize` --- src/path.rs | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/path.rs b/src/path.rs index 45ba6accd41b..10c460b1894e 100644 --- a/src/path.rs +++ b/src/path.rs @@ -3,7 +3,7 @@ //! Path related helpers. -use std::ffi::OsStr; +use std::ffi::{OsStr, OsString}; use std::path::{Component, MAIN_SEPARATOR_STR, Path, PathBuf}; /// Normalizes a given path by removing redundant components. @@ -23,14 +23,24 @@ pub fn normalize(path: &Path) -> PathBuf { } Component::CurDir => {} Component::ParentDir => { - // Get the length up to the parent directory - if let Some(len) = res - .parent() - .map(|p| p.as_os_str().as_encoded_bytes().len()) - // Ensure we don't pop the root directory - && len >= root_len + // Get length up to the parent directory and truncate, but ensure we don't pop the root directory. + // NB: this compares the system-dependent "encoded length" as discussed in OsString's documentation. + if let Some(parent) = res.parent() + && parent.as_os_str().len() >= root_len { - res.as_mut_os_string().truncate(len); + // To actually truncate the OsString, convert it to raw bytes first, truncate the Vec, then convert + // it back. + // [FIXME] Can be replaced with a plain `res.as_mut_os_string().truncate(parent_len)` once + // `os_string_truncate` is stabilized (#133262) + let byte_len = parent.as_os_str().as_encoded_bytes().len(); + let mut bytes = res.into_os_string().into_encoded_bytes(); + bytes.truncate(byte_len); + // SAFETY: All encoding concerns of `OsString` are met: + // - the provided bytes came directly from a known-to-be-valid `OsStr`, `res`. + // - since `parent` is also a valid `OsStr`, trimming at its byte length must also be at a valid + // boundary. + // This is very similar the example given in `OsStr::from_encoded_bytes_unchecked`'s documentation. + res = unsafe { OsString::from_encoded_bytes_unchecked(bytes).into() }; } } Component::Normal(p) => res.push(p), From 3c991603057252f7ead34417c92e7ebd9465ba0e Mon Sep 17 00:00:00 2001 From: Matthew Brown Date: Wed, 21 May 2025 02:01:08 -0400 Subject: [PATCH 2/4] Remove `os_string_truncate` from features lists --- src/bin/edit/main.rs | 2 +- src/lib.rs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/bin/edit/main.rs b/src/bin/edit/main.rs index 2c840045ebd3..1512c72c3850 100644 --- a/src/bin/edit/main.rs +++ b/src/bin/edit/main.rs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -#![feature(let_chains, linked_list_cursors, os_string_truncate, string_from_utf8_lossy_owned)] +#![feature(let_chains, linked_list_cursors, string_from_utf8_lossy_owned)] mod documents; mod draw_editor; diff --git a/src/lib.rs b/src/lib.rs index e0e5aeba58a7..ec168a031dde 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,7 +10,6 @@ maybe_uninit_fill, maybe_uninit_slice, maybe_uninit_uninit_array_transpose, - os_string_truncate )] #![allow(clippy::missing_transmute_annotations, clippy::new_without_default, stable_features)] From 95e6e36f477c8da32c8881f48bfd42c26bcbb29f Mon Sep 17 00:00:00 2001 From: Matthew Brown Date: Wed, 21 May 2025 02:34:24 -0400 Subject: [PATCH 3/4] Replace `.into()` with more explicit `PathBuf::from()` --- src/path.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/path.rs b/src/path.rs index 10c460b1894e..618521b2279a 100644 --- a/src/path.rs +++ b/src/path.rs @@ -40,7 +40,7 @@ pub fn normalize(path: &Path) -> PathBuf { // - since `parent` is also a valid `OsStr`, trimming at its byte length must also be at a valid // boundary. // This is very similar the example given in `OsStr::from_encoded_bytes_unchecked`'s documentation. - res = unsafe { OsString::from_encoded_bytes_unchecked(bytes).into() }; + res = PathBuf::from(unsafe { OsString::from_encoded_bytes_unchecked(bytes) }); } } Component::Normal(p) => res.push(p), From 7ef4c31a5c31cd59efe7b12b8b0763b128a4016c Mon Sep 17 00:00:00 2001 From: Matthew Brown Date: Wed, 21 May 2025 02:42:09 -0400 Subject: [PATCH 4/4] Fix typo in comment --- src/path.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/path.rs b/src/path.rs index 618521b2279a..2de7d214b1af 100644 --- a/src/path.rs +++ b/src/path.rs @@ -39,7 +39,7 @@ pub fn normalize(path: &Path) -> PathBuf { // - the provided bytes came directly from a known-to-be-valid `OsStr`, `res`. // - since `parent` is also a valid `OsStr`, trimming at its byte length must also be at a valid // boundary. - // This is very similar the example given in `OsStr::from_encoded_bytes_unchecked`'s documentation. + // This is very similar to the example from `OsStr::from_encoded_bytes_unchecked`'s documentation. res = PathBuf::from(unsafe { OsString::from_encoded_bytes_unchecked(bytes) }); } }