Fix edge cases and consistency issues

This commit is contained in:
2026-03-07 19:47:23 +02:00
parent 6bf9d60430
commit 9e1562c4c4
44 changed files with 5748 additions and 2221 deletions

View File

@@ -42,3 +42,84 @@ fn privacy_mode_strips_gps() {
strip_metadata(&input, &output, &MetadataConfig::Privacy).unwrap();
assert!(output.exists());
}
fn create_test_png(path: &Path) {
let img = image::RgbaImage::from_fn(100, 80, |x, y| {
image::Rgba([(x % 256) as u8, (y % 256) as u8, 128, 255])
});
img.save_with_format(path, image::ImageFormat::Png).unwrap();
}
#[test]
fn strip_png_metadata_produces_valid_png() {
let dir = tempfile::tempdir().unwrap();
let input = dir.path().join("test.png");
let output = dir.path().join("stripped.png");
create_test_png(&input);
strip_metadata(&input, &output, &MetadataConfig::StripAll).unwrap();
assert!(output.exists());
// Output must be a valid PNG that can be opened
let img = image::open(&output).unwrap();
assert_eq!(img.width(), 100);
assert_eq!(img.height(), 80);
}
#[test]
fn strip_png_removes_text_chunks() {
let dir = tempfile::tempdir().unwrap();
let input = dir.path().join("test.png");
let output = dir.path().join("stripped.png");
create_test_png(&input);
strip_metadata(&input, &output, &MetadataConfig::StripAll).unwrap();
// Read output and verify no tEXt chunks remain
let data = std::fs::read(&output).unwrap();
let mut pos = 8; // skip PNG signature
while pos + 12 <= data.len() {
let chunk_len = u32::from_be_bytes([data[pos], data[pos+1], data[pos+2], data[pos+3]]) as usize;
let chunk_type = &data[pos+4..pos+8];
assert_ne!(chunk_type, b"tEXt", "tEXt chunk should be stripped");
assert_ne!(chunk_type, b"iTXt", "iTXt chunk should be stripped");
assert_ne!(chunk_type, b"zTXt", "zTXt chunk should be stripped");
pos += 12 + chunk_len;
}
}
#[test]
fn strip_png_output_smaller_or_equal() {
let dir = tempfile::tempdir().unwrap();
let input = dir.path().join("test.png");
let output = dir.path().join("stripped.png");
create_test_png(&input);
let input_size = std::fs::metadata(&input).unwrap().len();
strip_metadata(&input, &output, &MetadataConfig::StripAll).unwrap();
let output_size = std::fs::metadata(&output).unwrap().len();
assert!(output_size <= input_size);
}
#[test]
fn strip_jpeg_removes_app1_exif() {
let dir = tempfile::tempdir().unwrap();
let input = dir.path().join("test.jpg");
let output = dir.path().join("stripped.jpg");
create_test_jpeg(&input);
strip_metadata(&input, &output, &MetadataConfig::StripAll).unwrap();
// Verify no APP1 (0xFFE1) markers remain
let data = std::fs::read(&output).unwrap();
let mut i = 2; // skip SOI
while i + 1 < data.len() {
if data[i] != 0xFF { break; }
let marker = data[i + 1];
if marker == 0xDA { break; } // SOS - rest is image data
assert_ne!(marker, 0xE1, "APP1/EXIF marker should be stripped");
if i + 3 < data.len() {
let len = ((data[i + 2] as usize) << 8) | (data[i + 3] as usize);
i += 2 + len;
} else {
break;
}
}
}