Split base64 over several items to insert newlines

This commit is contained in:
Alex 2022-11-18 00:20:42 +01:00
parent 8c4d2dbd93
commit 22fe9568bd
Signed by: lx
GPG key ID: 0E496D15096376BE
3 changed files with 44 additions and 15 deletions

View file

@ -385,13 +385,31 @@ impl<'a, 'b> Term<'a, 'b> {
/// assert_eq!(term.bytes().unwrap(), b"hello, world!");
/// ```
pub fn bytes(&self) -> Result<Vec<u8>, TypeError> {
let encoded = match &self.0 {
AnyTerm::Str(s) => s,
AnyTerm::List(r, l) if l.iter().all(|x| matches!(x, NonListTerm::Str(_))) => r,
_ => return Err(TypeError::WrongType("BYTES")),
let decode = |encoded| {
base64::decode_config(encoded, base64::URL_SAFE_NO_PAD)
.map_err(|_| TypeError::WrongType("BYTES"))
};
base64::decode_config(encoded, base64::URL_SAFE_NO_PAD)
.map_err(|_| TypeError::WrongType("BYTES"))
match self.0.mkref() {
AnyTerm::Str(encoded) => {
if encoded == b"." {
Ok(vec![])
} else {
decode(encoded)
}
}
AnyTerm::ListRef(_, list) => {
let mut ret = Vec::with_capacity(128);
for term in list.iter() {
if let NonListTerm::Str(encoded) = term {
ret.extend(decode(encoded)?)
} else {
return Err(TypeError::WrongType("BYTES"));
}
}
Ok(ret)
}
_ => Err(TypeError::WrongType("BYTES")),
}
}
/// Try to interpret this string as base64-encoded bytes,

View file

@ -123,10 +123,16 @@ pub fn dict<'a, I: IntoIterator<Item = (&'a str, Term<'a>)>>(pairs: I) -> Term<'
///
/// assert_eq!(encode(bytes(b"hello, world!")).unwrap(), b"aGVsbG8sIHdvcmxkIQ");
/// ```
pub fn bytes(b: &[u8]) -> Term<'static> {
Term(T::OwnedStr(
base64::encode_config(b, base64::URL_SAFE_NO_PAD).into_bytes(),
))
pub fn bytes(bytes: &[u8]) -> Term<'static> {
let chunks = bytes
.chunks(48)
.map(|b| T::OwnedStr(base64::encode_config(b, base64::URL_SAFE_NO_PAD).into_bytes()))
.collect::<Vec<_>>();
if chunks.len() > 1 {
Term(T::List(chunks))
} else {
Term(chunks.into_iter().next().unwrap_or(T::Str(b".")))
}
}
impl<'a> Term<'a> {
@ -197,7 +203,7 @@ fn encode_aux(buf: &mut Vec<u8>, term: T<'_>, indent: usize) -> Result<(), Error
T::List(l) => {
let indent2 = indent + 2;
for (i, v) in l.into_iter().enumerate() {
if buf.iter().rev().take_while(|c| **c != b'\n').count() > 80 {
if buf.iter().rev().take_while(|c| **c != b'\n').count() >= 70 {
buf.push(b'\n');
for _ in 0..indent2 {
buf.push(b' ');

View file

@ -55,21 +55,26 @@
//! a = hello,
//! b = world,
//! c = { a = 12, b = 42 },
//! } gTjRjHtSX6OCwq3pdl9Bpg6M2h-2WkciKi0uNV8NQX0
//! } YutjCfgXXYNkNR1IQiNi3pFKpvqfwICkLc3EJOekcq4
//! ```
//!
//! And the value of `text2` would be as follows:
//! ```raw
//! {
//! hash = BEBZp98KF_d1rvBd5Ib8q1w_oGvrvIcKRXFv9kMB0ewOWH42OPd8qa0V_2ranV92z0mEdswftqvpAYebziTIew,
//! hash = IT4ay3XM4SycgYjxV8_Ioxqqt9JwdFK0sZqd-TOhOl9IGxbTQwK8vPy409h59xCV
//! NrMjDC1YIS7bXIrrv_Tvbw,
//! payload = CALL myfunction {
//! a = hello,
//! b = world,
//! c = { a = 12, b = 42 },
//! } gTjRjHtSX6OCwq3pdl9Bpg6M2h-2WkciKi0uNV8NQX0,
//! signature = rAwIUTsCdoB_4eqo7r5e_J5ZHFaxHnXi99oNWi7h7y0mRfgt5u7-qXn7spIN1GcmDWYh4EPzoY34Br-sRxi0AA,
//! } YutjCfgXXYNkNR1IQiNi3pFKpvqfwICkLc3EJOekcq4,
//! signature = UFje_N6vnrN23-ygB1yr8LwSipSwxrMLEB2ov6bvU4rR9BmfLjxyq8zTzKxb_VNw
//! UABMRcy-KiITwpY_b3UdBg,
//! }
//! ```
//!
//! Note that the value of `text1` is embedded as-is inside `text2`. This is what allows us
//! to check the hash and the signature: the raw representation of the term hasn't changed.
pub mod crypto;
pub mod dec;