use chrono::{DateTime, Utc};
use kcode_kweb_db::ObjectId;
use kcode_server_object_envelopes::{
StoredArtifact, StoredProvenance, decode_file, decode_provenance, encode_file,
encode_provenance, sanitize_file_name,
};
fn object_id(value: u8) -> ObjectId {
ObjectId::from_bytes([128, 1, 2, 3, 4, value]).unwrap()
}
#[test]
fn file_envelope_preserves_safe_metadata_and_exact_bytes() {
let encoded = encode_file(
"pending:9",
Some("../voice note.ogg"),
"audio/ogg",
Some("voice"),
b"OggS payload".to_vec(),
)
.unwrap();
let decoded = decode_file(object_id(5), encoded).unwrap();
assert_eq!(decoded.object_id, object_id(5));
assert_eq!(decoded.file_name, "voice note.ogg");
assert_eq!(decoded.media_type, "audio/ogg");
assert_eq!(decoded.transport_kind.as_deref(), Some("voice"));
assert_eq!(decoded.bytes, b"OggS payload");
assert!(decoded.enveloped);
}
#[test]
fn file_envelope_uses_bounded_fallbacks_and_rejects_trailing_bytes() {
let encoded = encode_file(
"pending:12",
Some("../\n"),
"not a media type",
Some("voice! note"),
vec![1, 2, 3],
)
.unwrap();
let decoded = decode_file(object_id(6), encoded.clone()).unwrap();
assert_eq!(decoded.file_name, "object-12.bin");
assert_eq!(decoded.media_type, "application/octet-stream");
assert_eq!(decoded.transport_kind.as_deref(), Some("voicenote"));
let mut with_trailing_byte = encoded;
with_trailing_byte.push(0);
assert!(decode_file(object_id(6), with_trailing_byte).is_err());
assert_eq!(
sanitize_file_name("folder/résumé.pdf", "object.bin"),
"résumé.pdf"
);
}
#[test]
fn unrestricted_logical_ids_produce_safe_decodable_fallbacks() {
let encoded = encode_file(
"../x",
None,
"application/octet-stream",
None,
vec![1, 2, 3],
)
.unwrap();
let decoded = decode_file(object_id(12), encoded).unwrap();
assert_eq!(decoded.file_name, "object-.._x.bin");
assert_eq!(decoded.bytes, [1, 2, 3]);
assert!(decoded.enveloped);
}
#[test]
fn every_encoded_file_decodes_with_hostile_empty_and_long_names() {
let hostile_id = format!("pending:{}", "/\\\"\r\n".repeat(500));
let very_long_id = format!("pending:{}", "x".repeat(10_000));
let very_long_name = format!("directory\\{}", "é".repeat(500));
let cases = [
("", None),
(hostile_id.as_str(), Some("../\\\n")),
(very_long_id.as_str(), None),
("pending:7", Some(very_long_name.as_str())),
];
for (logical_id, file_name) in cases {
let encoded = encode_file(
logical_id,
file_name,
"application/octet-stream",
Some("file"),
vec![0, 1, 2, 3],
)
.unwrap();
let decoded = decode_file(object_id(9), encoded).unwrap();
assert!(decoded.enveloped);
assert_eq!(decoded.bytes, [0, 1, 2, 3]);
assert!(!decoded.file_name.trim().is_empty());
assert!(decoded.file_name.len() <= 255);
assert!(
!decoded.file_name.chars().any(|character| {
character.is_control() || matches!(character, '/' | '\\' | '"')
})
);
}
assert_eq!(sanitize_file_name("", ""), "object.bin");
let sanitized_fallback = sanitize_file_name("", &format!("fallback\\{}", "é".repeat(500)));
assert!(!sanitized_fallback.is_empty());
assert!(sanitized_fallback.len() <= 255);
}
#[test]
fn filename_basenames_and_encoded_bytes_are_platform_independent() {
assert_eq!(
sanitize_file_name("/srv/files/report.pdf", "object.bin"),
"report.pdf"
);
assert_eq!(
sanitize_file_name(r"C:\files\report.pdf", "object.bin"),
"report.pdf"
);
let slash_encoded = encode_file(
"pending:10",
Some("/srv/files/report.pdf"),
"application/pdf",
None,
b"%PDF-content".to_vec(),
)
.unwrap();
let backslash_encoded = encode_file(
"pending:10",
Some(r"C:\files\report.pdf"),
"application/pdf",
None,
b"%PDF-content".to_vec(),
)
.unwrap();
assert_eq!(slash_encoded, backslash_encoded);
}
#[test]
fn dot_segment_filenames_are_normalized_and_rejected() {
assert_eq!(sanitize_file_name(".", "fallback.bin"), "fallback.bin");
assert_eq!(sanitize_file_name("..", "."), "object.bin");
for file_name in [".", ".."] {
let encoded = encode_file(
"pending:13",
Some(file_name),
"application/octet-stream",
None,
Vec::new(),
)
.unwrap();
let decoded = decode_file(object_id(13), encoded).unwrap();
assert_eq!(decoded.file_name, "object-13.bin");
let mut noncanonical = Vec::new();
noncanonical.extend_from_slice(b"KFILE001");
noncanonical.extend_from_slice(&u32::try_from(file_name.len()).unwrap().to_be_bytes());
noncanonical.extend_from_slice(&24u32.to_be_bytes());
noncanonical.extend_from_slice(&0u32.to_be_bytes());
noncanonical.extend_from_slice(&0u64.to_be_bytes());
noncanonical.extend_from_slice(file_name.as_bytes());
noncanonical.extend_from_slice(b"application/octet-stream");
assert!(decode_file(object_id(13), noncanonical).is_err());
}
}
#[test]
fn reserved_kfile_markers_are_never_treated_as_historical_raw_files() {
for payload in [
&b"KFILE"[..],
&b"KFILE0"[..],
&b"KFILE00"[..],
&b"KFILE001"[..],
&b"KFILE002payload"[..],
] {
assert!(decode_file(object_id(10), payload.to_vec()).is_err());
}
}
#[test]
fn historical_raw_files_remain_readable_without_becoming_enveloped() {
let decoded = decode_file(object_id(7), b"%PDF-original".to_vec()).unwrap();
assert_eq!(decoded.file_name, format!("{}.pdf", object_id(7)));
assert_eq!(decoded.media_type, "application/pdf");
assert_eq!(decoded.bytes, b"%PDF-original");
assert!(!decoded.enveloped);
}
#[test]
fn decoders_reject_impossible_declared_sizes() {
let mut oversized_filename = Vec::new();
oversized_filename.extend_from_slice(b"KFILE001");
oversized_filename.extend_from_slice(&u32::MAX.to_be_bytes());
oversized_filename.extend_from_slice(&0u32.to_be_bytes());
oversized_filename.extend_from_slice(&0u32.to_be_bytes());
oversized_filename.extend_from_slice(&0u64.to_be_bytes());
assert!(decode_file(object_id(11), oversized_filename).is_err());
let mut oversized_content = Vec::new();
oversized_content.extend_from_slice(b"KFILE001");
oversized_content.extend_from_slice(&1u32.to_be_bytes());
oversized_content.extend_from_slice(&3u32.to_be_bytes());
oversized_content.extend_from_slice(&0u32.to_be_bytes());
oversized_content.extend_from_slice(&u64::MAX.to_be_bytes());
oversized_content.extend_from_slice(b"a/b");
assert!(decode_file(object_id(11), oversized_content).is_err());
for (file_name_length, media_type_length, transport_kind_length, expected) in [
(256u32, 1u32, 0u32, "file object filename length"),
(1u32, 256u32, 0u32, "file object media type length"),
(1u32, 1u32, 65u32, "file object transport kind length"),
] {
let mut oversized_metadata = Vec::new();
oversized_metadata.extend_from_slice(b"KFILE001");
oversized_metadata.extend_from_slice(&file_name_length.to_be_bytes());
oversized_metadata.extend_from_slice(&media_type_length.to_be_bytes());
oversized_metadata.extend_from_slice(&transport_kind_length.to_be_bytes());
oversized_metadata.extend_from_slice(&0u64.to_be_bytes());
let error = decode_file(object_id(11), oversized_metadata).unwrap_err();
assert!(error.to_string().starts_with(expected));
}
let mut oversized_provenance_source = Vec::new();
oversized_provenance_source.extend_from_slice(b"KPROV\0\x01\0");
oversized_provenance_source.extend_from_slice(&0i64.to_be_bytes());
oversized_provenance_source.extend_from_slice(&0u32.to_be_bytes());
oversized_provenance_source.extend_from_slice(&u32::MAX.to_be_bytes());
assert!(decode_provenance(&oversized_provenance_source).is_err());
let mut oversized_artifact_count = Vec::new();
oversized_artifact_count.extend_from_slice(b"KPROV\0\x01\0");
oversized_artifact_count.extend_from_slice(&0i64.to_be_bytes());
oversized_artifact_count.extend_from_slice(&0u32.to_be_bytes());
oversized_artifact_count.extend_from_slice(&0u32.to_be_bytes());
oversized_artifact_count.extend_from_slice(&0u32.to_be_bytes());
oversized_artifact_count.extend_from_slice(&u64::MAX.to_be_bytes());
assert!(decode_provenance(&oversized_artifact_count).is_err());
}
#[test]
fn provenance_envelope_has_one_canonical_binary_round_trip() {
let value = StoredProvenance {
data: "complete source".into(),
source: "test".into(),
source_created_at: DateTime::parse_from_rfc3339("2026-07-23T00:00:00Z")
.unwrap()
.with_timezone(&Utc),
artifacts: vec![StoredArtifact {
object_id: object_id(8),
original_filename: "source.bin".into(),
media_type: "application/octet-stream".into(),
role: "media".into(),
byte_length: 3,
sha256: [42; 32],
}],
};
let first = encode_provenance(&value).unwrap();
assert!(first.starts_with(b"KPROV\0\x01\0"));
assert!(!first.starts_with(b"{"));
let decoded = decode_provenance(&first).unwrap();
let second = encode_provenance(&decoded).unwrap();
assert_eq!(first, second);
assert_eq!(decoded, value);
}
#[test]
fn provenance_decoder_rejects_unknown_truncated_and_extended_payloads() {
let value = StoredProvenance {
data: "data".into(),
source: "source".into(),
source_created_at: DateTime::parse_from_rfc3339("2026-07-23T00:00:00Z")
.unwrap()
.with_timezone(&Utc),
artifacts: Vec::new(),
};
let encoded = encode_provenance(&value).unwrap();
assert!(decode_provenance(b"unknown").is_err());
assert!(decode_provenance(&encoded[..encoded.len() - 1]).is_err());
let mut extended = encoded;
extended.push(0);
assert!(decode_provenance(&extended).is_err());
}