@@ -433,18 +433,26 @@ binascii.a2b_base64
433
433
434
434
data: ascii_buffer
435
435
/
436
+ *
437
+ strict_mode: bool(accept={int}) = False
436
438
437
439
Decode a line of base64 data.
440
+
441
+ strict_mode
442
+ When set to True, bytes that are not part of the base64 standard are not allowed.
443
+ The same applies to excess data after padding (= / ==).
438
444
[clinic start generated code]*/
439
445
440
446
static PyObject *
441
- binascii_a2b_base64_impl (PyObject * module , Py_buffer * data )
442
- /*[clinic end generated code: output=0628223f19fd3f9b input=5872acf6e1cac243 ]*/
447
+ binascii_a2b_base64_impl (PyObject * module , Py_buffer * data , int strict_mode )
448
+ /*[clinic end generated code: output=5409557788d4f975 input=3a30c4e3528317c6 ]*/
443
449
{
444
450
assert (data -> len >= 0 );
445
451
446
452
const unsigned char * ascii_data = data -> buf ;
447
453
size_t ascii_len = data -> len ;
454
+ binascii_state * state = NULL ;
455
+ char padding_started = 0 ;
448
456
449
457
/* Allocate the buffer */
450
458
Py_ssize_t bin_len = ((ascii_len + 3 )/4 )* 3 ; /* Upper bound, corrected later */
@@ -455,6 +463,15 @@ binascii_a2b_base64_impl(PyObject *module, Py_buffer *data)
455
463
return NULL ;
456
464
unsigned char * bin_data_start = bin_data ;
457
465
466
+ if (strict_mode && ascii_len > 0 && ascii_data [0 ] == '=' ) {
467
+ malformed_padding :
468
+ state = get_binascii_state (module );
469
+ if (state ) {
470
+ PyErr_SetString (state -> Error , "Leading padding not allowed" );
471
+ }
472
+ goto error_end ;
473
+ }
474
+
458
475
int quad_pos = 0 ;
459
476
unsigned char leftchar = 0 ;
460
477
int pads = 0 ;
@@ -465,20 +482,42 @@ binascii_a2b_base64_impl(PyObject *module, Py_buffer *data)
465
482
** the invalid ones.
466
483
*/
467
484
if (this_ch == BASE64_PAD ) {
485
+ padding_started = 1 ;
486
+
468
487
if (quad_pos >= 2 && quad_pos + ++ pads >= 4 ) {
469
- /* A pad sequence means no more input.
470
- ** We've already interpreted the data
471
- ** from the quad at this point .
488
+ /* A pad sequence means we should not parse more input.
489
+ ** We've already interpreted the data from the quad at this point.
490
+ ** in strict mode, an error should raise if there's excess data after the padding .
472
491
*/
492
+ if (strict_mode && i + 1 < ascii_len ) {
493
+ state = get_binascii_state (module );
494
+ if (state ) {
495
+ PyErr_SetString (state -> Error , "Excess data after padding" );
496
+ }
497
+ goto error_end ;
498
+ }
499
+
473
500
goto done ;
474
501
}
475
502
continue ;
476
503
}
477
504
478
505
this_ch = table_a2b_base64 [this_ch ];
479
506
if (this_ch >= 64 ) {
507
+ if (strict_mode ) {
508
+ state = get_binascii_state (module );
509
+ if (state ) {
510
+ PyErr_SetString (state -> Error , "Only base64 data is allowed" );
511
+ }
512
+ goto error_end ;
513
+ }
480
514
continue ;
481
515
}
516
+
517
+ // Characters that are not '=', in the middle of the padding, are not allowed
518
+ if (strict_mode && padding_started ) {
519
+ goto malformed_padding ;
520
+ }
482
521
pads = 0 ;
483
522
484
523
switch (quad_pos ) {
@@ -505,7 +544,7 @@ binascii_a2b_base64_impl(PyObject *module, Py_buffer *data)
505
544
}
506
545
507
546
if (quad_pos != 0 ) {
508
- binascii_state * state = get_binascii_state (module );
547
+ state = get_binascii_state (module );
509
548
if (state == NULL ) {
510
549
/* error already set, from get_binascii_state */
511
550
} else if (quad_pos == 1 ) {
@@ -522,6 +561,7 @@ binascii_a2b_base64_impl(PyObject *module, Py_buffer *data)
522
561
} else {
523
562
PyErr_SetString (state -> Error , "Incorrect padding" );
524
563
}
564
+ error_end :
525
565
_PyBytesWriter_Dealloc (& writer );
526
566
return NULL ;
527
567
}
0 commit comments