e478cc4
fn is_hex(b: u8) -> bool {
b.is_ascii_hexdigit()
}
pub fn validate_oid(s: &str, len: u64) -> Result<(), crate::Error> {
if s.len() as u64 != len || !s.bytes().all(is_hex) {
return Err(crate::Error::InvalidRevSpec(format!(
"invalid object id: expected {len} hex chars"
)));
}
Ok(())
}
pub fn validate_short_name(kind: &str, name: &str) -> Result<(), crate::Error> {
if name.is_empty() {
return Err(crate::Error::InvalidRefName(format!("empty {kind} name")));
}
if name.contains('/') || name.contains("..") || name.starts_with('/') {
return Err(crate::Error::InvalidRefName(format!(
"invalid {kind} name: {name}"
)));
}
if name.starts_with("refs/") {
return Err(crate::Error::InvalidRefName(format!(
"expected short {kind} name, got qualified: {name}"
)));
}
if name
.bytes()
.any(|b| b <= 0x20 || b == 0x7f || b == b'~' || b == b'^' || b == b':')
{
return Err(crate::Error::InvalidRefName(format!(
"invalid {kind} name: {name}"
)));
}
Ok(())
}
pub fn validate_qualified_ref(name: &str) -> Result<(), crate::Error> {
if !name.starts_with("refs/") {
return Err(crate::Error::InvalidRefName(format!(
"expected qualified ref, got: {name}"
)));
}
if name.contains("..") || name.contains("@{") || name.contains("//") {
return Err(crate::Error::InvalidRefName(format!(
"invalid ref name: {name}"
)));
}
Ok(())
}
/// Validate a remote URL scheme; returns the scheme if allowed.
pub fn allowed_remote_scheme(url: &str) -> Result<(), crate::Error> {
// are allowed for remote operations.
let scheme = url
.split_once("://")
.map(|(s, _)| s.to_ascii_lowercase())
.unwrap_or_default();
match scheme.as_str() {
"http" | "https" | "ssh" => Ok(()),
_ => Err(crate::Error::InvalidRevSpec(format!(
"remote url scheme not allowed: {url}"
))),
}
}
pub const MAX_OBJECT_SIZE: u64 = 100 * 1024 * 1024;
pub const MAX_BLOB_SIZE: u64 = 100 * 1024 * 1024;
pub fn enforce_max_size(data: &[u8], max: u64, what: &str) -> Result<(), crate::Error> {
if data.len() as u64 > max {
return Err(crate::Error::Other(format!(
"{what} exceeds maximum size of {max} bytes"
)));
}
Ok(())
}