use super::*;
use std::sync::Mutex;
fn compress(compressor: &mut flate2::Compress, data: &[u8]) -> Vec<u8> {
let mut output = Vec::with_capacity(1024);
compressor
.compress_vec(data, &mut output, flate2::FlushCompress::Sync)
.unwrap();
let mut packet = (output.len() as u32).to_be_bytes().to_vec();
packet.extend(output);
packet
}
#[tokio::test]
async fn malformed_palette_index_and_runs_return_errors() {
for data in [
vec![3, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xc0],
vec![128, 1, 2, 3, 1],
vec![130, 1, 2, 3, 4, 5, 6, 128, 1],
vec![130, 1, 2, 3, 4, 5, 6, 2],
vec![129, 1, 2, 3],
vec![0, 1],
] {
let mut compressor = flate2::Compress::new(flate2::Compression::fast(), true);
let packet = compress(&mut compressor, &data);
let mut input = packet.as_slice();
let result = Decoder::new()
.decode(
&PixelFormat::rgba(),
&Rect {
x: 0,
y: 0,
width: 1,
height: 1,
},
&mut input,
&|_| async { Ok(()) },
)
.await;
assert!(result.is_err(), "malformed input accepted: {data:?}");
}
}
#[tokio::test]
async fn valid_modes_and_persistent_compression_preserve_pixels() {
let mut compressor = flate2::Compress::new(flate2::Compression::fast(), true);
let mut decoder = Decoder::new();
for (data, expected) in [
(vec![0, 1, 2, 3, 4, 5, 6], vec![1, 2, 3, 255, 4, 5, 6, 255]),
(vec![1, 1, 2, 3], vec![1, 2, 3, 255, 1, 2, 3, 255]),
(
vec![2, 1, 2, 3, 4, 5, 6, 0x40],
vec![1, 2, 3, 255, 4, 5, 6, 255],
),
(vec![128, 1, 2, 3, 1], vec![1, 2, 3, 255, 1, 2, 3, 255]),
(
vec![130, 1, 2, 3, 4, 5, 6, 128, 1],
vec![1, 2, 3, 255, 1, 2, 3, 255],
),
] {
let packet = compress(&mut compressor, &data);
let mut input = packet.as_slice();
let output = Mutex::new(Vec::new());
decoder
.decode(
&PixelFormat::rgba(),
&Rect {
x: 0,
y: 0,
width: 2,
height: 1,
},
&mut input,
&|event| {
output.lock().unwrap().push(event);
async { Ok(()) }
},
)
.await
.unwrap();
let VncEvent::RawImage(_, pixels) = output.into_inner().unwrap().remove(0) else {
panic!("expected pixels");
};
assert_eq!(pixels, expected);
}
}