R3.1: real paths without \?\ on Windows (dunce); old recent lists read plain

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-10-12 18:46:37 -04:00
1 parent 1066b41cb0
commit d0b5aede95
21 files changed
+59 -24

No files matched your search

+1
View File
@@ -7,6 +7,7 @@ license.workspace = true
publish.workspace = true
[dependencies]
dunce.workspace = true
ely-platform.workspace = true
log.workspace = true
aes-gcm.workspace = true
+20 -4
View File
@@ -10,12 +10,21 @@ const KEEP: usize = 20;
/// Recently opened paths, newest first.
pub fn recent(file: &Path) -> io::Result<Vec<PathBuf>> {
match std::fs::read(file) {
let listed: Vec<PathBuf> = match std::fs::read(file) {
Ok(bytes) => serde_json::from_slice(&bytes)
.map_err(|error| io::Error::other(format!("{}: {error}", file.display()))),
Err(error) if error.kind() == io::ErrorKind::NotFound => Ok(Vec::new()),
Err(error) => Err(error),
.map_err(|error| io::Error::other(format!("{}: {error}", file.display())))?,
Err(error) if error.kind() == io::ErrorKind::NotFound => return Ok(Vec::new()),
Err(error) => return Err(error),
};
// Older builds wrote `\\?\` paths.
let mut list = Vec::with_capacity(listed.len());
for path in listed {
let plain = dunce::simplified(&path).to_path_buf();
if !list.contains(&plain) {
list.push(plain);
}
}
Ok(list)
}
/// Takes `root` out of the list.
@@ -66,6 +75,13 @@ mod tests {
assert_eq!(list[..2], [PathBuf::from("/r/10"), PathBuf::from("/r/24")]);
forget(&file, Path::new("/r/10")).expect("forgets");
assert_eq!(recent(&file).expect("reads")[0], PathBuf::from("/r/24"));
#[cfg(windows)]
{
let old = [r"\\?\C:\r\old", r"C:\r\old", r"\\?\C:\r\new"];
std::fs::write(&file, serde_json::to_vec(&old).expect("json")).expect("writes");
let plain = [PathBuf::from(r"C:\r\old"), PathBuf::from(r"C:\r\new")];
assert_eq!(recent(&file).expect("reads"), plain);
}
std::fs::write(&file, "not json").expect("writes");
assert!(
remember(&file, Path::new("/r/1")).is_err(),
+2 -2
View File
@@ -183,7 +183,7 @@ pub fn export(
/// The canonical form of a possibly missing path.
fn resolved(path: &Path) -> io::Result<PathBuf> {
match std::fs::canonicalize(path) {
match dunce::canonicalize(path) {
Ok(real) => Ok(real),
Err(error) if error.kind() == io::ErrorKind::NotFound => {
let name = path.file_name().ok_or_else(|| {
@@ -192,7 +192,7 @@ fn resolved(path: &Path) -> io::Result<PathBuf> {
format!("{} has no file name", path.display()),
)
})?;
Ok(std::fs::canonicalize(parent_dir(path))?.join(name))
Ok(dunce::canonicalize(parent_dir(path))?.join(name))
}
Err(error) => Err(error),
}
+1 -1
View File
@@ -83,7 +83,7 @@ impl Sessions {
/// The key of an existing file; missing fails loud.
fn key(path: &Path) -> io::Result<Key> {
Ok(Key {
canonical: std::fs::canonicalize(path)?,
canonical: dunce::canonicalize(path)?,
id: file_id(path)?,
})
}
+1
View File
@@ -7,6 +7,7 @@ license.workspace = true
publish.workspace = true
[dependencies]
dunce.workspace = true
ely-ipc.workspace = true
base64.workspace = true
serde_json.workspace = true
+1 -1
View File
@@ -74,7 +74,7 @@ impl Lok {
/// dlopens the LOK library and hooks with the profile URL.
pub fn hook(install: &Path, profile_url: &str) -> io::Result<Self> {
let install = std::fs::canonicalize(install)?;
let install = dunce::canonicalize(install)?;
let install = install.as_path();
let install_str = install.to_string_lossy().into_owned();
let install_c = cstring(&install_str)?;
+1 -1
View File
@@ -53,7 +53,7 @@ impl Worker {
pub(crate) fn tile_self_check(&mut self, profile_dir: &Path) -> io::Result<bool> {
let doc = profile_dir.join("lok-verify.fodt");
std::fs::write(&doc, VERIFY_DOC)?;
let url = ipc::file_url_of(&doc.canonicalize()?);
let url = ipc::file_url_of(&dunce::canonicalize(&doc)?);
let payload = self.request(tag::VERIFY, &Pack::new().str(&url).bytes())?;
let red = Unpack::new(&payload).u64()?;
Ok(red > 0)
+1 -1
View File
@@ -36,7 +36,7 @@ pub fn run(
output: impl Write + Send + 'static,
) -> io::Result<()> {
set_output(Box::new(output));
let profile_dir = std::fs::canonicalize(profile_dir)?;
let profile_dir = dunce::canonicalize(profile_dir)?;
let profile_url = profile_url_of(&profile_dir);
let _ = teardown::PROFILE.set(profile_dir.clone());
let lok = Lok::hook(Path::new(install), &profile_url)?;
+1
View File
@@ -7,6 +7,7 @@ license.workspace = true
publish.workspace = true
[dependencies]
dunce.workspace = true
anyhow.workspace = true
directories.workspace = true
ely-files.workspace = true
+2 -2
View File
@@ -14,14 +14,14 @@ use crate::{After, Closing, Dialog, Engine, Host, Opening, Tab, Tabs, in_window,
/// The file a path names, links resolved.
fn identity(path: &Path) -> io::Result<PathBuf> {
match std::fs::canonicalize(path) {
match dunce::canonicalize(path) {
Ok(real) => Ok(real),
Err(error) if error.kind() == io::ErrorKind::NotFound => {
let parent = path.parent().unwrap_or(Path::new("."));
let name = path
.file_name()
.ok_or_else(|| io::Error::other("no file name"))?;
Ok(std::fs::canonicalize(parent)?.join(name))
Ok(dunce::canonicalize(parent)?.join(name))
}
Err(error) => Err(error),
}