diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:47:55 +0000 |
commit | 2aadc03ef15cb5ca5cc2af8a7c08e070742f0ac4 (patch) | |
tree | 033cc839730fda84ff08db877037977be94e5e3a /vendor/base64/tests/tests.rs | |
parent | Initial commit. (diff) | |
download | cargo-upstream.tar.xz cargo-upstream.zip |
Adding upstream version 0.70.1+ds1.upstream/0.70.1+ds1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | vendor/base64/tests/tests.rs | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/vendor/base64/tests/tests.rs b/vendor/base64/tests/tests.rs new file mode 100644 index 0000000..11fed96 --- /dev/null +++ b/vendor/base64/tests/tests.rs @@ -0,0 +1,194 @@ +extern crate base64; +extern crate rand; + +use rand::{FromEntropy, Rng}; + +use base64::*; + +mod helpers; +use self::helpers::*; + +// generate random contents of the specified length and test encode/decode roundtrip +fn roundtrip_random( + byte_buf: &mut Vec<u8>, + str_buf: &mut String, + config: Config, + byte_len: usize, + approx_values_per_byte: u8, + max_rounds: u64, +) { + // let the short ones be short but don't let it get too crazy large + let num_rounds = calculate_number_of_rounds(byte_len, approx_values_per_byte, max_rounds); + let mut r = rand::rngs::SmallRng::from_entropy(); + let mut decode_buf = Vec::new(); + + for _ in 0..num_rounds { + byte_buf.clear(); + str_buf.clear(); + decode_buf.clear(); + while byte_buf.len() < byte_len { + byte_buf.push(r.gen::<u8>()); + } + + encode_config_buf(&byte_buf, config, str_buf); + decode_config_buf(&str_buf, config, &mut decode_buf).unwrap(); + + assert_eq!(byte_buf, &decode_buf); + } +} + +fn calculate_number_of_rounds(byte_len: usize, approx_values_per_byte: u8, max: u64) -> u64 { + // don't overflow + let mut prod = approx_values_per_byte as u64; + + for _ in 0..byte_len { + if prod > max { + return max; + } + + prod = prod.saturating_mul(prod); + } + + prod +} + +fn no_pad_config() -> Config { + Config::new(CharacterSet::Standard, false) +} + +#[test] +fn roundtrip_random_short_standard() { + let mut byte_buf: Vec<u8> = Vec::new(); + let mut str_buf = String::new(); + + for input_len in 0..40 { + roundtrip_random(&mut byte_buf, &mut str_buf, STANDARD, input_len, 4, 10000); + } +} + +#[test] +fn roundtrip_random_with_fast_loop_standard() { + let mut byte_buf: Vec<u8> = Vec::new(); + let mut str_buf = String::new(); + + for input_len in 40..100 { + roundtrip_random(&mut byte_buf, &mut str_buf, STANDARD, input_len, 4, 1000); + } +} + +#[test] +fn roundtrip_random_short_no_padding() { + let mut byte_buf: Vec<u8> = Vec::new(); + let mut str_buf = String::new(); + + for input_len in 0..40 { + roundtrip_random( + &mut byte_buf, + &mut str_buf, + no_pad_config(), + input_len, + 4, + 10000, + ); + } +} + +#[test] +fn roundtrip_random_no_padding() { + let mut byte_buf: Vec<u8> = Vec::new(); + let mut str_buf = String::new(); + + for input_len in 40..100 { + roundtrip_random( + &mut byte_buf, + &mut str_buf, + no_pad_config(), + input_len, + 4, + 1000, + ); + } +} + +#[test] +fn roundtrip_decode_trailing_10_bytes() { + // This is a special case because we decode 8 byte blocks of input at a time as much as we can, + // ideally unrolled to 32 bytes at a time, in stages 1 and 2. Since we also write a u64's worth + // of bytes (8) to the output, we always write 2 garbage bytes that then will be overwritten by + // the NEXT block. However, if the next block only contains 2 bytes, it will decode to 1 byte, + // and therefore be too short to cover up the trailing 2 garbage bytes. Thus, we have stage 3 + // to handle that case. + + for num_quads in 0..25 { + let mut s: String = std::iter::repeat("ABCD").take(num_quads).collect(); + s.push_str("EFGHIJKLZg"); + + let decoded = decode(&s).unwrap(); + assert_eq!(num_quads * 3 + 7, decoded.len()); + + assert_eq!(s, encode_config(&decoded, STANDARD_NO_PAD)); + } +} + +#[test] +fn display_wrapper_matches_normal_encode() { + let mut bytes = Vec::<u8>::with_capacity(256); + + for i in 0..255 { + bytes.push(i); + } + bytes.push(255); + + assert_eq!( + encode(&bytes), + format!( + "{}", + base64::display::Base64Display::with_config(&bytes, STANDARD) + ) + ); +} + +#[test] +fn because_we_can() { + compare_decode("alice", "YWxpY2U="); + compare_decode("alice", &encode(b"alice")); + compare_decode("alice", &encode(&decode(&encode(b"alice")).unwrap())); +} + +#[test] +fn encode_config_slice_can_use_inline_buffer() { + let mut buf: [u8; 22] = [0; 22]; + let mut larger_buf: [u8; 24] = [0; 24]; + let mut input: [u8; 16] = [0; 16]; + + let mut rng = rand::rngs::SmallRng::from_entropy(); + for elt in &mut input { + *elt = rng.gen(); + } + + assert_eq!(22, encode_config_slice(&input, STANDARD_NO_PAD, &mut buf)); + let decoded = decode_config(&buf, STANDARD_NO_PAD).unwrap(); + + assert_eq!(decoded, input); + + // let's try it again with padding + + assert_eq!(24, encode_config_slice(&input, STANDARD, &mut larger_buf)); + let decoded = decode_config(&buf, STANDARD).unwrap(); + + assert_eq!(decoded, input); +} + +#[test] +#[should_panic(expected = "index 24 out of range for slice of length 22")] +fn encode_config_slice_panics_when_buffer_too_small() { + let mut buf: [u8; 22] = [0; 22]; + let mut input: [u8; 16] = [0; 16]; + + let mut rng = rand::rngs::SmallRng::from_entropy(); + for elt in &mut input { + *elt = rng.gen(); + } + + encode_config_slice(&input, STANDARD, &mut buf); +} |