Merge branch 'tor-netdoc/use-base64ct' into 'main'
Replace `base64` crate with `base64ct` crate in `tor-netdoc` See merge request tpo/core/arti!600
This commit is contained in:
commit
b1aab512ff
|
@ -510,9 +510,9 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
|
|||
|
||||
[[package]]
|
||||
name = "base64ct"
|
||||
version = "1.1.1"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6b4d9b1225d28d360ec6a231d65af1fd99a2a095154c8040689617290569c5c"
|
||||
checksum = "dea908e7347a8c64e378c17e30ef880ad73e3b4498346b055c2c00ea342f3179"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
|
@ -2289,9 +2289,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pem-rfc7468"
|
||||
version = "0.2.4"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84e93a3b1cc0510b03020f33f21e62acdde3dcaef432edc95bea377fbd4c2cd4"
|
||||
checksum = "8f22eb0e3c593294a99e9ff4b24cf6b752d43f193aa4415fe5077c159996d497"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
]
|
||||
|
@ -3822,7 +3822,7 @@ dependencies = [
|
|||
name = "tor-netdoc"
|
||||
version = "0.4.0"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"base64ct",
|
||||
"bitflags",
|
||||
"derive_more",
|
||||
"digest 0.10.3",
|
||||
|
|
|
@ -45,7 +45,7 @@ experimental-api = []
|
|||
dangerous-expose-struct-fields = ["visible", "visibility"]
|
||||
|
||||
[dependencies]
|
||||
base64 = "0.13.0"
|
||||
base64ct = { version = "1.5.0", features = ["alloc"] }
|
||||
bitflags = "1"
|
||||
derive_more = "0.99"
|
||||
digest = "0.10.0"
|
||||
|
|
|
@ -8,6 +8,7 @@ use crate::parse::keyword::Keyword;
|
|||
use crate::types::misc::FromBytes;
|
||||
use crate::util::PauseAt;
|
||||
use crate::{Error, ParseErrorKind as EK, Pos, Result};
|
||||
use base64ct::{Base64, Encoding};
|
||||
use std::cell::{Ref, RefCell};
|
||||
use std::str::FromStr;
|
||||
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
|
||||
/// 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.
|
||||
let mut v = Vec::new();
|
||||
let mut s = s.to_string();
|
||||
s.retain(|ch| ch != '\n');
|
||||
base64::decode_config_buf(s, base64::STANDARD, &mut v)?;
|
||||
let v = Base64::decode_vec(&s)?;
|
||||
Ok(v)
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ pub(crate) trait FromBytes: Sized {
|
|||
/// Types for decoding base64-encoded values.
|
||||
mod b64impl {
|
||||
use crate::{Error, ParseErrorKind as EK, Pos, Result};
|
||||
use base64ct::{Base64, Encoding};
|
||||
use std::ops::RangeBounds;
|
||||
|
||||
/// A byte array, encoded in base64 with optional padding.
|
||||
|
@ -44,12 +45,28 @@ mod b64impl {
|
|||
impl std::str::FromStr for B64 {
|
||||
type Err = Error;
|
||||
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. For more info on
|
||||
// this, take a look at this issue:
|
||||
// `https://github.com/RustCrypto/utils/issues/576`
|
||||
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
|
||||
.with_msg("Invalid base64")
|
||||
.at_pos(Pos::at(s))
|
||||
})?;
|
||||
Ok(B64(bytes))
|
||||
Ok(B64(v))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -455,27 +472,79 @@ mod nickname {
|
|||
#[cfg(test)]
|
||||
mod test {
|
||||
#![allow(clippy::unwrap_used)]
|
||||
use base64ct::Encoding;
|
||||
|
||||
use super::*;
|
||||
use crate::{Pos, Result};
|
||||
|
||||
/// 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();
|
||||
s.retain(|c| !c.is_ascii_whitespace());
|
||||
base64::decode(s)
|
||||
base64ct::Base64::decode_vec(s.as_str())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn base64() -> Result<()> {
|
||||
// Test parsing succeess:
|
||||
// Unpadded:
|
||||
assert_eq!("Mi43MTgyOA".parse::<B64>()?.as_bytes(), &b"2.71828"[..]);
|
||||
assert!("Mi43MTgyOA".parse::<B64>()?.check_len(7..8).is_ok());
|
||||
assert_eq!("Mg".parse::<B64>()?.as_bytes(), &b"2"[..]);
|
||||
assert!("Mg".parse::<B64>()?.check_len(1..2).is_ok());
|
||||
assert_eq!(
|
||||
"8J+NkvCfjZLwn42S8J+NkvCfjZLwn42S"
|
||||
.parse::<B64>()?
|
||||
.as_bytes(),
|
||||
"🍒🍒🍒🍒🍒🍒".as_bytes()
|
||||
);
|
||||
assert!("8J+NkvCfjZLwn42S8J+NkvCfjZLwn42S"
|
||||
.parse::<B64>()?
|
||||
.check_len(24..25)
|
||||
.is_ok());
|
||||
assert!("ppwthHXW8kXD0f9fE7UPYsOAAu4uj5ORwSomCMxKkz8="
|
||||
.parse::<B64>()?
|
||||
.check_len(32..33)
|
||||
.is_ok());
|
||||
// Padded:
|
||||
assert_eq!("Mi43MTgyOA==".parse::<B64>()?.as_bytes(), &b"2.71828"[..]);
|
||||
assert!("Mi43MTgyOA==".parse::<B64>()?.check_len(7..8).is_ok());
|
||||
assert_eq!("Mg==".parse::<B64>()?.as_bytes(), &b"2"[..]);
|
||||
assert!("Mg==".parse::<B64>()?.check_len(1..2).is_ok());
|
||||
|
||||
// Test parsing failures:
|
||||
// Invalid character.
|
||||
assert!("Mi43!!!!!!".parse::<B64>().is_err());
|
||||
// Invalid last character.
|
||||
assert!("Mi".parse::<B64>().is_err());
|
||||
assert!("Mi43MTgyOA".parse::<B64>()?.check_len(7..=8).is_ok());
|
||||
assert!("ppwthHXW8kXD0f9fE7UPYsOAAu4uj5ORwSomCMxaaaa"
|
||||
.parse::<B64>()
|
||||
.is_err());
|
||||
// Invalid length.
|
||||
assert!("Mi43MTgyOA".parse::<B64>()?.check_len(8..).is_err());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn base64_lengths() -> Result<()> {
|
||||
assert_eq!("".parse::<B64>()?.as_bytes(), b"");
|
||||
assert!("=".parse::<B64>().is_err());
|
||||
assert!("==".parse::<B64>().is_err());
|
||||
assert!("B".parse::<B64>().is_err());
|
||||
assert!("B=".parse::<B64>().is_err());
|
||||
assert!("B==".parse::<B64>().is_err());
|
||||
assert_eq!("Bg".parse::<B64>()?.as_bytes(), b"\x06");
|
||||
assert_eq!("Bg=".parse::<B64>()?.as_bytes(), b"\x06");
|
||||
assert_eq!("Bg==".parse::<B64>()?.as_bytes(), b"\x06");
|
||||
assert_eq!("BCg".parse::<B64>()?.as_bytes(), b"\x04\x28");
|
||||
assert_eq!("BCg=".parse::<B64>()?.as_bytes(), b"\x04\x28");
|
||||
assert!("BCg==".parse::<B64>().is_err());
|
||||
assert_eq!("BCDE".parse::<B64>()?.as_bytes(), b"\x04\x20\xc4");
|
||||
assert!("BCDE=".parse::<B64>().is_err());
|
||||
assert!("BCDE==".parse::<B64>().is_err());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn base16() -> Result<()> {
|
||||
assert_eq!("332e313432".parse::<B16>()?.as_bytes(), &b"3.142"[..]);
|
||||
|
|
Loading…
Reference in New Issue