refactor(bare): enhance security and performance optimizations

- Remove unnecessary sorting in advertise_refs for deterministic output
- Add path traversal detection and validation in bare_dir construction
- Implement symlink resolution checks to prevent security vulnerabilities
- Refactor cache system with CRC validation and improved metrics
- Integrate repo-specific cache invalidation using indexed keys
- Add comprehensive unit tests for commit operations and diff functionality
- Move configuration constants to centralized config module
- Optimize string operations in disk cache random value generation
- Enhance license detection algorithm with cleaner matching logic
- Streamline argument processing in various git operations
- Update dependencies including crc32fast and flate2 for performance
- Add signal handling capability to tokio runtime configuration
This commit is contained in:
zhenyi
2026-06-12 15:04:12 +08:00
parent e386f44ee2
commit 10a4398e81
41 changed files with 1373 additions and 365 deletions
+9 -12
View File
@@ -14,8 +14,7 @@ use sha2;
use crate::error::{GitError, GitResult};
/// Lease stale threshold: leases older than this are considered stale.
const LEASE_STALE_THRESHOLD_SECS: u64 = 30;
use crate::config::LEASE_STALE_THRESHOLD_SECS;
/// State directory relative path under repo prefix.
const STATE_DIR_RELATIVE: &str = "+gitks-cache/state";
@@ -27,10 +26,11 @@ const CACHE_DIR_RELATIVE: &str = "+gitks-cache/cache";
const INFO_REFS_DIR_RELATIVE: &str = "+gitks-cache/info_refs";
fn random_value() -> String {
use std::fmt::Write;
use std::sync::atomic::{AtomicU64, Ordering};
use std::time::{SystemTime, UNIX_EPOCH};
const HEX_CHARS: &[u8; 16] = b"0123456789abcdef";
let nanos = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
@@ -42,11 +42,13 @@ fn random_value() -> String {
buf[..8].copy_from_slice(&nanos.to_le_bytes());
buf[8..].copy_from_slice(&counter.to_le_bytes());
let mut s = String::with_capacity(32);
for byte in &buf {
let _ = write!(s, "{byte:02x}");
let mut hex = [0u8; 32];
for (i, &byte) in buf.iter().enumerate() {
hex[i * 2] = HEX_CHARS[(byte >> 4) as usize];
hex[i * 2 + 1] = HEX_CHARS[(byte & 0xf) as usize];
}
s
// SAFETY: hex chars are all valid ASCII (0-9, a-f)
unsafe { String::from_utf8_unchecked(hex.to_vec()) }
}
/// Compute SHA256 digest from multiple input parts.
@@ -137,7 +139,6 @@ impl DiskCache {
return Ok(val.trim().to_string());
}
// Atomic write: create temp file, then rename into place
let val = random_value();
let tmp_path = latest_path.with_extension("tmp");
std::fs::write(&tmp_path, &val).map_err(GitError::Io)?;
@@ -202,7 +203,6 @@ impl DiskCache {
let val = std::fs::read_to_string(&latest_path).map_err(GitError::Io)?;
Ok(Some(val.trim().to_string()))
} else {
// No latest file → create one
Ok(Some(self.ensure_state(relative_path)?))
}
}
@@ -252,7 +252,6 @@ impl DiskCache {
delta_base_offset: bool,
) -> GitResult<String> {
let latest = self.ensure_state(relative_path)?;
// Sort wants and haves for deterministic key
let mut wants_sorted = wants_hex.to_vec();
wants_sorted.sort();
let mut haves_sorted = haves_hex.to_vec();
@@ -468,7 +467,6 @@ impl DiskCache {
if !prefix_dir.is_dir() {
continue;
}
// Process all entries in this prefix directory
let entries = match std::fs::read_dir(&prefix_dir) {
Ok(iter) => iter,
Err(_) => continue,
@@ -498,7 +496,6 @@ impl DiskCache {
prefix_empty = false;
}
}
// Remove empty prefix directory
if prefix_empty {
std::fs::remove_dir(&prefix_dir).ok();
}