mirror of
https://git.proxmox.com/git/rustc
synced 2025-08-18 16:21:28 +00:00
153 lines
5.2 KiB
Rust
153 lines
5.2 KiB
Rust
//! Equivalence tests between `base64` crate and `base64ct`.
|
|
|
|
#![cfg(feature = "std")]
|
|
// TODO(tarcieri): fix `base64` crate deprecations
|
|
// warning: use of deprecated function `base64::encode`: Use Engine::encode
|
|
#![allow(deprecated)]
|
|
|
|
use base64ct::{Base64 as Base64ct, Encoding};
|
|
use proptest::{prelude::*, string::*};
|
|
use std::iter;
|
|
|
|
/// Incremental Base64 decoder.
|
|
type Decoder<'a> = base64ct::Decoder<'a, Base64ct>;
|
|
|
|
/// Incremental Base64 encoder.
|
|
type Encoder<'a> = base64ct::Encoder<'a, Base64ct>;
|
|
|
|
proptest! {
|
|
/// Ensure `base64ct` decodes data encoded by `base64` ref crate
|
|
#[test]
|
|
fn decode_equiv(bytes in bytes_regex(".{0,256}").unwrap()) {
|
|
let encoded = base64::encode(&bytes);
|
|
let decoded = Base64ct::decode_vec(&encoded);
|
|
prop_assert_eq!(Ok(bytes), decoded);
|
|
}
|
|
|
|
/// Ensure that `base64ct`'s incremental decoder is able to decode randomly
|
|
/// generated inputs encoded by the `base64` ref crate
|
|
#[test]
|
|
fn decode_incremental(bytes in bytes_regex(".{1,256}").unwrap(), chunk_size in 1..256usize) {
|
|
let encoded = base64::encode(&bytes);
|
|
let chunk_size = match chunk_size % bytes.len() {
|
|
0 => 1,
|
|
n => n
|
|
};
|
|
|
|
let mut buffer = [0u8; 384];
|
|
let mut decoder = Decoder::new(encoded.as_bytes()).unwrap();
|
|
let mut remaining_len = decoder.remaining_len();
|
|
|
|
for chunk in bytes.chunks(chunk_size) {
|
|
prop_assert!(!decoder.is_finished());
|
|
|
|
let decoded = decoder.decode(&mut buffer[..chunk.len()]);
|
|
prop_assert_eq!(Ok(chunk), decoded);
|
|
|
|
remaining_len -= decoded.unwrap().len();
|
|
prop_assert_eq!(remaining_len, decoder.remaining_len());
|
|
}
|
|
|
|
prop_assert!(decoder.is_finished());
|
|
prop_assert_eq!(decoder.remaining_len(), 0);
|
|
}
|
|
|
|
#[test]
|
|
fn decode_incremental_wrapped(
|
|
bytes in bytes_regex(".{1,256}").unwrap(),
|
|
line_width in 4..128usize,
|
|
chunk_size in 1..256usize
|
|
) {
|
|
for line_ending in ["\r", "\n", "\r\n"] {
|
|
let encoded = base64::encode(&bytes);
|
|
|
|
let mut encoded_wrapped = Vec::new();
|
|
let mut lines = encoded.as_bytes().chunks_exact(line_width);
|
|
|
|
for line in &mut lines {
|
|
encoded_wrapped.extend_from_slice(line);
|
|
encoded_wrapped.extend_from_slice(line_ending.as_bytes());
|
|
}
|
|
|
|
let last = lines.remainder();
|
|
|
|
if last.is_empty() {
|
|
encoded_wrapped.truncate(encoded_wrapped.len() - line_ending.len());
|
|
} else {
|
|
encoded_wrapped.extend_from_slice(last);
|
|
}
|
|
|
|
let chunk_size = match chunk_size % bytes.len() {
|
|
0 => 1,
|
|
n => n
|
|
};
|
|
|
|
let mut buffer = [0u8; 384];
|
|
let mut decoder = Decoder::new_wrapped(&encoded_wrapped, line_width).unwrap();
|
|
let mut remaining_len = decoder.remaining_len();
|
|
|
|
for chunk in bytes.chunks(chunk_size) {
|
|
prop_assert!(!decoder.is_finished());
|
|
|
|
let decoded = decoder.decode(&mut buffer[..chunk.len()]);
|
|
prop_assert_eq!(Ok(chunk), decoded);
|
|
|
|
remaining_len -= decoded.unwrap().len();
|
|
prop_assert_eq!(remaining_len, decoder.remaining_len());
|
|
}
|
|
|
|
prop_assert!(decoder.is_finished());
|
|
prop_assert_eq!(decoder.remaining_len(), 0);
|
|
}
|
|
}
|
|
|
|
/// Ensure `base64ct` and `base64` ref crate decode randomly generated
|
|
/// inputs equivalently.
|
|
///
|
|
/// Inputs are selected to be valid characters in the standard Base64
|
|
/// padded alphabet, but are not necessarily valid Base64.
|
|
#[test]
|
|
fn decode_random(base64ish in string_regex("[A-Za-z0-9+/]{0,256}").unwrap()) {
|
|
let base64ish_padded = match base64ish.len() % 4 {
|
|
0 => base64ish,
|
|
n => {
|
|
let padding_len = 4 - n;
|
|
base64ish + &iter::repeat("=").take(padding_len).collect::<String>()
|
|
}
|
|
};
|
|
|
|
let decoded_ct = Base64ct::decode_vec(&base64ish_padded).ok();
|
|
let decoded_ref = base64::decode(&base64ish_padded).ok();
|
|
prop_assert_eq!(decoded_ct, decoded_ref);
|
|
}
|
|
|
|
/// Ensure `base64ct` and the `base64` ref crate encode randomly generated
|
|
/// inputs equivalently.
|
|
#[test]
|
|
fn encode_equiv(bytes in bytes_regex(".{0,256}").unwrap()) {
|
|
let encoded_ct = Base64ct::encode_string(&bytes);
|
|
let encoded_ref = base64::encode(&bytes);
|
|
prop_assert_eq!(encoded_ct, encoded_ref);
|
|
}
|
|
|
|
/// Ensure that `base64ct`'s incremental encoder is able to encode randomly
|
|
/// generated inputs which match what's encoded by the `base64` ref crate
|
|
#[test]
|
|
fn encode_incremental(bytes in bytes_regex(".{1,256}").unwrap(), chunk_size in 1..256usize) {
|
|
let expected = base64::encode(&bytes);
|
|
let chunk_size = match chunk_size % bytes.len() {
|
|
0 => 1,
|
|
n => n
|
|
};
|
|
|
|
let mut buffer = [0u8; 1024];
|
|
let mut encoder = Encoder::new(&mut buffer).unwrap();
|
|
|
|
for chunk in bytes.chunks(chunk_size) {
|
|
encoder.encode(chunk).unwrap();
|
|
}
|
|
|
|
prop_assert_eq!(expected, encoder.finish().unwrap());
|
|
}
|
|
}
|