Replace `base64` crate with `base64ct` crate
Note: the `base64ct` crate rejects invalid characters when the decoding is done on padded strings. However, the `FromStr` impl for `B64` can have both padded **and** unpadded inputs, so all inputs are now padded first, before decoding.
This commit is contained in:
parent
4e3537746f
commit
6536ca0f61
|
@ -510,9 +510,9 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64ct"
|
name = "base64ct"
|
||||||
version = "1.1.1"
|
version = "1.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e6b4d9b1225d28d360ec6a231d65af1fd99a2a095154c8040689617290569c5c"
|
checksum = "dea908e7347a8c64e378c17e30ef880ad73e3b4498346b055c2c00ea342f3179"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
|
@ -2288,9 +2288,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pem-rfc7468"
|
name = "pem-rfc7468"
|
||||||
version = "0.2.4"
|
version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "84e93a3b1cc0510b03020f33f21e62acdde3dcaef432edc95bea377fbd4c2cd4"
|
checksum = "8f22eb0e3c593294a99e9ff4b24cf6b752d43f193aa4415fe5077c159996d497"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64ct",
|
"base64ct",
|
||||||
]
|
]
|
||||||
|
@ -3821,6 +3821,7 @@ name = "tor-netdoc"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
|
"base64ct",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
"digest 0.10.3",
|
"digest 0.10.3",
|
||||||
|
|
|
@ -46,6 +46,7 @@ dangerous-expose-struct-fields = ["visible", "visibility"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
base64 = "0.13.0"
|
base64 = "0.13.0"
|
||||||
|
base64ct = { version = "1.5.0", features = ["alloc"] }
|
||||||
bitflags = "1"
|
bitflags = "1"
|
||||||
derive_more = "0.99"
|
derive_more = "0.99"
|
||||||
digest = "0.10.0"
|
digest = "0.10.0"
|
||||||
|
|
|
@ -8,6 +8,7 @@ use crate::parse::keyword::Keyword;
|
||||||
use crate::types::misc::FromBytes;
|
use crate::types::misc::FromBytes;
|
||||||
use crate::util::PauseAt;
|
use crate::util::PauseAt;
|
||||||
use crate::{Error, ParseErrorKind as EK, Pos, Result};
|
use crate::{Error, ParseErrorKind as EK, Pos, Result};
|
||||||
|
use base64ct::{Base64, Encoding};
|
||||||
use std::cell::{Ref, RefCell};
|
use std::cell::{Ref, RefCell};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use tor_error::internal;
|
use tor_error::internal;
|
||||||
|
@ -290,12 +291,11 @@ impl<'a, K: Keyword> Iterator for NetDocReaderBase<'a, K> {
|
||||||
|
|
||||||
/// Helper: as base64::decode(), but allows newlines in the middle of the
|
/// Helper: as base64::decode(), but allows newlines in the middle of the
|
||||||
/// encoded object.
|
/// encoded object.
|
||||||
fn base64_decode_multiline(s: &str) -> std::result::Result<Vec<u8>, base64::DecodeError> {
|
fn base64_decode_multiline(s: &str) -> std::result::Result<Vec<u8>, base64ct::Error> {
|
||||||
// base64 module hates whitespace.
|
// base64 module hates whitespace.
|
||||||
let mut v = Vec::new();
|
|
||||||
let mut s = s.to_string();
|
let mut s = s.to_string();
|
||||||
s.retain(|ch| ch != '\n');
|
s.retain(|ch| ch != '\n');
|
||||||
base64::decode_config_buf(s, base64::STANDARD, &mut v)?;
|
let v = Base64::decode_vec(&s)?;
|
||||||
Ok(v)
|
Ok(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ pub(crate) trait FromBytes: Sized {
|
||||||
/// Types for decoding base64-encoded values.
|
/// Types for decoding base64-encoded values.
|
||||||
mod b64impl {
|
mod b64impl {
|
||||||
use crate::{Error, ParseErrorKind as EK, Pos, Result};
|
use crate::{Error, ParseErrorKind as EK, Pos, Result};
|
||||||
|
use base64ct::{Base64, Encoding};
|
||||||
use std::ops::RangeBounds;
|
use std::ops::RangeBounds;
|
||||||
|
|
||||||
/// A byte array, encoded in base64 with optional padding.
|
/// A byte array, encoded in base64 with optional padding.
|
||||||
|
@ -44,12 +45,26 @@ mod b64impl {
|
||||||
impl std::str::FromStr for B64 {
|
impl std::str::FromStr for B64 {
|
||||||
type Err = Error;
|
type Err = Error;
|
||||||
fn from_str(s: &str) -> Result<Self> {
|
fn from_str(s: &str) -> Result<Self> {
|
||||||
let bytes = base64::decode_config(s, base64::STANDARD_NO_PAD).map_err(|_| {
|
// The `base64ct` crate only rejects invalid
|
||||||
|
// characters when the input is padded. Therefore,
|
||||||
|
// the input must be padded fist.
|
||||||
|
let mut string = s.to_string();
|
||||||
|
// Determine padding length
|
||||||
|
let offset = 4 - s.len() % 4;
|
||||||
|
match offset {
|
||||||
|
4 => (),
|
||||||
|
_ => {
|
||||||
|
// Add pad to input
|
||||||
|
string.push_str("=".repeat(offset).as_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let v = Base64::decode_vec(&string);
|
||||||
|
let v = v.map_err(|_| {
|
||||||
EK::BadArgument
|
EK::BadArgument
|
||||||
.with_msg("Invalid base64")
|
.with_msg("Invalid base64")
|
||||||
.at_pos(Pos::at(s))
|
.at_pos(Pos::at(s))
|
||||||
})?;
|
})?;
|
||||||
Ok(B64(bytes))
|
Ok(B64(v))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,14 +470,16 @@ mod nickname {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
#![allow(clippy::unwrap_used)]
|
#![allow(clippy::unwrap_used)]
|
||||||
|
use base64ct::Encoding;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{Pos, Result};
|
use crate::{Pos, Result};
|
||||||
|
|
||||||
/// Decode s as a multi-line base64 string, ignoring ascii whitespace.
|
/// Decode s as a multi-line base64 string, ignoring ascii whitespace.
|
||||||
fn base64_decode_ignore_ws(s: &str) -> std::result::Result<Vec<u8>, base64::DecodeError> {
|
fn base64_decode_ignore_ws(s: &str) -> std::result::Result<Vec<u8>, base64ct::Error> {
|
||||||
let mut s = s.to_string();
|
let mut s = s.to_string();
|
||||||
s.retain(|c| !c.is_ascii_whitespace());
|
s.retain(|c| !c.is_ascii_whitespace());
|
||||||
base64::decode(s)
|
base64ct::Base64::decode_vec(s.as_str())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Reference in New Issue