ef0b83a
use crate::share::errors::GitError;
/// Maximum length of a lock path (git-lfs enforces a similar cap client-side).
pub const MAX_LOCK_PATH_LEN: usize = 1024;
/// Normalize a client-supplied oid into the canonical form used as the
/// storage key / DB value: lowercase `sha256:<64 hex>`.
///
/// Both the spec form (`sha256:<hex>`) and the bare 64-hex form accepted by
/// some servers/clients are accepted.
pub fn canonical_oid(raw: &str) -> Result<String, GitError> {
let raw = raw.trim();
let hex = match raw.strip_prefix("sha256:") {
Some(hex) => hex,
None if raw.len() == 64 => raw,
None => return Err(oid_error(raw)),
};
if hex.len() != 64 || !hex.bytes().all(|b| b.is_ascii_hexdigit()) {
return Err(oid_error(raw));
}
let mut out = String::with_capacity(70);
out.push_str("sha256:");
for c in hex.bytes() {
out.push(c.to_ascii_lowercase() as char);
}
Ok(out)
}
pub fn is_canonical_oid(oid: &str) -> bool {
oid.len() == 71 && oid.starts_with("sha256:") && oid[7..].bytes().all(|b| b.is_ascii_hexdigit())
}
/// Reject zero/negative sizes and anything above the configured cap.
pub fn validate_size(size: i64, cap_bytes: u64) -> Result<(), GitError> {
if size < 0 {
return Err(GitError::InvalidArgument(format!("invalid size {size}")));
}
let bytes = size as u64;
if bytes > cap_bytes {
return Err(GitError::InvalidArgument(format!(
"object size {bytes} exceeds limit {cap_bytes}"
)));
}
Ok(())
}
/// Locks paths must be non-empty, NUL-free and within a sane length.
pub fn validate_lock_path(path: &str) -> Result<&str, GitError> {
let path = path.trim();
if path.is_empty() {
return Err(GitError::InvalidArgument(
"lock path must not be empty".to_string(),
));
}
if path.len() > MAX_LOCK_PATH_LEN {
return Err(GitError::InvalidArgument(format!(
"lock path exceeds {MAX_LOCK_PATH_LEN} chars"
)));
}
if path.contains('\0') {
return Err(GitError::InvalidArgument(
"lock path contains NUL".to_string(),
));
}
Ok(path)
}
fn oid_error(raw: &str) -> GitError {
GitError::InvalidArgument(format!("invalid oid `{raw}` (expected sha256:<64 hex>)"))
}