fix: harden path lookup and mark gl backend gap

This commit is contained in:
2026-06-22 16:12:57 +04:00
parent 5436727961
commit f69c893a40
7 changed files with 209 additions and 47 deletions
+26 -1
View File
@@ -110,7 +110,7 @@ impl std::error::Error for PathError {}
/// Returns [`PathError`] when the input is empty, absolute, contains an
/// embedded NUL, attempts parent traversal, or is not valid UTF-8 after
/// legacy separator normalization.
pub fn normalize_relative(raw: &[u8], _policy: PathPolicy) -> Result<NormalizedPath, PathError> {
pub fn normalize_relative(raw: &[u8], policy: PathPolicy) -> Result<NormalizedPath, PathError> {
if raw.is_empty() {
return Err(PathError::Empty);
}
@@ -124,11 +124,17 @@ pub fn normalize_relative(raw: &[u8], _policy: PathPolicy) -> Result<NormalizedP
let mut parts = Vec::new();
for part in text.split(['/', '\\']) {
if part.is_empty() || part == "." {
if policy == PathPolicy::StrictLegacy {
return Err(PathError::ParentTraversal);
}
continue;
}
if part == ".." {
return Err(PathError::ParentTraversal);
}
if policy == PathPolicy::StrictLegacy && part.contains(':') {
return Err(PathError::Absolute);
}
parts.push(part);
}
if parts.is_empty() {
@@ -223,6 +229,25 @@ mod tests {
);
}
#[test]
fn strict_legacy_rejects_host_only_segments() {
assert_eq!(
normalize_relative(b"./DATA/MAPS", PathPolicy::StrictLegacy),
Err(PathError::ParentTraversal)
);
assert_eq!(
normalize_relative(b"DATA//MAPS", PathPolicy::StrictLegacy),
Err(PathError::ParentTraversal)
);
assert_eq!(
normalize_relative(b"DATA/stream:name", PathPolicy::StrictLegacy),
Err(PathError::Absolute)
);
let host = normalize_relative(b"./DATA//MAPS", PathPolicy::HostCompatible).expect("host");
assert_eq!(host.as_str(), "DATA/MAPS");
}
#[test]
fn join_under_keeps_normalized_path_below_root() {
let rel = normalize_relative(b"DATA/MAPS/Land.map", PathPolicy::StrictLegacy)