1use std::borrow::Cow;
8
9use crate::parsers::MessageStream;
10
11#[inline(always)]
12pub fn base64_decode(bytes: &[u8]) -> Option<Vec<u8>> {
13 base64_decode_stream(bytes.iter(), bytes.len(), u8::MAX)
14}
15
16pub fn base64_decode_stream<'x>(
17 stream: impl Iterator<Item = &'x u8>,
18 stream_len: usize,
19 stop_char: u8,
20) -> Option<Vec<u8>> {
21 let mut chunk: u32 = 0;
22 let mut byte_count: u8 = 0;
23
24 let mut buf = Vec::with_capacity(stream_len / 4 * 3);
25
26 for &ch in stream {
27 let val = BASE64_MAP[byte_count as usize][ch as usize];
28
29 if val < 0x01ffffff {
30 byte_count = (byte_count + 1) & 3;
31
32 if byte_count == 1 {
33 chunk = val;
34 } else {
35 chunk |= val;
36
37 if byte_count == 0 {
38 buf.extend_from_slice(&chunk.to_le_bytes()[0..3]);
39 }
40 }
41 } else {
42 match ch {
43 b'=' => match byte_count {
44 1 | 2 => {
45 buf.push(chunk.to_le_bytes()[0]);
46 byte_count = 0;
47 }
48 3 => {
49 buf.extend_from_slice(&chunk.to_le_bytes()[0..2]);
50 byte_count = 0;
51 }
52 0 => (),
53 _ => {
54 return None;
55 }
56 },
57 b' ' | b'\t' | b'\r' | b'\n' => (),
58 _ => return if ch == stop_char { buf.into() } else { None },
59 }
60 }
61 }
62
63 buf.into()
64}
65
66impl<'x> MessageStream<'x> {
67 pub fn decode_base64_mime(&mut self, boundary: &[u8]) -> (usize, Cow<'x, [u8]>) {
68 let mut chunk: u32 = 0;
69 let mut byte_count: u8 = 0;
70
71 let mut buf = Vec::with_capacity(self.remaining() / 4 * 3);
72 let mut last_ch = b'\n';
73 let mut before_last_ch = 0;
74 let mut end_pos = self.offset();
75
76 self.checkpoint();
77
78 while let Some(&ch) = self.next() {
79 let val = BASE64_MAP[byte_count as usize][ch as usize];
80
81 if val < 0x01ffffff {
82 byte_count = (byte_count + 1) & 3;
83
84 if byte_count == 1 {
85 chunk = val;
86 } else {
87 chunk |= val;
88
89 if byte_count == 0 {
90 buf.extend_from_slice(&chunk.to_le_bytes()[0..3]);
91 }
92 }
93 } else {
94 match ch {
95 b'=' => match byte_count {
96 1 | 2 => {
97 buf.push(chunk.to_le_bytes()[0]);
98 byte_count = 0;
99 }
100 3 => {
101 buf.extend_from_slice(&chunk.to_le_bytes()[0..2]);
102 byte_count = 0;
103 }
104 0 => (),
105 _ => {
106 self.restore();
107 return (usize::MAX, b""[..].into());
108 }
109 },
110 b'\n' => {
111 end_pos = if last_ch == b'\r' {
112 self.offset() - 2
113 } else {
114 self.offset() - 1
115 }
116 }
117 b' ' | b'\t' | b'\r' => (),
118 b'-' => {
119 if last_ch == b'-' {
120 return if !boundary.is_empty() && self.try_skip(boundary) {
121 buf.shrink_to_fit();
122 (
123 if before_last_ch == b'\n' {
124 end_pos
125 } else {
126 self.offset() - boundary.len() - 2
127 },
128 buf.into(),
129 )
130 } else {
131 self.restore();
132 (usize::MAX, b""[..].into())
133 };
134 }
135 }
136 _ => {
137 self.restore();
138 return (usize::MAX, b""[..].into());
139 }
140 }
141 }
142
143 before_last_ch = last_ch;
144 last_ch = ch;
145 }
146
147 buf.shrink_to_fit();
148 (
149 if boundary.is_empty() {
150 self.offset()
151 } else {
152 self.restore();
153 usize::MAX
154 },
155 buf.into(),
156 )
157 }
158
159 pub fn decode_base64_word(&mut self) -> Option<Vec<u8>> {
160 let mut chunk: u32 = 0;
161 let mut byte_count: u8 = 0;
162 let mut buf = Vec::with_capacity(64);
163
164 while let Some(&ch) = self.next() {
165 match ch {
166 b'=' => {
167 match byte_count {
168 1 | 2 => {
169 buf.push(chunk.to_le_bytes()[0]);
170 byte_count = 0;
171 }
172 3 => {
173 buf.extend_from_slice(&chunk.to_le_bytes()[0..2]);
174 byte_count = 0;
175 }
176 0 => (),
177 _ => {
178 break;
180 }
181 }
182 }
183 b'?' => {
184 if let Some(b'=') = self.next() {
185 return Some(buf);
186 } else {
187 break;
188 }
189 }
190 b'\n' => {
191 if !self.next_is_space() {
192 break;
193 }
194 }
195 b' ' | b'\t' | b'\r' => (),
196 _ => {
197 let val = BASE64_MAP[byte_count as usize][ch as usize];
198
199 if val < 0x01ffffff {
200 byte_count = (byte_count + 1) & 3;
201
202 if byte_count == 1 {
203 chunk = val;
204 } else {
205 chunk |= val;
206
207 if byte_count == 0 {
208 buf.extend_from_slice(&chunk.to_le_bytes()[0..3]);
209 }
210 }
211 } else {
212 break;
213 }
214 }
215 }
216 }
217
218 None
219 }
220}
221
222pub static BASE64_MAP: &[&[u32]] = &[
235 &[
236 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
237 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
238 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
239 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
240 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
241 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
242 0x01ffffff, 0x000000f8, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x000000fc, 0x000000d0,
243 0x000000d4, 0x000000d8, 0x000000dc, 0x000000e0, 0x000000e4, 0x000000e8, 0x000000ec,
244 0x000000f0, 0x000000f4, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
245 0x01ffffff, 0x01ffffff, 0x00000000, 0x00000004, 0x00000008, 0x0000000c, 0x00000010,
246 0x00000014, 0x00000018, 0x0000001c, 0x00000020, 0x00000024, 0x00000028, 0x0000002c,
247 0x00000030, 0x00000034, 0x00000038, 0x0000003c, 0x00000040, 0x00000044, 0x00000048,
248 0x0000004c, 0x00000050, 0x00000054, 0x00000058, 0x0000005c, 0x00000060, 0x00000064,
249 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000068,
250 0x0000006c, 0x00000070, 0x00000074, 0x00000078, 0x0000007c, 0x00000080, 0x00000084,
251 0x00000088, 0x0000008c, 0x00000090, 0x00000094, 0x00000098, 0x0000009c, 0x000000a0,
252 0x000000a4, 0x000000a8, 0x000000ac, 0x000000b0, 0x000000b4, 0x000000b8, 0x000000bc,
253 0x000000c0, 0x000000c4, 0x000000c8, 0x000000cc, 0x01ffffff, 0x01ffffff, 0x01ffffff,
254 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
255 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
256 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
257 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
258 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
259 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
260 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
261 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
262 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
263 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
264 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
265 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
266 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
267 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
268 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
269 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
270 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
271 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
272 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
273 ],
274 &[
275 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
276 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
277 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
278 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
279 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
280 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
281 0x01ffffff, 0x0000e003, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000f003, 0x00004003,
282 0x00005003, 0x00006003, 0x00007003, 0x00008003, 0x00009003, 0x0000a003, 0x0000b003,
283 0x0000c003, 0x0000d003, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
284 0x01ffffff, 0x01ffffff, 0x00000000, 0x00001000, 0x00002000, 0x00003000, 0x00004000,
285 0x00005000, 0x00006000, 0x00007000, 0x00008000, 0x00009000, 0x0000a000, 0x0000b000,
286 0x0000c000, 0x0000d000, 0x0000e000, 0x0000f000, 0x00000001, 0x00001001, 0x00002001,
287 0x00003001, 0x00004001, 0x00005001, 0x00006001, 0x00007001, 0x00008001, 0x00009001,
288 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000a001,
289 0x0000b001, 0x0000c001, 0x0000d001, 0x0000e001, 0x0000f001, 0x00000002, 0x00001002,
290 0x00002002, 0x00003002, 0x00004002, 0x00005002, 0x00006002, 0x00007002, 0x00008002,
291 0x00009002, 0x0000a002, 0x0000b002, 0x0000c002, 0x0000d002, 0x0000e002, 0x0000f002,
292 0x00000003, 0x00001003, 0x00002003, 0x00003003, 0x01ffffff, 0x01ffffff, 0x01ffffff,
293 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
294 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
295 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
296 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
297 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
298 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
299 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
300 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
301 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
302 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
303 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
304 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
305 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
306 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
307 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
308 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
309 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
310 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
311 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
312 ],
313 &[
314 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
315 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
316 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
317 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
318 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
319 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
320 0x01ffffff, 0x00800f00, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00c00f00, 0x00000d00,
321 0x00400d00, 0x00800d00, 0x00c00d00, 0x00000e00, 0x00400e00, 0x00800e00, 0x00c00e00,
322 0x00000f00, 0x00400f00, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
323 0x01ffffff, 0x01ffffff, 0x00000000, 0x00400000, 0x00800000, 0x00c00000, 0x00000100,
324 0x00400100, 0x00800100, 0x00c00100, 0x00000200, 0x00400200, 0x00800200, 0x00c00200,
325 0x00000300, 0x00400300, 0x00800300, 0x00c00300, 0x00000400, 0x00400400, 0x00800400,
326 0x00c00400, 0x00000500, 0x00400500, 0x00800500, 0x00c00500, 0x00000600, 0x00400600,
327 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00800600,
328 0x00c00600, 0x00000700, 0x00400700, 0x00800700, 0x00c00700, 0x00000800, 0x00400800,
329 0x00800800, 0x00c00800, 0x00000900, 0x00400900, 0x00800900, 0x00c00900, 0x00000a00,
330 0x00400a00, 0x00800a00, 0x00c00a00, 0x00000b00, 0x00400b00, 0x00800b00, 0x00c00b00,
331 0x00000c00, 0x00400c00, 0x00800c00, 0x00c00c00, 0x01ffffff, 0x01ffffff, 0x01ffffff,
332 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
333 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
334 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
335 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
336 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
337 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
338 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
339 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
340 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
341 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
342 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
343 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
344 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
345 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
346 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
347 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
348 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
349 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
350 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
351 ],
352 &[
353 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
354 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
355 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
356 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
357 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
358 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
359 0x01ffffff, 0x003e0000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x003f0000, 0x00340000,
360 0x00350000, 0x00360000, 0x00370000, 0x00380000, 0x00390000, 0x003a0000, 0x003b0000,
361 0x003c0000, 0x003d0000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
362 0x01ffffff, 0x01ffffff, 0x00000000, 0x00010000, 0x00020000, 0x00030000, 0x00040000,
363 0x00050000, 0x00060000, 0x00070000, 0x00080000, 0x00090000, 0x000a0000, 0x000b0000,
364 0x000c0000, 0x000d0000, 0x000e0000, 0x000f0000, 0x00100000, 0x00110000, 0x00120000,
365 0x00130000, 0x00140000, 0x00150000, 0x00160000, 0x00170000, 0x00180000, 0x00190000,
366 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x001a0000,
367 0x001b0000, 0x001c0000, 0x001d0000, 0x001e0000, 0x001f0000, 0x00200000, 0x00210000,
368 0x00220000, 0x00230000, 0x00240000, 0x00250000, 0x00260000, 0x00270000, 0x00280000,
369 0x00290000, 0x002a0000, 0x002b0000, 0x002c0000, 0x002d0000, 0x002e0000, 0x002f0000,
370 0x00300000, 0x00310000, 0x00320000, 0x00330000, 0x01ffffff, 0x01ffffff, 0x01ffffff,
371 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
372 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
373 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
374 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
375 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
376 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
377 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
378 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
379 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
380 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
381 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
382 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
383 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
384 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
385 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
386 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
387 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
388 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
389 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
390 ],
391];
392
393#[cfg(test)]
394mod tests {
395 use crate::parsers::MessageStream;
396
397 #[test]
398 fn decode_base64() {
399 for (encoded_str, expected_result) in [
400 ("VGVzdA==", "Test"),
401 ("WWU=", "Ye"),
402 ("QQ==", "A"),
403 ("cm8=", "ro"),
404 (
405 "QXJlIHlvdSBhIFNoaW1hbm8gb3IgQ2FtcGFnbm9sbyBwZXJzb24/",
406 "Are you a Shimano or Campagnolo person?",
407 ),
408 (
409 "PCFET0NUWVBFIGh0bWw+CjxodG1sPgo8Ym9keT4KPC9ib2R5Pgo8L2h0bWw+Cg==",
410 "<!DOCTYPE html>\n<html>\n<body>\n</body>\n</html>\n",
411 ),
412 (
413 "PCFET0NUWVBFIGh0bWw+CjxodG1sPg\no8Ym9ke\nT4KPC 9ib2R5Pg\n o8L2h0bWw+Cg==",
414 "<!DOCTYPE html>\n<html>\n<body>\n</body>\n</html>\n",
415 ),
416 ("w6HDqcOtw7PDug==", "áéíóú"),
417 ("====", ""),
418 ("w6HDq!cOtw7PDug=", ""),
419 ("w6 HD qcOt", "áéí"),
420 ("cmáé", ""),
421 ("áé", ""),
422 ("w\n6\nH\nD\nq\nc\nO\nt\nw\n7\n P\tD u g\n==", "áéíóú"),
423 ("w6HDqcOtw7PDug==", "áéíóú"),
424 ] {
425 assert_eq!(
426 super::base64_decode(encoded_str.as_bytes()).unwrap_or_default(),
427 expected_result.as_bytes(),
428 "Failed for {encoded_str:?}",
429 );
430 }
431 }
432
433 #[test]
434 fn decode_base64_mime() {
435 for (encoded_str, expected_result) in [
436 ("VGVzdA==\r\n--boundary\n", "Test"),
437 (
438 "PCFET0NUWVBFIGh0bWw+CjxodG1sPg\no8Ym9ke\nT4KPC 9ib2R5Pg\n o8L2h0bWw+Cg==\r\n--boundary--\r\n",
439 "<!DOCTYPE html>\n<html>\n<body>\n</body>\n</html>\n",
440 ),
441 ("w6HDqcOtw7PDug==\r\n--boundary \n", "áéíóú"),
442 ("w\n6\nH\nD\nq\nc\nO\nt\nw\n7\n P\tD u g\n==\r\n--boundary\n", "áéíóú"),
443 ("w6HDqcOtw7PDug==--boundary", "áéíóú"),
444 (
445 "w6HDqcOtw7PDug==\n--boundary--",
446 "áéíóú",
447 ),
448 (
449 "w\n6\nH\nD\nq\nc\nO\nt\nw\n7\n P\tD u g\n==\n--boundary",
450 "áéíóú",
451 ),
452 ] {
453 let mut s = MessageStream::new(encoded_str.as_bytes());
454 let (_, result) = s.decode_base64_mime(b"boundary");
455
456 assert_eq!(
457 result,
458 expected_result.as_bytes(),
459 "Failed for {encoded_str:?}",
460 );
461 }
462 }
463
464 #[test]
465 fn decode_base64_word() {
466 for (encoded_str, expected_result) in [
467 ("w 6 H D q c O t w 7 P D u g== ?=", "áéíóú"),
468 ("w6HDqcOtw7PDug==?=", "áéíóú"),
469 ("w6HDqc\n Otw7PDug==?=", "áéíóú"),
470 ("w6HDqcOtw7PDug================?=", "áéíóú"),
471 ("?=", ""),
472 ] {
473 let mut s = MessageStream::new(encoded_str.as_bytes());
474 assert_eq!(
475 s.decode_base64_word().unwrap(),
476 expected_result.as_bytes(),
477 "Failed for {encoded_str:?}",
478 );
479 }
480 }
481}