From 4a30679491f85d03a4b5c5b6daddc6f78eff662c Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 17 Nov 2021 12:13:52 +0000 Subject: [PATCH 1/2] f4jumble: Return `Error` from allocating functions --- components/f4jumble/src/lib.rs | 18 ++++-------------- components/zcash_address/src/kind/unified.rs | 7 ++++--- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/components/f4jumble/src/lib.rs b/components/f4jumble/src/lib.rs index 9fbf265c5..1afea0523 100644 --- a/components/f4jumble/src/lib.rs +++ b/components/f4jumble/src/lib.rs @@ -155,25 +155,15 @@ pub fn f4jumble_inv_mut(message: &mut [u8]) -> Result<(), Error> { } #[cfg(feature = "std")] -pub fn f4jumble(message: &[u8]) -> Option> { +pub fn f4jumble(message: &[u8]) -> Result, Error> { let mut result = message.to_vec(); - let res = f4jumble_mut(&mut result); - if res.is_ok() { - Some(result) - } else { - None - } + f4jumble_mut(&mut result).map(|()| result) } #[cfg(feature = "std")] -pub fn f4jumble_inv(message: &[u8]) -> Option> { +pub fn f4jumble_inv(message: &[u8]) -> Result, Error> { let mut result = message.to_vec(); - let res = f4jumble_inv_mut(&mut result); - if res.is_ok() { - Some(result) - } else { - None - } + f4jumble_inv_mut(&mut result).map(|()| result) } #[cfg(test)] diff --git a/components/zcash_address/src/kind/unified.rs b/components/zcash_address/src/kind/unified.rs index 7a501c2d3..2f68095db 100644 --- a/components/zcash_address/src/kind/unified.rs +++ b/components/zcash_address/src/kind/unified.rs @@ -222,7 +222,8 @@ pub(crate) mod private { writer.write_all(&padding).unwrap(); let padded = writer.into_inner(); - f4jumble::f4jumble(&padded).unwrap_or_else(|| panic!("f4jumble failed on {:?}", padded)) + f4jumble::f4jumble(&padded) + .unwrap_or_else(|e| panic!("f4jumble failed on {:?}: {}", padded, e)) } /// Parse the items of the unified container. @@ -265,8 +266,8 @@ pub(crate) mod private { result } - let encoded = f4jumble::f4jumble_inv(buf).ok_or_else(|| { - ParseError::InvalidEncoding("F4Jumble decoding failed".to_owned()) + let encoded = f4jumble::f4jumble_inv(buf).map_err(|e| { + ParseError::InvalidEncoding(format!("F4Jumble decoding failed: {}", e)) })?; // Validate and strip trailing padding bytes. From fa75c9587c2391c232156abda6f076d369b6992a Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 17 Nov 2021 12:13:57 +0000 Subject: [PATCH 2/2] zcash_address: Avoid an unnecessary allocation while parsing a UA --- components/zcash_address/src/kind/unified.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/components/zcash_address/src/kind/unified.rs b/components/zcash_address/src/kind/unified.rs index 2f68095db..533516354 100644 --- a/components/zcash_address/src/kind/unified.rs +++ b/components/zcash_address/src/kind/unified.rs @@ -227,7 +227,7 @@ pub(crate) mod private { } /// Parse the items of the unified container. - fn parse_items(hrp: &str, buf: &[u8]) -> Result, ParseError> { + fn parse_items>>(hrp: &str, buf: T) -> Result, ParseError> { fn read_receiver( mut cursor: &mut std::io::Cursor<&[u8]>, ) -> Result { @@ -266,7 +266,9 @@ pub(crate) mod private { result } - let encoded = f4jumble::f4jumble_inv(buf).map_err(|e| { + // Here we allocate if necessary to get a mutable Vec to unjumble. + let mut encoded = buf.into(); + f4jumble::f4jumble_inv_mut(&mut encoded[..]).map_err(|e| { ParseError::InvalidEncoding(format!("F4Jumble decoding failed: {}", e)) })?; @@ -327,7 +329,7 @@ pub(crate) mod private { } } - fn parse_internal(hrp: &str, buf: &[u8]) -> Result { + fn parse_internal>>(hrp: &str, buf: T) -> Result { Self::parse_items(hrp, buf).and_then(Self::try_from_items_internal) } } @@ -365,7 +367,7 @@ pub trait Encoding: private::SealedContainer { let data = Vec::::from_base32(&data) .map_err(|e| ParseError::InvalidEncoding(e.to_string()))?; - Self::parse_internal(hrp, &data[..]).map(|value| (net, value)) + Self::parse_internal(hrp, data).map(|value| (net, value)) } else { Err(ParseError::NotUnified) }