forgiving_base64.rs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. //! <https://infra.spec.whatwg.org/#forgiving-base64-decode>
  2. #[derive(Debug)]
  3. pub struct InvalidBase64(InvalidBase64Details);
  4. #[derive(Debug)]
  5. enum InvalidBase64Details {
  6. UnexpectedSymbol(u8),
  7. AlphabetSymbolAfterPadding,
  8. LoneAlphabetSymbol,
  9. Padding,
  10. }
  11. #[derive(Debug)]
  12. pub enum DecodeError<E> {
  13. InvalidBase64(InvalidBase64),
  14. WriteError(E),
  15. }
  16. impl<E> From<InvalidBase64Details> for DecodeError<E> {
  17. fn from(e: InvalidBase64Details) -> Self {
  18. DecodeError::InvalidBase64(InvalidBase64(e))
  19. }
  20. }
  21. pub(crate) enum Impossible {}
  22. impl From<DecodeError<Impossible>> for InvalidBase64 {
  23. fn from(e: DecodeError<Impossible>) -> Self {
  24. match e {
  25. DecodeError::InvalidBase64(e) => e,
  26. DecodeError::WriteError(e) => match e {},
  27. }
  28. }
  29. }
  30. /// `input` is assumed to be in an ASCII-compatible encoding
  31. pub fn decode_to_vec(input: &[u8]) -> Result<Vec<u8>, InvalidBase64> {
  32. let mut v = Vec::new();
  33. {
  34. let mut decoder = Decoder::new(|bytes| Ok(v.extend_from_slice(bytes)));
  35. decoder.feed(input)?;
  36. decoder.finish()?;
  37. }
  38. Ok(v)
  39. }
  40. /// <https://infra.spec.whatwg.org/#forgiving-base64-decode>
  41. pub struct Decoder<F, E>
  42. where
  43. F: FnMut(&[u8]) -> Result<(), E>,
  44. {
  45. write_bytes: F,
  46. bit_buffer: u32,
  47. buffer_bit_length: u8,
  48. padding_symbols: u8,
  49. }
  50. impl<F, E> Decoder<F, E>
  51. where
  52. F: FnMut(&[u8]) -> Result<(), E>,
  53. {
  54. pub fn new(write_bytes: F) -> Self {
  55. Self {
  56. write_bytes,
  57. bit_buffer: 0,
  58. buffer_bit_length: 0,
  59. padding_symbols: 0,
  60. }
  61. }
  62. /// Feed to the decoder partial input in an ASCII-compatible encoding
  63. pub fn feed(&mut self, input: &[u8]) -> Result<(), DecodeError<E>> {
  64. for &byte in input.iter() {
  65. let value = BASE64_DECODE_TABLE[byte as usize];
  66. if value < 0 {
  67. // A character that’s not part of the alphabet
  68. // Remove ASCII whitespace
  69. if matches!(byte, b' ' | b'\t' | b'\n' | b'\r' | b'\x0C') {
  70. continue;
  71. }
  72. if byte == b'=' {
  73. self.padding_symbols = self.padding_symbols.saturating_add(1);
  74. continue;
  75. }
  76. Err(InvalidBase64Details::UnexpectedSymbol(byte))?
  77. }
  78. if self.padding_symbols > 0 {
  79. Err(InvalidBase64Details::AlphabetSymbolAfterPadding)?
  80. }
  81. self.bit_buffer <<= 6;
  82. self.bit_buffer |= value as u32;
  83. // 18 before incrementing means we’ve just reached 24
  84. if self.buffer_bit_length < 18 {
  85. self.buffer_bit_length += 6;
  86. } else {
  87. // We’ve accumulated four times 6 bits, which equals three times 8 bits.
  88. let byte_buffer = [
  89. (self.bit_buffer >> 16) as u8,
  90. (self.bit_buffer >> 8) as u8,
  91. self.bit_buffer as u8,
  92. ];
  93. (self.write_bytes)(&byte_buffer).map_err(DecodeError::WriteError)?;
  94. self.buffer_bit_length = 0;
  95. // No need to reset bit_buffer,
  96. // since next time we’re only gonna read relevant bits.
  97. }
  98. }
  99. Ok(())
  100. }
  101. /// Call this to signal the end of the input
  102. pub fn finish(mut self) -> Result<(), DecodeError<E>> {
  103. match (self.buffer_bit_length, self.padding_symbols) {
  104. (0, 0) => {
  105. // A multiple of four of alphabet symbols, and nothing else.
  106. }
  107. (12, 2) | (12, 0) => {
  108. // A multiple of four of alphabet symbols, followed by two more symbols,
  109. // optionally followed by two padding characters (which make a total multiple of four).
  110. let byte_buffer = [(self.bit_buffer >> 4) as u8];
  111. (self.write_bytes)(&byte_buffer).map_err(DecodeError::WriteError)?;
  112. }
  113. (18, 1) | (18, 0) => {
  114. // A multiple of four of alphabet symbols, followed by three more symbols,
  115. // optionally followed by one padding character (which make a total multiple of four).
  116. let byte_buffer = [(self.bit_buffer >> 10) as u8, (self.bit_buffer >> 2) as u8];
  117. (self.write_bytes)(&byte_buffer).map_err(DecodeError::WriteError)?;
  118. }
  119. (6, _) => Err(InvalidBase64Details::LoneAlphabetSymbol)?,
  120. _ => Err(InvalidBase64Details::Padding)?,
  121. }
  122. Ok(())
  123. }
  124. }
  125. /// Generated by `make_base64_decode_table.py` based on "Table 1: The Base 64 Alphabet"
  126. /// at <https://tools.ietf.org/html/rfc4648#section-4>
  127. ///
  128. /// Array indices are the byte value of symbols.
  129. /// Array values are their positions in the base64 alphabet,
  130. /// or -1 for symbols not in the alphabet.
  131. /// The position contributes 6 bits to the decoded bytes.
  132. #[rustfmt::skip]
  133. const BASE64_DECODE_TABLE: [i8; 256] = [
  134. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  135. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  136. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
  137. 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
  138. -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
  139. 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
  140. -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
  141. 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
  142. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  143. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  144. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  145. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  146. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  147. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  148. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  149. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  150. ];