mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-09-30 13:19:44 +02:00
perf(extensions): avoid copying unwrapped Base64 input
Decode borrowed input directly when it contains no CR/LF, retaining normalization for wrapped input. Verify trailing-bit compatibility, malformed-input errors, Unicode rejection and large payload parity.
This commit is contained in:
1 parent
48ba08976a
commit
ace42351ad
1 file changed
+54
-3
@@ -104,11 +104,15 @@ pub(crate) fn decode_string(value: &str, encoding: &str) -> Result<Vec<u8>, Stri
|
||||
}
|
||||
|
||||
pub(crate) fn decode_base64(value: &str) -> Result<Vec<u8>, base64::DecodeError> {
|
||||
GeneralPurpose::new(
|
||||
let engine = GeneralPurpose::new(
|
||||
&alphabet::STANDARD,
|
||||
GeneralPurposeConfig::new().with_decode_allow_trailing_bits(true),
|
||||
)
|
||||
.decode(value.replace(['\r', '\n'], ""))
|
||||
);
|
||||
if value.contains(['\r', '\n']) {
|
||||
engine.decode(value.replace(['\r', '\n'], ""))
|
||||
} else {
|
||||
engine.decode(value)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn decode_option_bytes(
|
||||
@@ -225,3 +229,50 @@ fn go_float_i64(number: f64) -> i64 {
|
||||
i64::MIN
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn base64_preserves_newlines_trailing_bits_and_error_offsets() {
|
||||
let engine = GeneralPurpose::new(
|
||||
&alphabet::STANDARD,
|
||||
GeneralPurposeConfig::new().with_decode_allow_trailing_bits(true),
|
||||
);
|
||||
for value in [
|
||||
"",
|
||||
"Zg==",
|
||||
"Zh==",
|
||||
"Zm8=",
|
||||
"Zm9=",
|
||||
"Zm9v",
|
||||
"\r\nZ\rg==\n",
|
||||
"\r\n",
|
||||
"Zg=",
|
||||
"Zg===",
|
||||
"Zg==!",
|
||||
"Zg==\n!",
|
||||
"Z g==",
|
||||
"Zg==\t",
|
||||
"🎵",
|
||||
"\n🎵",
|
||||
] {
|
||||
assert_eq!(
|
||||
decode_base64(value),
|
||||
engine.decode(value.replace(['\r', '\n'], "")),
|
||||
"{value:?}"
|
||||
);
|
||||
}
|
||||
let bytes: Vec<_> = (0..=255).cycle().take(1024 * 1024).collect();
|
||||
let encoded = STANDARD.encode(&bytes);
|
||||
assert_eq!(decode_base64(&encoded).unwrap(), bytes);
|
||||
let wrapped = encoded
|
||||
.as_bytes()
|
||||
.chunks(76)
|
||||
.map(|line| std::str::from_utf8(line).unwrap())
|
||||
.collect::<Vec<_>>()
|
||||
.join("\r\n");
|
||||
assert_eq!(decode_base64(&wrapped).unwrap(), bytes);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user