mirror of
https://github.com/xavo95/repak.git
synced 2025-01-18 19:04:07 +00:00
Fix empty intermediate directories being omitted from full directory index which can cause issues in some cases
This commit is contained in:
parent
dccdc13739
commit
c9abc25336
1 changed files with 45 additions and 13 deletions
|
@ -615,6 +615,19 @@ fn fnv64(data: &[u8], offset: u64) -> u64 {
|
||||||
hash
|
hash
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn split_path_child(path: &str) -> Option<(&str, &str)> {
|
||||||
|
if path == "/" || path.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
let path = path.strip_suffix('/').unwrap_or(path);
|
||||||
|
let i = path.rfind('/').map(|i| i + 1);
|
||||||
|
match i {
|
||||||
|
Some(i) => Some(path.split_at(i)),
|
||||||
|
None => Some(("/", path)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn generate_full_directory_index<W: Write>(
|
fn generate_full_directory_index<W: Write>(
|
||||||
writer: &mut W,
|
writer: &mut W,
|
||||||
entries: &BTreeMap<String, super::entry::Entry>,
|
entries: &BTreeMap<String, super::entry::Entry>,
|
||||||
|
@ -622,24 +635,21 @@ fn generate_full_directory_index<W: Write>(
|
||||||
) -> Result<(), super::Error> {
|
) -> Result<(), super::Error> {
|
||||||
let mut fdi = BTreeMap::new();
|
let mut fdi = BTreeMap::new();
|
||||||
for (path, offset) in entries.keys().zip(offsets) {
|
for (path, offset) in entries.keys().zip(offsets) {
|
||||||
let (directory, filename) = {
|
let mut p = path.as_str();
|
||||||
let i = path.rfind('/').map(|i| i + 1); // we want to include the slash on the directory
|
while let Some((parent, _)) = split_path_child(p) {
|
||||||
match i {
|
p = parent;
|
||||||
Some(i) => {
|
fdi.entry(p).or_default();
|
||||||
let (l, r) = path.split_at(i);
|
|
||||||
(l.to_owned(), r.to_owned())
|
|
||||||
}
|
}
|
||||||
None => ("/".to_owned(), path.to_owned()),
|
|
||||||
}
|
let (directory, filename) = split_path_child(path).expect("none root path");
|
||||||
};
|
|
||||||
|
|
||||||
fdi.entry(directory)
|
fdi.entry(directory)
|
||||||
.and_modify(|d: &mut BTreeMap<String, u32>| {
|
.and_modify(|d: &mut BTreeMap<&str, u32>| {
|
||||||
d.insert(filename.clone(), *offset);
|
d.insert(filename, *offset);
|
||||||
})
|
})
|
||||||
.or_insert_with(|| {
|
.or_insert_with(|| {
|
||||||
let mut files_and_offsets = BTreeMap::new();
|
let mut files_and_offsets = BTreeMap::new();
|
||||||
files_and_offsets.insert(filename.clone(), *offset);
|
files_and_offsets.insert(filename, *offset);
|
||||||
files_and_offsets
|
files_and_offsets
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -672,3 +682,25 @@ fn encrypt(key: aes::Aes256, bytes: &mut [u8]) {
|
||||||
key.encrypt_block(aes::Block::from_mut_slice(chunk))
|
key.encrypt_block(aes::Block::from_mut_slice(chunk))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_split_path_child() {
|
||||||
|
assert_eq!(
|
||||||
|
split_path_child("a/really/long/path"),
|
||||||
|
Some(("a/really/long/", "path"))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
split_path_child("a/really/long/"),
|
||||||
|
Some(("a/really/", "long"))
|
||||||
|
);
|
||||||
|
assert_eq!(split_path_child("a"), Some(("/", "a")));
|
||||||
|
assert_eq!(split_path_child("a//b"), Some(("a//", "b")));
|
||||||
|
assert_eq!(split_path_child("a//"), Some(("a/", "")));
|
||||||
|
assert_eq!(split_path_child("/"), None);
|
||||||
|
assert_eq!(split_path_child(""), None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue