use rustlite_core::error::{Error, Result};
#[inline]
pub fn validate_key(key: &[u8]) -> Result<()> {
const MAX_KEY_SIZE: usize = 16 * 1024 * 1024;
if key.is_empty() {
return Err(Error::InvalidInput("Key cannot be empty".to_string()));
}
if key.len() > MAX_KEY_SIZE {
return Err(Error::InvalidInput(format!(
"Key size {} exceeds maximum {}",
key.len(),
MAX_KEY_SIZE
)));
}
Ok(())
}
#[inline]
pub fn validate_value(value: &[u8]) -> Result<()> {
const MAX_VALUE_SIZE: usize = 1024 * 1024 * 1024;
if value.len() > MAX_VALUE_SIZE {
return Err(Error::InvalidInput(format!(
"Value size {} exceeds maximum {}",
value.len(),
MAX_VALUE_SIZE
)));
}
Ok(())
}
#[inline]
pub fn validate_query(query: &str) -> Result<()> {
const MAX_QUERY_LENGTH: usize = 1024 * 1024;
if query.is_empty() {
return Err(Error::InvalidInput("Query cannot be empty".to_string()));
}
if query.len() > MAX_QUERY_LENGTH {
return Err(Error::InvalidInput(format!(
"Query length {} exceeds maximum {}",
query.len(),
MAX_QUERY_LENGTH
)));
}
Ok(())
}
#[inline]
pub fn validate_index_name(name: &str) -> Result<()> {
const MAX_INDEX_NAME_LENGTH: usize = 256;
if name.is_empty() {
return Err(Error::InvalidInput(
"Index name cannot be empty".to_string(),
));
}
if name.len() > MAX_INDEX_NAME_LENGTH {
return Err(Error::InvalidInput(format!(
"Index name length {} exceeds maximum {}",
name.len(),
MAX_INDEX_NAME_LENGTH
)));
}
if name.contains('/') || name.contains('\\') || name.contains("..") {
return Err(Error::InvalidInput(
"Index name cannot contain path separators or '..'".to_string(),
));
}
if name.contains('\0') {
return Err(Error::InvalidInput(
"Index name cannot contain null bytes".to_string(),
));
}
Ok(())
}
#[allow(dead_code)]
#[inline]
pub fn validate_path(path: &str) -> Result<()> {
const MAX_PATH_LENGTH: usize = 4096;
if path.is_empty() {
return Err(Error::InvalidInput("Path cannot be empty".to_string()));
}
if path.len() > MAX_PATH_LENGTH {
return Err(Error::InvalidInput(format!(
"Path length {} exceeds maximum {}",
path.len(),
MAX_PATH_LENGTH
)));
}
if path.contains('\0') {
return Err(Error::InvalidInput(
"Path cannot contain null bytes".to_string(),
));
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_validate_key() {
assert!(validate_key(b"valid").is_ok());
assert!(validate_key(b"").is_err());
let large = vec![0u8; 17 * 1024 * 1024];
assert!(validate_key(&large).is_err());
}
#[test]
fn test_validate_value() {
assert!(validate_value(b"valid").is_ok());
assert!(validate_value(b"").is_ok()); }
#[test]
fn test_validate_query() {
assert!(validate_query("SELECT * FROM table").is_ok());
assert!(validate_query("").is_err());
let long = "a".repeat(2 * 1024 * 1024);
assert!(validate_query(&long).is_err());
}
#[test]
fn test_validate_index_name() {
assert!(validate_index_name("valid_name").is_ok());
assert!(validate_index_name("../etc/passwd").is_err());
assert!(validate_index_name("path/to/file").is_err());
}
}