|
|
|
|
@ -477,6 +477,7 @@ fn mime_smtp_parse_line(
|
|
|
|
|
ctx.filename.clear();
|
|
|
|
|
ctx.headers.truncate(ctx.main_headers_nb);
|
|
|
|
|
ctx.encoding = MimeSmtpEncoding::Plain;
|
|
|
|
|
ctx.bufeolen = 0;
|
|
|
|
|
if i.len() >= b.len() + 2 && i[b.len()] == b'-' && i[b.len() + 1] == b'-' {
|
|
|
|
|
ctx.boundaries.pop();
|
|
|
|
|
}
|
|
|
|
|
@ -571,17 +572,49 @@ fn mime_smtp_parse_line(
|
|
|
|
|
if i.len() > MAX_ENC_LINE_LEN {
|
|
|
|
|
warnings |= MIME_ANOM_LONG_ENC_LINE;
|
|
|
|
|
}
|
|
|
|
|
let mut c = 0;
|
|
|
|
|
let mut c = 0usize;
|
|
|
|
|
let mut eol_equal = false;
|
|
|
|
|
let mut quoted_buffer = Vec::with_capacity(i.len());
|
|
|
|
|
if ctx.bufeolen > 0 && ctx.bufeol[0] == b'=' {
|
|
|
|
|
// we were escaping
|
|
|
|
|
if i.len() >= 2 {
|
|
|
|
|
let (h1, h2) = if ctx.bufeolen == 1 {
|
|
|
|
|
(i[0], i[1])
|
|
|
|
|
} else {
|
|
|
|
|
(ctx.bufeol[1], i[0])
|
|
|
|
|
};
|
|
|
|
|
if let Some(v) = hex(h1) {
|
|
|
|
|
if let Some(v2) = hex(h2) {
|
|
|
|
|
quoted_buffer.push((v << 4) | v2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if quoted_buffer.is_empty() {
|
|
|
|
|
warnings |= MIME_ANOM_INVALID_QP;
|
|
|
|
|
}
|
|
|
|
|
c = 3 - ctx.bufeolen as usize;
|
|
|
|
|
ctx.bufeolen = 0;
|
|
|
|
|
} else if ctx.bufeolen > 0 {
|
|
|
|
|
quoted_buffer.extend_from_slice(&ctx.bufeol[..ctx.bufeolen as usize]);
|
|
|
|
|
ctx.bufeolen = 0;
|
|
|
|
|
}
|
|
|
|
|
while c < i.len() {
|
|
|
|
|
if i[c] == b'=' {
|
|
|
|
|
if c == i.len() - 1 {
|
|
|
|
|
if c == i.len() - 1 && full.len() > i.len() {
|
|
|
|
|
eol_equal = true;
|
|
|
|
|
break;
|
|
|
|
|
} else if c + 2 >= i.len() {
|
|
|
|
|
// log event ?
|
|
|
|
|
warnings |= MIME_ANOM_INVALID_QP;
|
|
|
|
|
if full.len() > i.len() {
|
|
|
|
|
// log event ?
|
|
|
|
|
warnings |= MIME_ANOM_INVALID_QP;
|
|
|
|
|
} else {
|
|
|
|
|
// keep in state the bytes to unescape
|
|
|
|
|
ctx.bufeolen = (i.len() - c) as u8;
|
|
|
|
|
ctx.bufeol[0] = b'=';
|
|
|
|
|
if ctx.bufeolen == 2 {
|
|
|
|
|
ctx.bufeol[1] = i[c + 1];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if let Some(v) = hex(i[c + 1]) {
|
|
|
|
|
@ -599,7 +632,13 @@ fn mime_smtp_parse_line(
|
|
|
|
|
c += 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if !eol_equal {
|
|
|
|
|
if i.is_empty() {
|
|
|
|
|
ctx.bufeolen = (full.len() - i.len()) as u8;
|
|
|
|
|
if ctx.bufeolen > 0 {
|
|
|
|
|
ctx.bufeol[..ctx.bufeolen as usize]
|
|
|
|
|
.copy_from_slice(&full[i.len()..]);
|
|
|
|
|
}
|
|
|
|
|
} else if !eol_equal {
|
|
|
|
|
quoted_buffer.extend_from_slice(&full[i.len()..]);
|
|
|
|
|
}
|
|
|
|
|
mime_smtp_find_url_strings(ctx, "ed_buffer);
|
|
|
|
|
@ -679,7 +718,11 @@ pub unsafe extern "C" fn SCMimeSmtpGetHeader(
|
|
|
|
|
let name: &CStr = CStr::from_ptr(str); //unsafe
|
|
|
|
|
|
|
|
|
|
// Convert to lowercase, mime::slice_equals_lowercase expects it.
|
|
|
|
|
let name: Vec<u8> = name.to_bytes().iter().map(|b| b.to_ascii_lowercase()).collect();
|
|
|
|
|
let name: Vec<u8> = name
|
|
|
|
|
.to_bytes()
|
|
|
|
|
.iter()
|
|
|
|
|
.map(|b| b.to_ascii_lowercase())
|
|
|
|
|
.collect();
|
|
|
|
|
for h in &ctx.headers[ctx.main_headers_nb..] {
|
|
|
|
|
if mime::slice_equals_lowercase(&h.name, &name) {
|
|
|
|
|
*buffer = h.value.as_ptr();
|
|
|
|
|
|