Skip to content

Commit

Permalink
Do not require padding when decoding base64 bytes (#1448)
Browse files Browse the repository at this point in the history
  • Loading branch information
bschoenmaeckers authored Sep 17, 2024
1 parent dbe03f6 commit bc0c97a
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 4 deletions.
18 changes: 14 additions & 4 deletions src/validators/config.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use std::borrow::Cow;
use std::str::FromStr;

use base64::engine::general_purpose::{STANDARD, URL_SAFE};
use base64::{DecodeError, Engine};
use base64::engine::general_purpose::GeneralPurpose;
use base64::engine::{DecodePaddingMode, GeneralPurposeConfig};
use base64::{alphabet, DecodeError, Engine};
use pyo3::types::{PyDict, PyString};
use pyo3::{intern, prelude::*};

Expand All @@ -11,6 +12,15 @@ use crate::input::EitherBytes;
use crate::serializers::BytesMode;
use crate::tools::SchemaDict;

const URL_SAFE_OPTIONAL_PADDING: GeneralPurpose = GeneralPurpose::new(
&alphabet::URL_SAFE,
GeneralPurposeConfig::new().with_decode_padding_mode(DecodePaddingMode::Indifferent),
);
const STANDARD_OPTIONAL_PADDING: GeneralPurpose = GeneralPurpose::new(
&alphabet::STANDARD,
GeneralPurposeConfig::new().with_decode_padding_mode(DecodePaddingMode::Indifferent),
);

#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
pub struct ValBytesMode {
pub ser: BytesMode,
Expand All @@ -29,10 +39,10 @@ impl ValBytesMode {
pub fn deserialize_string<'py>(self, s: &str) -> Result<EitherBytes<'_, 'py>, ErrorType> {
match self.ser {
BytesMode::Utf8 => Ok(EitherBytes::Cow(Cow::Borrowed(s.as_bytes()))),
BytesMode::Base64 => URL_SAFE
BytesMode::Base64 => URL_SAFE_OPTIONAL_PADDING
.decode(s)
.or_else(|err| match err {
DecodeError::InvalidByte(_, b'/' | b'+') => STANDARD.decode(s),
DecodeError::InvalidByte(_, b'/' | b'+') => STANDARD_OPTIONAL_PADDING.decode(s),
_ => Err(err),
})
.map(EitherBytes::from)
Expand Down
6 changes: 6 additions & 0 deletions tests/test_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,12 @@ def test_json_bytes_base64_round_trip():
assert v.validate_json(b'{"key":' + encoded_url + b'}') == {'key': data}


def test_json_bytes_base64_no_padding():
v = SchemaValidator({'type': 'bytes'}, {'val_json_bytes': 'base64'})
base_64_without_padding = 'bm8tcGFkZGluZw'
assert v.validate_json(json.dumps(base_64_without_padding)) == b'no-padding'


def test_json_bytes_base64_invalid():
v = SchemaValidator({'type': 'bytes'}, {'val_json_bytes': 'base64'})
wrong_input = 'wrong!'
Expand Down

0 comments on commit bc0c97a

Please sign in to comment.