Skip to content

Commit

Permalink
Correct BinHex 4.0 alphabet according to specifications
Browse files Browse the repository at this point in the history
# Description

This pull request addresses an inconsistency between the source code and the [BinHex 4.0 specifications](https://files.stairways.com/other/binhex-40-specs-info.txt). Specifically, the variable `BIN_HEX` in [`alphabet.rs`](https://github.com/marshallpierce/rust-base64/blob/bf15ccf30af8bb6b1f326fffa025d7b0aaa3342f/src/alphabet.rs#L201C1-L206C3) and corrects it to align with the specs.

# Changes

```diff
pub const BIN_HEX: Alphabet = Alphabet::from_str_unchecked(
-    "!\"#$%&'()*+,-0123456789@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdehijklmpqr",
+    "!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr",
);
```

The new addition includes the character `f` and excludes the character `7`, as per the spec.

# References

- [BinHex 4.0 Definition](https://files.stairways.com/other/binhex-40-specs-info.txt)
- [RFC 1741 - MIME Content Type for BinHex Encoded Files](https://www.rfc-editor.org/rfc/rfc1741.txt)
- [MacMIME - How to send Macintosh files with MIME](https://www.iana.org/assignments/media-types/application/applefile)

# Misc

```rust
#[cfg(test)]
mod tests {
    use base64::{
        alphabet::{self, Alphabet, ParseAlphabetError},
        engine::{self, GeneralPurposeConfig},
        Engine,
    };

    const BIN_HEX_NEW: Result<Alphabet, ParseAlphabetError> = alphabet::Alphabet::new(
        "!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr",
    );

    const ENGINE_CONFIG: GeneralPurposeConfig = engine::GeneralPurposeConfig::new()
        .with_decode_allow_trailing_bits(true)
        .with_encode_padding(false)
        .with_decode_padding_mode(engine::DecodePaddingMode::RequireNone);

    const SAMPLE_INPUT: &str = "Hello, world!";
    const EXPECTED_ENCODED_OUTPUT: &str = "5'9XE'mX)(G[FQaN)3";

    #[test]
    fn src_encode() {
        let engine_src = engine::GeneralPurpose::new(&alphabet::BIN_HEX, ENGINE_CONFIG);
        let res_enc = engine_src.encode(SAMPLE_INPUT);

        assert_eq!(res_enc, EXPECTED_ENCODED_OUTPUT);
    }

    #[test]
    fn src_decode() {
        let engine_src = engine::GeneralPurpose::new(&alphabet::BIN_HEX, ENGINE_CONFIG);
        let res_dec = engine_src.decode(EXPECTED_ENCODED_OUTPUT).unwrap();

        assert_eq!(res_dec, SAMPLE_INPUT.as_bytes());
    }

    #[test]
    fn new_encode() {
        let engine_new = engine::GeneralPurpose::new(&BIN_HEX_NEW.unwrap(), ENGINE_CONFIG);
        let res_enc = engine_new.encode(SAMPLE_INPUT);

        assert_eq!(res_enc, EXPECTED_ENCODED_OUTPUT);
    }

    #[test]
    fn new_decode() {
        let engine_new = engine::GeneralPurpose::new(&BIN_HEX_NEW.unwrap(), ENGINE_CONFIG);
        let res_dec = engine_new.decode(EXPECTED_ENCODED_OUTPUT).unwrap();

        assert_eq!(res_dec, SAMPLE_INPUT.as_bytes());
    }
}
```

Output

```sh
running 4 tests
test tests::new_encode ... ok
test tests::new_decode ... ok
test tests::src_decode ... FAILED
test tests::src_encode ... FAILED

failures:

---- tests::src_decode stdout ----
thread 'tests::src_decode' panicked at src\main.rs:34:9:
assertion `left == right` failed
  left: [72, 101, 173, 112, 111, 45, 32, 119, 176, 118, 124, 165, 33]
 right: [72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33]
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

---- tests::src_encode stdout ----
thread 'tests::src_encode' panicked at src\main.rs:26:9:
assertion `left == right` failed
  left: "5'8VD'mV)(FZEP`M)3"
 right: "5'9XE'mX)(G[FQaN)3"


failures:
    tests::src_decode
    tests::src_encode

test result: FAILED. 2 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
```
  • Loading branch information
jobansd committed Apr 30, 2024
1 parent bf15ccf commit 838355e
Showing 1 changed file with 1 addition and 1 deletion.
2 changes: 1 addition & 1 deletion src/alphabet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ pub const IMAP_MUTF7: Alphabet = Alphabet::from_str_unchecked(
///
/// See [BinHex 4.0 Definition](http://files.stairways.com/other/binhex-40-specs-info.txt)
pub const BIN_HEX: Alphabet = Alphabet::from_str_unchecked(
"!\"#$%&'()*+,-0123456789@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdehijklmpqr",
"!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr",
);

#[cfg(test)]
Expand Down

0 comments on commit 838355e

Please sign in to comment.