melib: fix minor header parsing errors
- set_subject checked if last byte was control character instead of last character. Characters can be multi-byte, duh. - email::parser::date didn't provide for Date values that had -0000 instead of +0000 (that's a chrono requirement/bug)async
parent
81c70b0136
commit
7732b851e6
|
@ -719,7 +719,7 @@ named!(
|
|||
let mut env = Envelope::new(0);
|
||||
if let Some(date) = date {
|
||||
env.set_date(&date);
|
||||
if let Some(d) = crate::email::parser::date(env.date_as_str().as_bytes()) {
|
||||
if let Ok(d) = crate::email::parser::date(env.date_as_str().as_bytes()) {
|
||||
env.set_datetime(d);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ pub struct Envelope {
|
|||
to: Vec<Address>,
|
||||
cc: Vec<Address>,
|
||||
bcc: Vec<Address>,
|
||||
subject: Option<Vec<u8>>,
|
||||
subject: Option<String>,
|
||||
message_id: MessageID,
|
||||
in_reply_to: Option<MessageID>,
|
||||
references: Option<References>,
|
||||
|
@ -315,7 +315,7 @@ impl Envelope {
|
|||
if let Some(ref mut x) = in_reply_to {
|
||||
self.push_references(x);
|
||||
}
|
||||
if let Some(d) = parser::date(&self.date.as_bytes()) {
|
||||
if let Ok(d) = parser::date(&self.date.as_bytes()) {
|
||||
self.set_datetime(d);
|
||||
}
|
||||
if self.message_id.raw().is_empty() {
|
||||
|
@ -343,7 +343,7 @@ impl Envelope {
|
|||
}
|
||||
|
||||
pub fn datetime(&self) -> chrono::DateTime<chrono::FixedOffset> {
|
||||
if let Some(d) = parser::date(&self.date.as_bytes()) {
|
||||
if let Ok(d) = parser::date(&self.date.as_bytes()) {
|
||||
return d;
|
||||
}
|
||||
chrono::FixedOffset::west(0)
|
||||
|
@ -412,7 +412,7 @@ impl Envelope {
|
|||
|
||||
pub fn subject(&self) -> Cow<str> {
|
||||
match self.subject {
|
||||
Some(ref s) => String::from_utf8_lossy(s),
|
||||
Some(ref s) => Cow::from(s),
|
||||
_ => Cow::from(String::new()),
|
||||
}
|
||||
}
|
||||
|
@ -467,10 +467,13 @@ impl Envelope {
|
|||
};
|
||||
self.in_reply_to = Some(MessageID::new(new_val, slice));
|
||||
}
|
||||
pub fn set_subject(&mut self, mut new_val: Vec<u8>) {
|
||||
pub fn set_subject(&mut self, new_val: Vec<u8>) {
|
||||
let mut new_val = String::from_utf8(new_val)
|
||||
.unwrap_or_else(|err| String::from_utf8_lossy(&err.into_bytes()).into());
|
||||
while new_val
|
||||
.chars()
|
||||
.last()
|
||||
.map(|&u| char::is_control(u as char))
|
||||
.map(|c| char::is_control(c))
|
||||
.unwrap_or(false)
|
||||
{
|
||||
new_val.pop();
|
||||
|
|
|
@ -658,13 +658,18 @@ fn eat_comments(input: &[u8]) -> Vec<u8> {
|
|||
* right now we expect input will have no extra spaces in between tokens
|
||||
*
|
||||
* We should use a custom parser here*/
|
||||
pub fn date(input: &[u8]) -> Option<chrono::DateTime<chrono::FixedOffset>> {
|
||||
let parsed_result = phrase(&eat_comments(input))
|
||||
.to_full_result()
|
||||
.unwrap()
|
||||
.replace(b"-", b"+");
|
||||
chrono::DateTime::parse_from_rfc2822(String::from_utf8_lossy(parsed_result.trim()).as_ref())
|
||||
.ok()
|
||||
pub fn date(input: &[u8]) -> Result<chrono::DateTime<chrono::FixedOffset>> {
|
||||
let mut parsed_result = phrase(&eat_comments(input)).to_full_result()?;
|
||||
if let Some(pos) = parsed_result.find(b"-0000") {
|
||||
parsed_result[pos] = b'+';
|
||||
}
|
||||
|
||||
Ok(
|
||||
chrono::DateTime::parse_from_rfc2822(
|
||||
String::from_utf8_lossy(parsed_result.trim()).as_ref(),
|
||||
)
|
||||
.map_err(|err| MeliError::new(err.to_string()))?,
|
||||
)
|
||||
}
|
||||
|
||||
named!(pub message_id<&[u8]>,
|
||||
|
@ -1052,38 +1057,48 @@ mod tests {
|
|||
let words = b"=?iso-8859-7?B?W215Y291cnNlcy5udHVhLmdyIC0gyvXs4fTp6t4g6uHpIMri4e306ere?=
|
||||
=?iso-8859-7?B?INb18+nq3l0gzd3hIMHt4erv3+358+c6IMzF0c/TIMHQz9TFy8XTzMHU?=
|
||||
=?iso-8859-7?B?2c0gwiDUzC4gysHNLiDFzsXUwdPH0yAyMDE3LTE4OiDTx8zFydnTxw==?=";
|
||||
assert!("[mycourses.ntua.gr - Κυματική και Κβαντική Φυσική] Νέα Ανακοίνωση: ΜΕΡΟΣ ΑΠΟΤΕΛΕΣΜΑΤΩΝ Β ΤΜ. ΚΑΝ. ΕΞΕΤΑΣΗΣ 2017-18: ΣΗΜΕΙΩΣΗ" == std::str::from_utf8(&phrase(words.trim()).to_full_result().unwrap()).unwrap());
|
||||
assert_eq!("[mycourses.ntua.gr - Κυματική και Κβαντική Φυσική] Νέα Ανακοίνωση: ΜΕΡΟΣ ΑΠΟΤΕΛΕΣΜΑΤΩΝ Β ΤΜ. ΚΑΝ. ΕΞΕΤΑΣΗΣ 2017-18: ΣΗΜΕΙΩΣΗ" , std::str::from_utf8(&phrase(words.trim()).to_full_result().unwrap()).unwrap());
|
||||
let words = b"=?UTF-8?Q?=CE=A0=CF=81=CF=8C=CF=83=CE=B8=CE=B5?= =?UTF-8?Q?=CF=84=CE=B7_=CE=B5=CE=BE=CE=B5=CF=84?= =?UTF-8?Q?=CE=B1=CF=83=CF=84=CE=B9=CE=BA=CE=AE?=";
|
||||
assert!(
|
||||
"Πρόσθετη εξεταστική"
|
||||
== std::str::from_utf8(&phrase(words.trim()).to_full_result().unwrap()).unwrap()
|
||||
assert_eq!(
|
||||
"Πρόσθετη εξεταστική",
|
||||
std::str::from_utf8(&phrase(words.trim()).to_full_result().unwrap()).unwrap()
|
||||
);
|
||||
let words = b"[Advcomparch] =?utf-8?b?zqPPhc68z4DOtc+BzrnPhs6/z4HOrCDPg861IGZs?=\n\t=?utf-8?b?dXNoIM67z4zOs8+JIG1pc3ByZWRpY3Rpb24gzrrOsc+Ezqwgz4TOt869?=\n\t=?utf-8?b?IM61zrrPhM6tzrvOtc+Dzrcgc3RvcmU=?=";
|
||||
assert!(
|
||||
"[Advcomparch] Συμπεριφορά σε flush λόγω misprediction κατά την εκτέλεση store"
|
||||
== std::str::from_utf8(&phrase(words.trim()).to_full_result().unwrap()).unwrap()
|
||||
assert_eq!(
|
||||
"[Advcomparch] Συμπεριφορά σε flush λόγω misprediction κατά την εκτέλεση store",
|
||||
std::str::from_utf8(&phrase(words.trim()).to_full_result().unwrap()).unwrap()
|
||||
);
|
||||
let words = b"Re: [Advcomparch] =?utf-8?b?zqPPhc68z4DOtc+BzrnPhs6/z4HOrCDPg861IGZs?=
|
||||
=?utf-8?b?dXNoIM67z4zOs8+JIG1pc3ByZWRpY3Rpb24gzrrOsc+Ezqwgz4TOt869?=
|
||||
=?utf-8?b?IM61zrrPhM6tzrvOtc+Dzrcgc3RvcmU=?=";
|
||||
assert!(
|
||||
"Re: [Advcomparch] Συμπεριφορά σε flush λόγω misprediction κατά την εκτέλεση store"
|
||||
== std::str::from_utf8(&phrase(words.trim()).to_full_result().unwrap()).unwrap()
|
||||
assert_eq!(
|
||||
"Re: [Advcomparch] Συμπεριφορά σε flush λόγω misprediction κατά την εκτέλεση store",
|
||||
std::str::from_utf8(&phrase(words.trim()).to_full_result().unwrap()).unwrap()
|
||||
);
|
||||
let words = b"sdf";
|
||||
assert!("sdf" == std::str::from_utf8(&phrase(words).to_full_result().unwrap()).unwrap());
|
||||
assert_eq!(
|
||||
"sdf",
|
||||
std::str::from_utf8(&phrase(words).to_full_result().unwrap()).unwrap()
|
||||
);
|
||||
let words = b"=?iso-8859-7?b?U2VnIGZhdWx0IPP05+0g5er03evl8+cg9O/1?= =?iso-8859-7?q?_example_ru_n_=5Fsniper?=";
|
||||
assert!(
|
||||
"Seg fault στην εκτέλεση του example ru n _sniper"
|
||||
== std::str::from_utf8(&phrase(words).to_full_result().unwrap()).unwrap()
|
||||
assert_eq!(
|
||||
"Seg fault στην εκτέλεση του example ru n _sniper",
|
||||
std::str::from_utf8(&phrase(words).to_full_result().unwrap()).unwrap()
|
||||
);
|
||||
let words = b"Re: [Advcomparch]
|
||||
=?iso-8859-7?b?U2VnIGZhdWx0IPP05+0g5er03evl8+cg9O/1?=
|
||||
=?iso-8859-7?q?_example_ru_n_=5Fsniper?=";
|
||||
|
||||
assert!(
|
||||
"Re: [Advcomparch] Seg fault στην εκτέλεση του example ru n _sniper"
|
||||
== std::str::from_utf8(&phrase(words).to_full_result().unwrap()).unwrap()
|
||||
assert_eq!(
|
||||
"Re: [Advcomparch] Seg fault στην εκτέλεση του example ru n _sniper",
|
||||
std::str::from_utf8(&phrase(words).to_full_result().unwrap()).unwrap()
|
||||
);
|
||||
|
||||
let words = r#"[internal] =?UTF-8?B?zp3Orc6/z4Igzp/OtM63zrPPjM+CIM6jz4XOs86zz4E=?=
|
||||
=?UTF-8?B?zrHPhs6uz4I=?="#;
|
||||
assert_eq!(
|
||||
"[internal] Νέος Οδηγός Συγγραφής",
|
||||
std::str::from_utf8(&phrase(words.as_bytes()).to_full_result().unwrap()).unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue