Skip to content

Commit 352a432

Browse files
authored
Test bech32 decoder errors (#223)
1 parent 753f0ec commit 352a432

File tree

3 files changed

+44
-19
lines changed

3 files changed

+44
-19
lines changed

src/bech32_decoder.rs

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::*;
22

3+
#[derive(Debug)]
34
pub(crate) struct Bech32Decoder<'a> {
45
data: &'a [u8],
56
i: usize,
@@ -32,18 +33,8 @@ impl<'a> Bech32Decoder<'a> {
3233
if let Some((i, last)) = fes.clone().enumerate().last() {
3334
let padding_len = (i + 1) * 5 % 8;
3435

35-
if padding_len > 4 {
36-
return Err(Bech32Error::Padding {
37-
source: PaddingError::TooMuch,
38-
ty: self.ty,
39-
});
40-
}
41-
4236
if u64::from(last.to_u8().trailing_zeros()) < padding_len.into_u64() {
43-
return Err(Bech32Error::Padding {
44-
source: PaddingError::NonZero,
45-
ty: self.ty,
46-
});
37+
return Err(Bech32Error::Padding { ty: self.ty });
4738
}
4839
}
4940

@@ -99,6 +90,43 @@ impl<'a> Bech32Decoder<'a> {
9990
mod tests {
10091
use super::*;
10192

93+
fn checksum(s: &str) -> String {
94+
let checked_hrpstring = CheckedHrpstring::new::<bech32::NoChecksum>(s).unwrap();
95+
96+
checked_hrpstring
97+
.fe32_iter::<std::vec::IntoIter<u8>>()
98+
.with_checksum::<bech32::Bech32m>(&checked_hrpstring.hrp())
99+
.chars()
100+
.collect()
101+
}
102+
103+
#[test]
104+
fn errors() {
105+
#[track_caller]
106+
fn case(s: &str, err: &str) {
107+
assert_eq!(
108+
Bech32Decoder::new(Bech32Type::PublicKey, &checksum(s))
109+
.and_then(Bech32Decoder::byte_array::<1>)
110+
.unwrap_err()
111+
.to_string(),
112+
err,
113+
);
114+
}
115+
116+
case(
117+
"foo1",
118+
"expected bech32 human-readable part `public1...` but found `foo1...`",
119+
);
120+
121+
case("public1c", "bech32 public key version `c` not supported");
122+
123+
case("public1a", "bech32 public key truncated");
124+
125+
case("public1aqqq", "bech32 public key overlong by 1 character");
126+
127+
case("public1aql", "bech32 public key has nonzero padding");
128+
}
129+
102130
#[test]
103131
fn length() {
104132
#[track_caller]

src/bech32_error.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,13 @@ pub enum Bech32Error {
1313
ty.hrp(),
1414
))]
1515
Hrp { ty: Bech32Type, actual: crate::Hrp },
16-
#[snafu(display("bech32 {ty} overlong by {}", Count(*excess, "characters")))]
16+
#[snafu(display("bech32 {ty} overlong by {}", Count(*excess, "character")))]
1717
Overlong { excess: usize, ty: Bech32Type },
18-
#[snafu(display("bech32 {ty} has invalid padding"))]
19-
Padding {
20-
ty: Bech32Type,
21-
source: PaddingError,
22-
},
18+
#[snafu(display("bech32 {ty} has nonzero padding"))]
19+
Padding { ty: Bech32Type },
2320
#[snafu(display("bech32 {ty} truncated"))]
2421
Truncated { ty: Bech32Type },
25-
#[snafu(display("bech32 {ty} version `{version}` is not supported"))]
22+
#[snafu(display("bech32 {ty} version `{version}` not supported"))]
2623
UnsupportedVersion {
2724
ty: Bech32Type,
2825
version: bech32::Fe32,

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ use {
6666
},
6767
bech32::{
6868
ByteIterExt, Fe32, Fe32IterExt, Hrp,
69-
primitives::decode::{CheckedHrpstring, CheckedHrpstringError, PaddingError},
69+
primitives::decode::{CheckedHrpstring, CheckedHrpstringError},
7070
},
7171
blake3::Hasher,
7272
camino::{Utf8Component, Utf8Path, Utf8PathBuf},

0 commit comments

Comments
 (0)