-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Panic when deleting file with a non-UTF-8 name on a Mac #124
Comments
Thanks a lot pointing this out! It should definitely not be needed to do that, and I'd hope that a fix can be contributed. |
Upd: think it's just a matter of escaping binary chars to match the url format spec Do you know much about NSStrings and → NSURLs that is fed into the file manager's I've tried to fix it, but think there is no FileManager API that can delete an arbitrary bag of bytes that OsString can represent, it only accepts ~dozen encodings. The rust's non-encoding-aware deprecated stringWithCString api doesn't produce the needed NSString, but AnyObject (also tried with other 3 brew Swift (uses FileManager) /objc/py cli trash tools, and they also bug with non-utf8, though doesn't neccessarily mean there is no way) At the very least we could check (in Rust) whether the passed path is utf-8 and report and error if it's not instead of crashing, but it's a surprising limitation |
I see, so applying a URL encoding to the bytes would do the trick? I wouldn't be surprised if NSURL is what's passed to the file-manager. |
It should, but the problem is I can't find an objc API for such a basic thing:
I've even found another objc crate that has a method to get NSString from OsStr, but that one also failed with invalid utf8 src (yes, FM gets NSURL Lines 80 to 84 in 1a0fc59
) |
@madsmtm you're the resident Objc guru that added objc2 crate. Would you please suggest how to do this simple thing:
|
Haven't researched closely yet, but what about |
Where you'd get the pointer with |
That was the first one I've tried, also thought that the FS repr would mean raw bytes, but I get a panic
snippet I used for testing let in_oss = OsStr::from_bytes(b"/Volumes/Untitled/\xf8");
let bpath = in_oss.as_bytes();
let cstring = CString::new(bpath).expect("CString::new failed to create from given path");
let cstring_len = cstring.count_bytes();
println!("cstring: {:?}={cstring_len}",cstring);
let nncstring = NonNull::new(cstring.into_raw()).expect("REASON");
println!("nncstring: {:?}",nncstring);
let string:Retained<NSString> = unsafe {file_mgr.stringWithFileSystemRepresentation_length(nncstring, cstring_len)}; this works with utf-8 |
No I mean |
Sorry about the confusion, too many tests :) // URL from CString via fileURLWithFileSystemRepresentation_isDirectory_relativeToURL
// FAILS with binary path
let path_b:&[u8] = b"/Volumes/Untitled/\xf8";
let path_os:&OsStr = OsStr::from_bytes(&path_b);
let path_b:&[u8] = path_os.as_bytes();
// OK with valid utf8 manual %-encoding
let path_os:&OsStr = OsStr::new("/Volumes/Untitled/%F8");
let path_b:&[u8] = path_os.as_bytes();
// OK (different valid utf-8 string)
let path_os:&OsStr = OsStr::new("/Volumes/Untitled/ピ");
let path_b:&[u8] = path_os.as_bytes();
// same in all cases
let mut p:PathBuf = PathBuf::new(); p.push(path_os); let path_p = p;
if path_p.is_file() {println!("path_os is a file! {:?}",path_os);}
let cstring = CString::new(path_b).expect("CString::new failed to create from given path");
let cstring_len = cstring.count_bytes();
println!("pre={:?}\nc{}={:?}",&path_os,cstring_len,&cstring);
let nncstring = NonNull::new(cstring.into_raw()).expect("REASON");
let is_dir = false;
let url_s = unsafe{NSURL::fileURLWithFileSystemRepresentation_isDirectory_relativeToURL(nncstring,is_dir,None)};
// println!("fileURLWithFileSystemRepresentation_isDirectory_relativeToURL\n{url:?}",);
let res_s = unsafe{file_mgr.trashItemAtURL_resultingItemURL_error(&url_s, None) };//
let err_s = match res_s {Ok(())=>format!("ok"), Err(err)=>format!("{err}"),};
println!("fileURLWithFileSystemRepresentation_isDirectory_relativeToURL:\nurl_s={url_s:?}\n\nres_s={err_s}"); I've meanwhile adapted the std's |
…non-binary strings Issue: Byron#124
…non-binary strings Issue: Byron#124
…non-binary strings Issue: Byron#124
Because it converts all paths to strings for some reason during the "canonicalization" step
trash-rs/src/macos.rs
Line 65 in 1a0fc59
The text was updated successfully, but these errors were encountered: