diff --git a/google-apis-common/src/serde.rs b/google-apis-common/src/serde.rs index 622a60a215..8d95afe87c 100644 --- a/google-apis-common/src/serde.rs +++ b/google-apis-common/src/serde.rs @@ -170,7 +170,13 @@ pub mod standard_base64 { D: Deserializer<'de>, { let s: Cow = Deserialize::deserialize(deserializer)?; - base64::prelude::BASE64_STANDARD.decode(s.as_ref()).map_err(serde::de::Error::custom) + match base64::prelude::BASE64_STANDARD.decode(s.as_ref()) { + Ok(decoded) => Ok(decoded), + Err(first_err) => match base64::prelude::BASE64_URL_SAFE.decode(s.as_ref()) { + Ok(decoded) => Ok(decoded), + Err(_) => Err(serde::de::Error::custom(first_err)) + } + } } } } @@ -202,7 +208,13 @@ pub mod urlsafe_base64 { D: Deserializer<'de>, { let s: Cow = Deserialize::deserialize(deserializer)?; - base64::prelude::BASE64_URL_SAFE.decode(s.as_ref()).map_err(serde::de::Error::custom) + match base64::prelude::BASE64_URL_SAFE.decode(s.as_ref()) { + Ok(decoded) => Ok(decoded), + Err(first_err) => match base64::prelude::BASE64_STANDARD.decode(s.as_ref()) { + Ok(decoded) => Ok(decoded), + Err(_) => Err(serde::de::Error::custom(first_err)) + } + } } } } @@ -343,14 +355,28 @@ mod test { assert_eq!(Some(b"hello world".as_slice()), wrapper.bytes.as_deref()); } + #[test] + fn urlsafe_base64_de_standard_success_cases() { + let wrapper: Base64URLSafeWrapper = // Expect URL-safe base64 accepts standard encoding + serde_json::from_reader(r#"{"bytes": "REE/P0V+Nz4oIWtH"}"#.as_bytes()).unwrap(); + assert_eq!(Some(b"DA??E~7>(!kG".as_slice()), wrapper.bytes.as_deref()); + } + #[test] fn urlsafe_base64_de_failure_cases() { assert!( - serde_json::from_str::(r#"{"bytes": "aGVsbG8gd29ybG+Q"}"#) + serde_json::from_str::(r#"{"bytes": "aGVsbG8gd29ybG&Q"}"#) .is_err() ); } + #[test] + fn standard_base64_de_urlsafe_success_cases() { + let wrapper: Base64URLSafeWrapper = // Expect standard base64 accepts url-safe encoding + serde_json::from_reader(r#"{"bytes": "REE_P0V-Nz4oIWtH"}"#.as_bytes()).unwrap(); + assert_eq!(Some(b"DA??E~7>(!kG".as_slice()), wrapper.bytes.as_deref()); + } + #[test] fn standard_base64_de_failure_cases() { assert!(serde_json::from_str::(r#"{"bytes": "%"}"#).is_err());