|
1 | 1 | //! <https://infra.spec.whatwg.org/#forgiving-base64-decode>
|
2 | 2 |
|
3 | 3 | #[derive(Debug)]
|
4 |
| -pub struct InvalidBase64(()); |
| 4 | +pub struct InvalidBase64(InvalidBase64Details); |
| 5 | + |
| 6 | +#[derive(Debug)] |
| 7 | +enum InvalidBase64Details { |
| 8 | + UnexpectedSymbol(u8), |
| 9 | + AlphabetSymbolAfterPadding, |
| 10 | + LoneAlphabetSymbol, |
| 11 | + Padding, |
| 12 | +} |
5 | 13 |
|
6 | 14 | #[derive(Debug)]
|
7 | 15 | pub enum DecodeError<E> {
|
8 | 16 | InvalidBase64(InvalidBase64),
|
9 | 17 | WriteError(E),
|
10 | 18 | }
|
11 | 19 |
|
12 |
| -impl<E> From<InvalidBase64> for DecodeError<E> { |
13 |
| - fn from(e: InvalidBase64) -> Self { DecodeError::InvalidBase64(e) } |
| 20 | +impl<E> From<InvalidBase64Details> for DecodeError<E> { |
| 21 | + fn from(e: InvalidBase64Details) -> Self { |
| 22 | + DecodeError::InvalidBase64(InvalidBase64(e)) |
| 23 | + } |
14 | 24 | }
|
15 | 25 |
|
16 | 26 | pub(crate) enum Impossible {}
|
@@ -71,11 +81,10 @@ impl<F, E> Decoder<F, E> where F: FnMut(&[u8]) -> Result<(), E> {
|
71 | 81 | continue
|
72 | 82 | }
|
73 | 83 |
|
74 |
| - Err(InvalidBase64(()))? |
| 84 | + Err(InvalidBase64Details::UnexpectedSymbol(byte))? |
75 | 85 | }
|
76 | 86 | if self.padding_symbols > 0 {
|
77 |
| - // Alphabet symbols after padding |
78 |
| - Err(InvalidBase64(()))? |
| 87 | + Err(InvalidBase64Details::AlphabetSymbolAfterPadding)? |
79 | 88 | }
|
80 | 89 | self.bit_buffer <<= 6;
|
81 | 90 | self.bit_buffer |= value as u32;
|
@@ -120,9 +129,11 @@ impl<F, E> Decoder<F, E> where F: FnMut(&[u8]) -> Result<(), E> {
|
120 | 129 | ];
|
121 | 130 | (self.write_bytes)(&byte_buffer).map_err(DecodeError::WriteError)?;
|
122 | 131 | }
|
| 132 | + (6, _) => { |
| 133 | + Err(InvalidBase64Details::LoneAlphabetSymbol)? |
| 134 | + } |
123 | 135 | _ => {
|
124 |
| - // No other combination is acceptable |
125 |
| - Err(InvalidBase64(()))? |
| 136 | + Err(InvalidBase64Details::Padding)? |
126 | 137 | }
|
127 | 138 | }
|
128 | 139 | Ok(())
|
|
0 commit comments