fix(clipboard): unix, keep Windows directories searchable (#16406)

A directory pasted from Windows with FILE_ATTRIBUTE_READONLY or
FILE_ATTRIBUTE_HIDDEN (Git for Windows hides `.git`) was given mode 0444 or
0400 in the FUSE list, because the read-only and hidden branches came before
the directory branch. Without `x` the directory cannot be entered once a
mode-preserving copy lands it on disk. Windows does not restrict access to a
directory for either attribute, so give every directory 0755, as a plain one
already gets.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Cheolhee Lee
2026-09-30 23:50:12 +08:00
committed by GitHub
co-authored by Claude Opus 5.5
parent 9d3ae7acd2
commit fada664df7
+28 -2
View File
@@ -140,12 +140,13 @@ impl FileDescription {
// cannot set as is...
} else if normal {
PERM_RWX
} else if directory {
// Windows ignores read-only and hidden on a directory; without `x` it cannot be entered.
PERM_RWX
} else if readonly {
PERM_READ
} else if hidden {
PERM_SELF_RO
} else if directory {
PERM_RWX
} else {
PERM_RW
};
@@ -327,6 +328,31 @@ mod tests {
));
}
fn parse_perm(attributes: u32) -> u16 {
let mut pdu = descriptor_pdu("folder");
pdu[ATTRIBUTES_OFFSET..ATTRIBUTES_OFFSET + size_of::<u32>()]
.copy_from_slice(&attributes.to_le_bytes());
FileDescription::parse_file_descriptors(pdu, 0).unwrap()[0].perm
}
#[test]
fn windows_directories_stay_searchable() {
const FILE_ATTRIBUTE_READONLY: u32 = 0x01;
const FILE_ATTRIBUTE_HIDDEN: u32 = 0x02;
const FILE_ATTRIBUTE_DIRECTORY: u32 = 0x10;
for attributes in [
FILE_ATTRIBUTE_DIRECTORY,
FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_READONLY,
FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_HIDDEN,
] {
assert_eq!(
parse_perm(attributes),
PERM_RWX,
"attributes {attributes:#x}"
);
}
}
fn parse_last_write_time(filetime: u64) -> SystemTime {
let mut pdu = descriptor_pdu("file.txt");
pdu[PDU_HEADER_SIZE..PDU_HEADER_SIZE + size_of::<u32>()]