RPM build fix (reverted CI changes which will need to be un-reverted or made conditional) and vendor Rust dependencies to make builds much faster in any CI system.
This commit is contained in:
330
zeroidc/vendor/base64/tests/decode.rs
vendored
Normal file
330
zeroidc/vendor/base64/tests/decode.rs
vendored
Normal file
@@ -0,0 +1,330 @@
|
||||
extern crate base64;
|
||||
|
||||
use base64::*;
|
||||
|
||||
mod helpers;
|
||||
|
||||
use self::helpers::*;
|
||||
|
||||
#[test]
|
||||
fn decode_rfc4648_0() {
|
||||
compare_decode("", "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_rfc4648_1() {
|
||||
compare_decode("f", "Zg==");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_rfc4648_1_just_a_bit_of_padding() {
|
||||
// allows less padding than required
|
||||
compare_decode("f", "Zg=");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_rfc4648_1_no_padding() {
|
||||
compare_decode("f", "Zg");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_rfc4648_2() {
|
||||
compare_decode("fo", "Zm8=");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_rfc4648_2_no_padding() {
|
||||
compare_decode("fo", "Zm8");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_rfc4648_3() {
|
||||
compare_decode("foo", "Zm9v");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_rfc4648_4() {
|
||||
compare_decode("foob", "Zm9vYg==");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_rfc4648_4_no_padding() {
|
||||
compare_decode("foob", "Zm9vYg");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_rfc4648_5() {
|
||||
compare_decode("fooba", "Zm9vYmE=");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_rfc4648_5_no_padding() {
|
||||
compare_decode("fooba", "Zm9vYmE");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_rfc4648_6() {
|
||||
compare_decode("foobar", "Zm9vYmFy");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_reject_null() {
|
||||
assert_eq!(
|
||||
DecodeError::InvalidByte(3, 0x0),
|
||||
decode_config("YWx\0pY2U==", config_std_pad()).unwrap_err()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_single_pad_byte_after_2_chars_in_trailing_quad_ok() {
|
||||
for num_quads in 0..25 {
|
||||
let mut s: String = std::iter::repeat("ABCD").take(num_quads).collect();
|
||||
s.push_str("Zg=");
|
||||
|
||||
let input_len = num_quads * 3 + 1;
|
||||
|
||||
// Since there are 3 bytes in the trailing quad, want to be sure this allows for the fact
|
||||
// that it could be bad padding rather than assuming that it will decode to 2 bytes and
|
||||
// therefore allow 1 extra round of fast decode logic (stage 1 / 2).
|
||||
|
||||
let mut decoded = Vec::new();
|
||||
decoded.resize(input_len, 0);
|
||||
|
||||
assert_eq!(
|
||||
input_len,
|
||||
decode_config_slice(&s, STANDARD, &mut decoded).unwrap()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//this is a MAY in the rfc: https://tools.ietf.org/html/rfc4648#section-3.3
|
||||
#[test]
|
||||
fn decode_1_pad_byte_in_fast_loop_then_extra_padding_chunk_error() {
|
||||
for num_quads in 0..25 {
|
||||
let mut s: String = std::iter::repeat("ABCD").take(num_quads).collect();
|
||||
s.push_str("YWxpY2U=====");
|
||||
|
||||
// since the first 8 bytes are handled in stage 1 or 2, the padding is detected as a
|
||||
// generic invalid byte, not specifcally a padding issue.
|
||||
// Could argue that the *next* padding byte (in the next quad) is technically the first
|
||||
// erroneous one, but reporting that accurately is more complex and probably nobody cares
|
||||
assert_eq!(
|
||||
DecodeError::InvalidByte(num_quads * 4 + 7, b'='),
|
||||
decode(&s).unwrap_err()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_2_pad_bytes_in_leftovers_then_extra_padding_chunk_error() {
|
||||
for num_quads in 0..25 {
|
||||
let mut s: String = std::iter::repeat("ABCD").take(num_quads).collect();
|
||||
s.push_str("YWxpY2UABB====");
|
||||
|
||||
// 6 bytes (4 padding) after last 8-byte chunk, so it's decoded by stage 4.
|
||||
// First padding byte is invalid.
|
||||
assert_eq!(
|
||||
DecodeError::InvalidByte(num_quads * 4 + 10, b'='),
|
||||
decode(&s).unwrap_err()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_valid_bytes_after_padding_in_leftovers_error() {
|
||||
for num_quads in 0..25 {
|
||||
let mut s: String = std::iter::repeat("ABCD").take(num_quads).collect();
|
||||
s.push_str("YWxpY2UABB=B");
|
||||
|
||||
// 4 bytes after last 8-byte chunk, so it's decoded by stage 4.
|
||||
// First (and only) padding byte is invalid.
|
||||
assert_eq!(
|
||||
DecodeError::InvalidByte(num_quads * 4 + 10, b'='),
|
||||
decode(&s).unwrap_err()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_absurd_pad_error() {
|
||||
for num_quads in 0..25 {
|
||||
let mut s: String = std::iter::repeat("ABCD").take(num_quads).collect();
|
||||
s.push_str("==Y=Wx===pY=2U=====");
|
||||
|
||||
// Plenty of remaining bytes, so handled by stage 1 or 2.
|
||||
// first padding byte
|
||||
assert_eq!(
|
||||
DecodeError::InvalidByte(num_quads * 4, b'='),
|
||||
decode(&s).unwrap_err()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_extra_padding_after_1_pad_bytes_in_trailing_quad_returns_error() {
|
||||
for num_quads in 0..25 {
|
||||
let mut s: String = std::iter::repeat("ABCD").take(num_quads).collect();
|
||||
s.push_str("EEE===");
|
||||
|
||||
// handled by stage 1, 2, or 4 depending on length
|
||||
// first padding byte -- which would be legal if it was the only padding
|
||||
assert_eq!(
|
||||
DecodeError::InvalidByte(num_quads * 4 + 3, b'='),
|
||||
decode(&s).unwrap_err()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_extra_padding_after_2_pad_bytes_in_trailing_quad_2_returns_error() {
|
||||
for num_quads in 0..25 {
|
||||
let mut s: String = std::iter::repeat("ABCD").take(num_quads).collect();
|
||||
s.push_str("EE====");
|
||||
|
||||
// handled by stage 1, 2, or 4 depending on length
|
||||
// first padding byte -- which would be legal if it was by itself
|
||||
assert_eq!(
|
||||
DecodeError::InvalidByte(num_quads * 4 + 2, b'='),
|
||||
decode(&s).unwrap_err()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_start_quad_with_padding_returns_error() {
|
||||
for num_quads in 0..25 {
|
||||
// add enough padding to ensure that we'll hit all 4 stages at the different lengths
|
||||
for pad_bytes in 1..32 {
|
||||
let mut s: String = std::iter::repeat("ABCD").take(num_quads).collect();
|
||||
let padding: String = std::iter::repeat("=").take(pad_bytes).collect();
|
||||
s.push_str(&padding);
|
||||
|
||||
if pad_bytes % 4 == 1 {
|
||||
// detected in early length check
|
||||
assert_eq!(DecodeError::InvalidLength, decode(&s).unwrap_err());
|
||||
} else {
|
||||
// padding lengths 2 - 8 are handled by stage 4
|
||||
// padding length >= 8 will hit at least one chunk at stages 1, 2, 3 at different
|
||||
// prefix lengths
|
||||
assert_eq!(
|
||||
DecodeError::InvalidByte(num_quads * 4, b'='),
|
||||
decode(&s).unwrap_err()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_padding_followed_by_non_padding_returns_error() {
|
||||
for num_quads in 0..25 {
|
||||
for pad_bytes in 0..31 {
|
||||
let mut s: String = std::iter::repeat("ABCD").take(num_quads).collect();
|
||||
let padding: String = std::iter::repeat("=").take(pad_bytes).collect();
|
||||
s.push_str(&padding);
|
||||
s.push_str("E");
|
||||
|
||||
if pad_bytes % 4 == 0 {
|
||||
assert_eq!(DecodeError::InvalidLength, decode(&s).unwrap_err());
|
||||
} else {
|
||||
// pad len 1 - 8 will be handled by stage 4
|
||||
// pad len 9 (suffix len 10) will have 8 bytes of padding handled by stage 3
|
||||
// first padding byte
|
||||
assert_eq!(
|
||||
DecodeError::InvalidByte(num_quads * 4, b'='),
|
||||
decode(&s).unwrap_err()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_one_char_in_quad_with_padding_error() {
|
||||
for num_quads in 0..25 {
|
||||
let mut s: String = std::iter::repeat("ABCD").take(num_quads).collect();
|
||||
s.push_str("E=");
|
||||
|
||||
assert_eq!(
|
||||
DecodeError::InvalidByte(num_quads * 4 + 1, b'='),
|
||||
decode(&s).unwrap_err()
|
||||
);
|
||||
|
||||
// more padding doesn't change the error
|
||||
s.push_str("=");
|
||||
assert_eq!(
|
||||
DecodeError::InvalidByte(num_quads * 4 + 1, b'='),
|
||||
decode(&s).unwrap_err()
|
||||
);
|
||||
|
||||
s.push_str("=");
|
||||
assert_eq!(
|
||||
DecodeError::InvalidByte(num_quads * 4 + 1, b'='),
|
||||
decode(&s).unwrap_err()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_one_char_in_quad_without_padding_error() {
|
||||
for num_quads in 0..25 {
|
||||
let mut s: String = std::iter::repeat("ABCD").take(num_quads).collect();
|
||||
s.push('E');
|
||||
|
||||
assert_eq!(DecodeError::InvalidLength, decode(&s).unwrap_err());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_reject_invalid_bytes_with_correct_error() {
|
||||
for length in 1..100 {
|
||||
for index in 0_usize..length {
|
||||
for invalid_byte in " \t\n\r\x0C\x0B\x00%*.".bytes() {
|
||||
let prefix: String = std::iter::repeat("A").take(index).collect();
|
||||
let suffix: String = std::iter::repeat("B").take(length - index - 1).collect();
|
||||
|
||||
let input = prefix + &String::from_utf8(vec![invalid_byte]).unwrap() + &suffix;
|
||||
assert_eq!(
|
||||
length,
|
||||
input.len(),
|
||||
"length {} error position {}",
|
||||
length,
|
||||
index
|
||||
);
|
||||
|
||||
if length % 4 == 1 && !suffix.is_empty() {
|
||||
assert_eq!(DecodeError::InvalidLength, decode(&input).unwrap_err());
|
||||
} else {
|
||||
assert_eq!(
|
||||
DecodeError::InvalidByte(index, invalid_byte),
|
||||
decode(&input).unwrap_err()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_imap() {
|
||||
assert_eq!(
|
||||
decode_config(b"+,,+", crate::IMAP_MUTF7),
|
||||
decode_config(b"+//+", crate::STANDARD_NO_PAD)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_invalid_trailing_bytes() {
|
||||
// The case of trailing newlines is common enough to warrant a test for a good error
|
||||
// message.
|
||||
assert_eq!(
|
||||
Err(DecodeError::InvalidByte(8, b'\n')),
|
||||
decode(b"Zm9vCg==\n")
|
||||
);
|
||||
// extra padding, however, is still InvalidLength
|
||||
assert_eq!(Err(DecodeError::InvalidLength), decode(b"Zm9vCg==="));
|
||||
}
|
||||
|
||||
fn config_std_pad() -> Config {
|
||||
Config::new(CharacterSet::Standard, true)
|
||||
}
|
||||
Reference in New Issue
Block a user