use sanctum::sync::validate_node_name; #[test] fn test_validate_node_name_rejections() { // 1. Leere Namen assert!(validate_node_name("").is_err()); // 2. Relative Verzeichnisreferenzen assert!(validate_node_name(".").is_err()); assert!(validate_node_name("..").is_err()); // 3. Pfadtrenner assert!(validate_node_name("foo/bar").is_err()); assert!(validate_node_name("foo\\bar").is_err()); assert!(validate_node_name("../evil.exe").is_err()); assert!(validate_node_name("..\\evil.exe").is_err()); assert!(validate_node_name("/root_file").is_err()); // 4. Null-Bytes assert!(validate_node_name("test\0file.txt").is_err()); // 5. Steuerzeichen (< 0x20) assert!(validate_node_name("line\nbreak.txt").is_err()); assert!(validate_node_name("carriage\rreturn.txt").is_err()); assert!(validate_node_name("tab\tseparated.txt").is_err()); assert!(validate_node_name("control\x01char.txt").is_err()); // 6. Windows reservierte Gerätenamen let reserved_names = [ "CON", "con", "prn", "PRN", "aux", "AUX", "nul", "NUL", "COM1", "com2", "COM9", "lpt1", "LPT2", "LPT9", "con.txt", "aux.dat", "NUL.tar.gz", "com1.log", "prn.pdf", ]; for res in reserved_names { assert!( validate_node_name(res).is_err(), "Reservierter Name '{}' muss abgewiesen werden", res ); } } #[test] fn test_validate_node_name_accepted() { let valid_names = [ "document.pdf", "my_notes_2026.txt", "archive.tar.gz", "spaces are allowed.docx", "unicode_äöü_ß_test.rs", "hyphens-and_underscores.json", "file (1).jpg", "normal_file", ]; for valid in valid_names { assert!( validate_node_name(valid).is_ok(), "Gültiger Name '{}' sollte akzeptiert werden", valid ); } } #[test] fn test_storage_create_and_rename_reject_invalid_names() { let mut path = std::env::temp_dir(); path.push(format!( "sanctum_test_pathutil_{}.sanctum", std::process::id() )); if path.exists() { let _ = std::fs::remove_file(&path); } let salt = sanctum::crypto::generate_salt(); let kdf_params = sanctum::crypto::KdfParams { memory_cost: sanctum::crypto::MIN_MEMORY_COST_KIB, time_cost: sanctum::crypto::MIN_TIME_COST, parallelism: 1, }; let kek = sanctum::crypto::derive_kek("Pass1234!", &salt, &kdf_params).unwrap(); let dek = sanctum::crypto::generate_dek(); let (wrapped, nonce, tag) = sanctum::crypto::wrap_dek(&kek, &dek).unwrap(); let db = sanctum::storage::Database::open(&path).unwrap(); db.init_schema(&salt, &kdf_params, &wrapped, &nonce, &tag) .unwrap(); // create_node_in_vault mit ungültigem Namen muss scheitern assert!(db.create_node_in_vault(0, 1, "..", false, &dek).is_err()); assert!(db.create_node_in_vault(0, 1, "CON", false, &dek).is_err()); assert!(db .create_node_in_vault(0, 1, "sub/dir", false, &dek) .is_err()); // Gültige Datei erstellen let valid_node = db .create_node_in_vault(0, 1, "valid.txt", false, &dek) .unwrap(); // rename_node_in_vault mit ungültigem Namen muss scheitern assert!(db .rename_node_in_vault(valid_node.id, 1, "..", 0, &dek) .is_err()); assert!(db .rename_node_in_vault(valid_node.id, 1, "AUX", 0, &dek) .is_err()); assert!(db .rename_node_in_vault(valid_node.id, 1, "bad\\name", 0, &dek) .is_err()); let _ = std::fs::remove_file(&path); }