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:
+182
-5
@@ -1,6 +1,5 @@
|
||||
use gitks::sanitize::*;
|
||||
|
||||
// ==================== validate_ref_name tests ====================
|
||||
|
||||
#[test]
|
||||
fn test_validate_ref_name_accepts_valid_names() {
|
||||
@@ -69,7 +68,6 @@ fn test_validate_ref_name_rejects_too_long() {
|
||||
assert!(validate_ref_name(&max_valid_name).is_ok());
|
||||
}
|
||||
|
||||
// ==================== validate_revision tests ====================
|
||||
|
||||
#[test]
|
||||
fn test_validate_revision_accepts_empty() {
|
||||
@@ -149,7 +147,6 @@ fn test_validate_revision_accepts_valid_branch_names() {
|
||||
assert!(validate_revision("v1.0.0").is_ok());
|
||||
}
|
||||
|
||||
// ==================== validate_file_path tests ====================
|
||||
|
||||
#[test]
|
||||
fn test_validate_file_path_accepts_valid_paths() {
|
||||
@@ -216,7 +213,6 @@ fn test_validate_file_path_rejects_windows_reserved_names() {
|
||||
assert!(validate_file_path("CON.txt").is_err());
|
||||
}
|
||||
|
||||
// ==================== validate_relative_path tests ====================
|
||||
|
||||
#[test]
|
||||
fn test_validate_relative_path_accepts_valid_paths() {
|
||||
@@ -244,7 +240,6 @@ fn test_validate_relative_path_rejects_traversal() {
|
||||
assert!(validate_relative_path("path/..").is_err());
|
||||
}
|
||||
|
||||
// ==================== validate_config_key tests ====================
|
||||
|
||||
#[test]
|
||||
fn test_validate_config_key_accepts_safe_keys() {
|
||||
@@ -281,3 +276,185 @@ fn test_validate_config_key_rejects_invalid_chars() {
|
||||
assert!(validate_config_key("key$(command)").is_err());
|
||||
assert!(validate_config_key("key`command`").is_err());
|
||||
}
|
||||
|
||||
|
||||
/// Ensure no input causes panic in validate_ref_name.
|
||||
#[test]
|
||||
fn fuzz_validate_ref_name_no_panic() {
|
||||
let long_name = "x".repeat(300);
|
||||
let test_inputs: Vec<&str> = vec![
|
||||
"",
|
||||
"\0",
|
||||
"\0\0\0",
|
||||
"\x7f",
|
||||
"\x01\x02\x03",
|
||||
"~^:?*[]\\ ",
|
||||
"../../../etc/passwd",
|
||||
"a/b/c/d/e/f/g/h",
|
||||
&long_name,
|
||||
"branch@{upstream}",
|
||||
"HEAD~99999999999",
|
||||
"HEAD^99999999999",
|
||||
"ref:HEAD",
|
||||
"ref:refs/heads/main",
|
||||
"; rm -rf /",
|
||||
"$(echo pwned)",
|
||||
"`echo pwned`",
|
||||
"\n\r\t",
|
||||
];
|
||||
for input in test_inputs {
|
||||
let _ = validate_ref_name(input);
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensure no input causes panic in validate_revision.
|
||||
#[test]
|
||||
fn fuzz_validate_revision_no_panic() {
|
||||
let test_inputs: Vec<&str> = vec![
|
||||
"",
|
||||
"HEAD",
|
||||
"HEAD~0",
|
||||
"HEAD~99999999",
|
||||
"HEAD^0",
|
||||
"HEAD^99999999",
|
||||
"HEAD^{tree}",
|
||||
"HEAD^{commit}",
|
||||
"HEAD^{object}",
|
||||
"abcdef01",
|
||||
"abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789",
|
||||
"0000",
|
||||
"zzzz",
|
||||
"ref:HEAD",
|
||||
"ref:refs/heads/main",
|
||||
"\0",
|
||||
"branch~abc",
|
||||
"branch^abc",
|
||||
"branch~",
|
||||
"branch^",
|
||||
"a~10001",
|
||||
"a^10001",
|
||||
];
|
||||
for input in test_inputs {
|
||||
let _ = validate_revision(input);
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensure no input causes panic in validate_file_path.
|
||||
#[test]
|
||||
fn fuzz_validate_file_path_no_panic() {
|
||||
let long_path = "x".repeat(5000);
|
||||
let medium_path = "a".repeat(100);
|
||||
let test_inputs: Vec<&str> = vec![
|
||||
"",
|
||||
"/etc/passwd",
|
||||
"../escape",
|
||||
"a/../b",
|
||||
".git",
|
||||
".git/config",
|
||||
"src/.git/HEAD",
|
||||
"a/b/.git",
|
||||
"\0",
|
||||
"\0\0\0",
|
||||
&long_path,
|
||||
"path/with\x00null",
|
||||
"path/with\nnewline",
|
||||
"normal/path.txt",
|
||||
&medium_path,
|
||||
];
|
||||
for input in test_inputs {
|
||||
let _ = validate_file_path(input);
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensure no input causes panic in validate_remote_url.
|
||||
#[test]
|
||||
fn fuzz_validate_remote_url_no_panic() {
|
||||
let long_url = "x".repeat(5000);
|
||||
let test_inputs: Vec<&str> = vec![
|
||||
"",
|
||||
"https://github.com/user/repo",
|
||||
"http://localhost:3000/repo",
|
||||
"ssh://git@host/repo",
|
||||
"git://host/repo",
|
||||
"git+ssh://git@host/repo",
|
||||
"file:///etc/passwd",
|
||||
"ext::sh -c 'rm -rf /'",
|
||||
"ftp://host/repo",
|
||||
"https://user:pass@host/repo",
|
||||
"\0",
|
||||
"https://host\0injection",
|
||||
&long_url,
|
||||
];
|
||||
for input in test_inputs {
|
||||
let _ = validate_remote_url(input);
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensure no input causes panic in validate_oid_hex.
|
||||
#[test]
|
||||
fn fuzz_validate_oid_hex_no_panic() {
|
||||
let long_hex = "x".repeat(65);
|
||||
let exact_hex = "x".repeat(64);
|
||||
let test_inputs: Vec<&str> = vec![
|
||||
"",
|
||||
"abc",
|
||||
"abcd",
|
||||
"0123456789abcdef",
|
||||
"ZZZZ",
|
||||
"g000",
|
||||
"0000000000000000000000000000000000000000",
|
||||
&long_hex,
|
||||
&exact_hex,
|
||||
"\0",
|
||||
" ",
|
||||
"\n",
|
||||
];
|
||||
for input in test_inputs {
|
||||
let _ = validate_oid_hex(input);
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensure no input causes panic in validate_relative_path.
|
||||
#[test]
|
||||
fn fuzz_validate_relative_path_no_panic() {
|
||||
let long_path = "x".repeat(5000);
|
||||
let test_inputs: Vec<&str> = vec![
|
||||
"",
|
||||
"/absolute",
|
||||
"relative/path",
|
||||
"../escape",
|
||||
"path/../escape",
|
||||
"\0",
|
||||
&long_path,
|
||||
".",
|
||||
"..",
|
||||
"...",
|
||||
"a/b/c",
|
||||
];
|
||||
for input in test_inputs {
|
||||
let _ = validate_relative_path(input);
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensure no input causes panic in validate_refspec.
|
||||
#[test]
|
||||
fn fuzz_validate_refspec_no_panic() {
|
||||
let long_refspec = "x".repeat(2000);
|
||||
let test_inputs: Vec<&str> = vec![
|
||||
"",
|
||||
"+refs/heads/*:refs/heads/*",
|
||||
"refs/heads/main",
|
||||
"; rm -rf /",
|
||||
"$(evil)",
|
||||
"`evil`",
|
||||
"| pipe",
|
||||
"& bg",
|
||||
"< redirect",
|
||||
"> redirect",
|
||||
"\0",
|
||||
&long_refspec,
|
||||
];
|
||||
for input in test_inputs {
|
||||
let _ = validate_refspec(input);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user