Skip to content

Commit

Permalink
Fix decoder (#5)
Browse files Browse the repository at this point in the history
* Ensure consistency
* Replace decoder algorithm
  • Loading branch information
newca12 committed Sep 26, 2022
1 parent ec6aefd commit 5ac04af
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 11 deletions.
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@ repository = "https://github.com/iam-medvedev/rust-utf7-imap"
description = "Mailbox names encoder and decoder (UTF-7 IMAP RFC 3501)"
keywords = ["mailbox", "decoder", "utf7", "imap", "rfc3501"]
categories = ["parsing","encoding"]
edition = "2021"
readme = "README.md"
maintenance = { status = "passively-maintained" }

[dependencies]
regex = "1.5"
regex = "1.6"
base64 = "0.13"
encoding_rs = "0.8"

[dev-dependencies]
proptest = "1.0.0"
7 changes: 7 additions & 0 deletions proptest-regressions/lib.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Seeds for failure cases proptest has generated in the past. It is
# automatically read and these particular cases re-run before any
# novel cases are generated.
#
# It is recommended to check this file in to source control so that
# everyone who runs the test benefits from these saved cases.
cc 120bd33aec9c1c92be0da98c789fcccae2aa09f033bc6f6600677b8e140f6bf9 # shrinks to s = "&&-"
28 changes: 18 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ extern crate encoding_rs;
extern crate regex;

use encoding_rs::UTF_16BE;
use regex::Regex;
use regex::{Captures, Regex};

/// Encode UTF-7 IMAP mailbox name
///
Expand Down Expand Up @@ -106,17 +106,16 @@ fn encode_modified_utf7(text: String) -> String {
/// assert_eq!(decode_utf7_imap(test_string), "Отправленные");
/// ```
pub fn decode_utf7_imap(text: String) -> String {
let re = Regex::new(r"&[^&-]*-").unwrap();
let mut result = text.clone();

for cap in re.captures_iter(&text) {
let encoded_text = cap.get(0).map_or("", |m| m.as_str());
let decoded_text = decode_utf7_part(String::from(encoded_text));
let pattern = Regex::new(r"&([^-]*)-").unwrap();
pattern.replace_all(&text, expand).to_string()
}

result = result.replace(&encoded_text, &decoded_text);
fn expand(cap: &Captures) -> String {
if cap.get(1).unwrap().as_str() == "" {
"&".to_string()
} else {
decode_utf7_part(cap.get(0).unwrap().as_str().to_string())
}

result
}

fn decode_utf7_part(text: String) -> String {
Expand Down Expand Up @@ -178,4 +177,13 @@ mod tests {
let test_string = String::from("th&AOkA4g-tre");
assert_eq!(decode_utf7_imap(test_string), "théâtre")
}

use proptest::prelude::*;
proptest! {
#![proptest_config(ProptestConfig::with_cases(10000))]
#[test]
fn fuzzy_dec_enc_check(s in "\\PC*") {
assert_eq!(decode_utf7_imap(encode_utf7_imap(s.clone())),s)
}
}
}

0 comments on commit 5ac04af

Please sign in to comment.