Skip to content

Commit 44e605e

Browse files
committed
Check std::io::Write encoded string is not too long
As we did for encoding to a foramtter, before encoding to a `std::io::Write` writer, check that we do not exceed the spec limit of 90 characters.
1 parent 3e6ecff commit 44e605e

File tree

1 file changed

+54
-3
lines changed

1 file changed

+54
-3
lines changed

src/lib.rs

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ pub fn encode_to_writer<Ck: Checksum, W: std::io::Write>(
314314
w: &mut W,
315315
hrp: Hrp,
316316
data: &[u8],
317-
) -> Result<(), std::io::Error> {
317+
) -> Result<(), IoEncodeError> {
318318
encode_lower_to_writer::<Ck, W>(w, hrp, data)
319319
}
320320

@@ -328,7 +328,9 @@ pub fn encode_lower_to_writer<Ck: Checksum, W: std::io::Write>(
328328
w: &mut W,
329329
hrp: Hrp,
330330
data: &[u8],
331-
) -> Result<(), std::io::Error> {
331+
) -> Result<(), IoEncodeError> {
332+
let _ = encoded_length::<Ck>(&hrp, data)?;
333+
332334
let iter = data.iter().copied().bytes_to_fes();
333335
let chars = iter.with_checksum::<Ck>(&hrp).chars();
334336
for c in chars {
@@ -347,7 +349,9 @@ pub fn encode_upper_to_writer<Ck: Checksum, W: std::io::Write>(
347349
w: &mut W,
348350
hrp: Hrp,
349351
data: &[u8],
350-
) -> Result<(), std::io::Error> {
352+
) -> Result<(), IoEncodeError> {
353+
let _ = encoded_length::<Ck>(&hrp, data)?;
354+
351355
let iter = data.iter().copied().bytes_to_fes();
352356
let chars = iter.with_checksum::<Ck>(&hrp).chars();
353357
for c in chars {
@@ -506,6 +510,53 @@ impl From<fmt::Error> for EncodeError {
506510
fn from(e: fmt::Error) -> Self { Self::Fmt(e) }
507511
}
508512

513+
/// An error while encoding an address to a `std::io` writer.
514+
#[cfg(feature = "std")]
515+
#[derive(Debug)]
516+
#[non_exhaustive]
517+
pub enum IoEncodeError {
518+
/// Encoding HRP and data into a bech32 string exceeds the spec limit of 90 characters.
519+
TooLong(EncodedLengthError),
520+
/// Error encoding to writer.
521+
Write(std::io::Error),
522+
}
523+
524+
#[cfg(feature = "std")]
525+
impl fmt::Display for IoEncodeError {
526+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
527+
use IoEncodeError::*;
528+
529+
match *self {
530+
TooLong(ref e) => write_err!(f, "encoded string too long"; e),
531+
Write(ref e) => write_err!(f, "error encoding to writer"; e),
532+
}
533+
}
534+
}
535+
536+
#[cfg(feature = "std")]
537+
impl std::error::Error for IoEncodeError {
538+
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
539+
use IoEncodeError::*;
540+
541+
match *self {
542+
TooLong(ref e) => Some(e),
543+
Write(ref e) => Some(e),
544+
}
545+
}
546+
}
547+
548+
#[cfg(feature = "std")]
549+
impl From<EncodedLengthError> for IoEncodeError {
550+
#[inline]
551+
fn from(e: EncodedLengthError) -> Self { Self::TooLong(e) }
552+
}
553+
554+
#[cfg(feature = "std")]
555+
impl From<std::io::Error> for IoEncodeError {
556+
#[inline]
557+
fn from(e: std::io::Error) -> Self { Self::Write(e) }
558+
}
559+
509560
/// Encoding bech32 string exceeds the spec limit of 90 characters.
510561
#[derive(Debug, Clone, PartialEq, Eq)]
511562
#[non_exhaustive]

0 commit comments

Comments
 (0)