From 1f4d0eafb5e5ec38a4e148271c2f37f52fb9a846 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E9=9B=85=20=C2=B7=20Misaki=20Masa?= Date: Wed, 22 Jan 2025 20:34:14 +0800 Subject: [PATCH] fix: unmangle the hexadecimal space strings (`"\x20"`) in Linux partition labels (#2233) --- Cargo.lock | 1 + yazi-fs/src/mounts/linux.rs | 13 ++++++++++--- yazi-shared/Cargo.toml | 1 + yazi-shared/src/chars.rs | 19 +++++++++++++++++++ 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1983e399..b5c61412 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3591,6 +3591,7 @@ dependencies = [ "crossterm", "futures", "libc", + "memchr", "parking_lot", "percent-encoding", "ratatui", diff --git a/yazi-fs/src/mounts/linux.rs b/yazi-fs/src/mounts/linux.rs index 0f305153..980a9e39 100644 --- a/yazi-fs/src/mounts/linux.rs +++ b/yazi-fs/src/mounts/linux.rs @@ -1,9 +1,9 @@ -use std::{borrow::Cow, collections::{HashMap, HashSet}, ffi::{OsStr, OsString}, os::{fd::AsFd, unix::{ffi::OsStrExt, fs::MetadataExt}}, time::Duration}; +use std::{borrow::Cow, collections::{HashMap, HashSet}, ffi::{OsStr, OsString}, os::{fd::AsFd, unix::{ffi::{OsStrExt, OsStringExt}, fs::MetadataExt}}, time::Duration}; use anyhow::Result; use tokio::{io::{Interest, unix::AsyncFd}, time::sleep}; use tracing::error; -use yazi_shared::replace_cow; +use yazi_shared::{replace_cow, replace_vec_cow}; use super::{Locked, Partition, Partitions}; @@ -129,7 +129,14 @@ impl Partitions { let mut map = HashMap::new(); for entry in std::fs::read_dir("/dev/disk/by-label")?.flatten() { let meta = std::fs::metadata(entry.path())?; - map.insert((meta.dev(), meta.ino()), entry.file_name()); + let name = entry.file_name(); + map.insert( + (meta.dev(), meta.ino()), + match replace_vec_cow(name.as_bytes(), br"\x20", b" ") { + Cow::Borrowed(_) => name, + Cow::Owned(v) => OsString::from_vec(v), + }, + ); } Ok(map) } diff --git a/yazi-shared/Cargo.toml b/yazi-shared/Cargo.toml index 56861c56..afff7566 100644 --- a/yazi-shared/Cargo.toml +++ b/yazi-shared/Cargo.toml @@ -16,6 +16,7 @@ yazi-macro = { path = "../yazi-macro", version = "0.4.3" } anyhow = { workspace = true } crossterm = { workspace = true } futures = { workspace = true } +memchr = "2.7.4" parking_lot = { workspace = true } percent-encoding = "2.3.1" ratatui = { workspace = true } diff --git a/yazi-shared/src/chars.rs b/yazi-shared/src/chars.rs index e234b03c..c76ce38f 100644 --- a/yazi-shared/src/chars.rs +++ b/yazi-shared/src/chars.rs @@ -64,6 +64,25 @@ fn replace_cow_impl<'s>( result + unsafe { src.get_unchecked(last..) } } +pub fn replace_vec_cow<'a>(v: &'a [u8], from: &[u8], to: &[u8]) -> Cow<'a, [u8]> { + let mut it = memchr::memmem::find_iter(v, from); + let Some(mut last) = it.next() else { return Cow::Borrowed(v) }; + + let mut out = Vec::with_capacity(v.len()); + out.extend_from_slice(&v[..last]); + out.extend_from_slice(to); + last += from.len(); + + for idx in it { + out.extend_from_slice(&v[last..idx]); + out.extend_from_slice(to); + last = idx + from.len(); + } + + out.extend_from_slice(&v[last..]); + Cow::Owned(out) +} + pub fn replace_to_printable(s: &[String], tab_size: u8) -> String { let mut buf = Vec::new(); buf.try_reserve_exact(s.iter().map(|s| s.len()).sum::() | 15).unwrap_or_else(|_| panic!());