pub(crate) const NAMESPACE_PREFIXES: &[&str] = &[
"home", "tmp", "dev", "sys", "etc", "lib", "boot", "usr", "var",
];
#[cfg(test)]
pub(crate) fn canonicalize_path(p: &str) -> String {
let stripped = p.trim_start_matches('/');
let first = stripped.split('/').next().unwrap_or("");
if NAMESPACE_PREFIXES.contains(&first) || first == "proc" {
stripped.to_owned()
} else {
format!("home/{stripped}")
}
}
#[cfg(test)]
pub(crate) fn valid_world_name(world_name: &str) -> bool {
validate_world_name(world_name).is_ok()
}
pub(crate) fn validate_world_name(world_name: &str) -> Result<(), &'static str> {
if world_name.is_empty() {
return Err("world path is empty");
}
if is_reserved_world_name(world_name) {
return Err("world path is a reserved namespace root");
}
if world_name.contains('\\') {
return Err("world path contains backslash");
}
if world_name.chars().any(char::is_control) {
return Err("world path contains control bytes");
}
for segment in world_name.split('/') {
if segment.is_empty() {
return Err("world path has empty segment");
}
if is_dot_segment(segment) {
return Err("world path contains dot or encoded-dot segment");
}
}
Ok(())
}
fn is_dot_segment(segment: &str) -> bool {
let Some(rest) = strip_dot_token(segment) else {
return false;
};
rest.is_empty()
|| strip_dot_token(rest)
.map(|tail| tail.is_empty())
.unwrap_or(false)
}
fn strip_dot_token(segment: &str) -> Option<&str> {
if let Some(rest) = segment.strip_prefix('.') {
return Some(rest);
}
if segment
.as_bytes()
.get(..3)
.is_some_and(|prefix| prefix.eq_ignore_ascii_case(b"%2e"))
{
return Some(&segment[3..]);
}
None
}
fn is_reserved_world_name(world_name: &str) -> bool {
NAMESPACE_PREFIXES.contains(&world_name)
|| matches!(world_name, "proc" | "var/log")
|| world_name.starts_with("proc/")
}