18
18
#[ macro_use] extern crate matches;
19
19
pub extern crate mime;
20
20
21
+ use forgiving_base64:: { InvalidBase64 , DecodeError } ;
22
+
23
+ pub mod forgiving_base64;
24
+
21
25
pub struct DataUrl < ' a > {
22
26
mime_type : mime:: Mime ,
23
27
base64 : bool ,
@@ -30,19 +34,6 @@ pub enum DataUrlError {
30
34
NoComma ,
31
35
}
32
36
33
- #[ derive( Debug ) ]
34
- pub enum DecodeError < E > {
35
- InvalidBase64 ( InvalidBase64 ) ,
36
- WriteError ( E ) ,
37
- }
38
-
39
- #[ derive( Debug ) ]
40
- pub struct InvalidBase64 ( ( ) ) ;
41
-
42
- impl < E > From < InvalidBase64 > for DecodeError < E > {
43
- fn from ( e : InvalidBase64 ) -> Self { DecodeError :: InvalidBase64 ( e) }
44
- }
45
-
46
37
impl < ' a > DataUrl < ' a > {
47
38
/// <https://fetch.spec.whatwg.org/#data-url-processor>
48
39
/// but starting from a string rather than a parsed `Url`, to avoid extra string copies.
@@ -87,17 +78,6 @@ impl<'a> DataUrl<'a> {
87
78
}
88
79
}
89
80
90
- enum Impossible { }
91
-
92
- impl From < DecodeError < Impossible > > for InvalidBase64 {
93
- fn from ( e : DecodeError < Impossible > ) -> Self {
94
- match e {
95
- DecodeError :: InvalidBase64 ( e) => e,
96
- DecodeError :: WriteError ( e) => match e { }
97
- }
98
- }
99
- }
100
-
101
81
/// The URL’s fragment identifier (after `#`)
102
82
pub struct FragmentIdentifier < ' a > ( & ' a str ) ;
103
83
@@ -312,142 +292,8 @@ fn decode_with_base64<F, E>(encoded_body_plus_fragment: &str, write_bytes: F)
312
292
-> Result < Option < FragmentIdentifier > , DecodeError < E > >
313
293
where F : FnMut ( & [ u8 ] ) -> Result < ( ) , E >
314
294
{
315
- let mut decoder = ForgivingBase64Decoder :: new ( write_bytes) ;
295
+ let mut decoder = forgiving_base64 :: Decoder :: new ( write_bytes) ;
316
296
let fragment = decode_without_base64 ( encoded_body_plus_fragment, |bytes| decoder. feed ( bytes) ) ?;
317
297
decoder. finish ( ) ?;
318
298
Ok ( fragment)
319
299
}
320
-
321
- /// <https://infra.spec.whatwg.org/#forgiving-base64-decode>
322
- ///
323
- /// `input` is assumed to be in an ASCII-compatible encoding
324
- pub fn forgiving_base64_decode_to_vec ( input : & [ u8 ] ) -> Result < Vec < u8 > , InvalidBase64 > {
325
- let mut v = Vec :: new ( ) ;
326
- {
327
- let mut decoder = ForgivingBase64Decoder :: new ( |bytes| Ok ( v. extend_from_slice ( bytes) ) ) ;
328
- decoder. feed ( input) ?;
329
- decoder. finish ( ) ?;
330
- }
331
- Ok ( v)
332
- }
333
-
334
- /// <https://infra.spec.whatwg.org/#forgiving-base64-decode>
335
- pub struct ForgivingBase64Decoder < F , E > where F : FnMut ( & [ u8 ] ) -> Result < ( ) , E > {
336
- write_bytes : F ,
337
- bit_buffer : u32 ,
338
- buffer_bit_length : u8 ,
339
- padding_symbols : u8 ,
340
- }
341
-
342
- impl < F , E > ForgivingBase64Decoder < F , E > where F : FnMut ( & [ u8 ] ) -> Result < ( ) , E > {
343
- pub fn new ( write_bytes : F ) -> Self {
344
- Self {
345
- write_bytes,
346
- bit_buffer : 0 ,
347
- buffer_bit_length : 0 ,
348
- padding_symbols : 0 ,
349
- }
350
- }
351
-
352
- /// Feed to the decoder partial input in an ASCII-compatible encoding
353
- pub fn feed ( & mut self , input : & [ u8 ] ) -> Result < ( ) , DecodeError < E > > {
354
- for & byte in input. iter ( ) {
355
- let value = BASE64_DECODE_TABLE [ byte as usize ] ;
356
- if value < 0 {
357
- // A character that’s not part of the alphabet
358
-
359
- // Remove ASCII whitespace
360
- // '\t' | '\n' | '\r' was already filtered by decode_without_base64()
361
- if byte == b' ' || byte == b'\x0C' {
362
- continue
363
- }
364
-
365
- if byte == b'=' {
366
- self . padding_symbols = self . padding_symbols . saturating_add ( 8 ) ;
367
- continue
368
- }
369
-
370
- Err ( InvalidBase64 ( ( ) ) ) ?
371
- }
372
- if self . padding_symbols > 0 {
373
- // Alphabet symbols after padding
374
- Err ( InvalidBase64 ( ( ) ) ) ?
375
- }
376
- self . bit_buffer <<= 6 ;
377
- self . bit_buffer |= value as u32 ;
378
- if self . buffer_bit_length < 24 {
379
- self . buffer_bit_length += 6 ;
380
- } else {
381
- // We’ve accumulated four times 6 bits, which equals three times 8 bits.
382
- let byte_buffer = [
383
- ( self . bit_buffer >> 16 ) as u8 ,
384
- ( self . bit_buffer >> 8 ) as u8 ,
385
- self . bit_buffer as u8 ,
386
- ] ;
387
- ( self . write_bytes ) ( & byte_buffer) . map_err ( DecodeError :: WriteError ) ?;
388
- self . buffer_bit_length = 0 ;
389
- // No need to reset bit_buffer,
390
- // since next time we’re only gonna read relevant bits.
391
- }
392
- }
393
- Ok ( ( ) )
394
- }
395
-
396
- /// Call this to signal the end of the input
397
- pub fn finish ( mut self ) -> Result < ( ) , DecodeError < E > > {
398
- match ( self . buffer_bit_length , self . padding_symbols ) {
399
- ( 0 , 0 ) => {
400
- // A multiple of four of alphabet symbols, and nothing else.
401
- }
402
- ( 12 , 2 ) | ( 12 , 0 ) => {
403
- // A multiple of four of alphabet symbols, followed by two more symbols,
404
- // optionally followed by two padding characters (which make a total multiple of four).
405
- let byte_buffer = [
406
- ( self . bit_buffer >> 4 ) as u8 ,
407
- ] ;
408
- ( self . write_bytes ) ( & byte_buffer) . map_err ( DecodeError :: WriteError ) ?;
409
- }
410
- ( 18 , 1 ) | ( 18 , 0 ) => {
411
- // A multiple of four of alphabet symbols, followed by three more symbols,
412
- // optionally followed by one padding character (which make a total multiple of four).
413
- let byte_buffer = [
414
- ( self . bit_buffer >> 10 ) as u8 ,
415
- ( self . bit_buffer >> 2 ) as u8 ,
416
- ] ;
417
- ( self . write_bytes ) ( & byte_buffer) . map_err ( DecodeError :: WriteError ) ?;
418
- }
419
- _ => {
420
- // No other combination is acceptable
421
- Err ( InvalidBase64 ( ( ) ) ) ?
422
- }
423
- }
424
- Ok ( ( ) )
425
- }
426
- }
427
-
428
-
429
- /// Generated by `make_base64_decode_table.py` based on "Table 1: The Base 64 Alphabet"
430
- /// at <https://tools.ietf.org/html/rfc4648#section-4>
431
- ///
432
- /// Array indices are the byte value of symbols.
433
- /// Array values are their positions in the base64 alphabet,
434
- /// or -1 for symbols not in the alphabet.
435
- /// The position contributes 6 bits to the decoded bytes.
436
- const BASE64_DECODE_TABLE : [ i8 ; 256 ] = [
437
- -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ,
438
- -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ,
439
- -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , 62 , -1 , -1 , -1 , 63 ,
440
- 52 , 53 , 54 , 55 , 56 , 57 , 58 , 59 , 60 , 61 , -1 , -1 , -1 , -1 , -1 , -1 ,
441
- -1 , 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 ,
442
- 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , -1 , -1 , -1 , -1 , -1 ,
443
- -1 , 26 , 27 , 28 , 29 , 30 , 31 , 32 , 33 , 34 , 35 , 36 , 37 , 38 , 39 , 40 ,
444
- 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , -1 , -1 , -1 , -1 , -1 ,
445
- -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ,
446
- -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ,
447
- -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ,
448
- -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ,
449
- -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ,
450
- -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ,
451
- -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ,
452
- -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ,
453
- ] ;
0 commit comments