Skip to main content

Crate uuencoding

Crate uuencoding 

Source
Expand description

UUencoding and UUdecoding.

§Background

UUencoding (Unix-to-Unix encoding) originated in the early 1980s as a way to transfer binary files over Unix-to-Unix Copy Program (UUCP) links, which carried only 7-bit ASCII text. A begin line records the file’s Unix permission mode and filename; data lines each start with a length character followed by groups of four printable ASCII characters encoding three bytes; an end line terminates the block. The scheme predates MIME by roughly a decade and was the dominant binary-transfer mechanism on Usenet and early email networks through the early 1990s.

§Two use cases in MIME contexts

  1. CTE-declared blocks — a message part carries the header Content-Transfer-Encoding: x-uuencode (or x-uue). The part body is a single UU block; decode processes it directly.

  2. Inline blocks in text/plain — a human-composed message contains one or more UU blocks embedded in prose. scan locates each begin/end pair by offset so callers can extract and decode them individually.

§Relationship to mime-tree

mime-tree depends on this crate. This crate does not depend on mime-tree. Callers are responsible for MIME/S/MIME recursion; neither crate recurses into the other.

§Real-world tolerance

This crate tolerates common mailer mutations without requiring the caller to pre-sanitize input:

  • CRLF line endings — trailing \r is stripped from every line.
  • Trailing-space stripping — many mailers strip trailing spaces from data lines; the decoder pads short lines with 0x20 (space), which decodes to zero, matching the intended zero bits.
  • Space/backtick ambiguity for zero — both 0x20 (space) and 0x60 (backtick) are accepted as the zero-value UU character in both length and data positions.
  • Missing end line — a block whose end line was stripped is returned as DecodedBlock or ScannedBlock with is_truncated = true rather than an error, so callers receive the partial payload.

§Security note

UUencoding expands data by approximately 4/3 (three raw bytes become four encoded bytes, plus line-length overhead). Decoded output is therefore smaller than the encoded input. However, decoded bytes may represent a compressed archive (.tar.gz, .zip, .rar, etc.). Any subsequent decompression is the caller’s responsibility and must be independently guarded against decompression-bomb attacks. This crate does not decompress and does not impose size limits.

§Quick start

// Encode bytes into a UU block.
let encoded = uuencoding::encode(b"Cat", "cat.txt", 0o644);
assert_eq!(encoded, b"begin 644 cat.txt\n#0V%T\n`\nend\n");
// Decode a single UU block.
let block = uuencoding::decode(b"begin 644 hello.txt\n%2&5L;&\\ \n \nend\n").unwrap();
assert_eq!(block.data, b"Hello");
assert_eq!(block.metadata.filename, "hello.txt");
assert_eq!(block.metadata.mode, 420); // 0o644
// Scan prose text for embedded UU blocks.
let text = b"Hi Alice,\nbegin 644 note.txt\n%2&5L;&\\ \n \nend\nSee you soon.\n";
for result in uuencoding::scan(text) {
    let block = result.unwrap();
    println!("found {} bytes for {}", block.data.len(), block.metadata.filename);
}

Structs§

BlockMetadata
Metadata extracted from a UU begin line.
DecodedBlock
A successfully decoded UU block.
ScannedBlock
A UU block located and fully decoded from a larger byte slice.

Enums§

UuError
Errors produced by UUencode operations.

Functions§

decode
Decode a single UU block from input.
decode_limited
Decode a single UU block from input, stopping early once max_bytes decoded bytes have been produced.
encode
Encode data as a UU block with the given filename and Unix mode.
scan
Scan input for UU blocks, returning one entry per block found.