summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Korber <philippkorber@gmail.com>2019-02-14 20:13:54 +0100
committerPhilipp Korber <philippkorber@gmail.com>2019-02-14 20:33:09 +0100
commit64433a447edee225e7910320987e73f9aee932af (patch)
tree9b01a03541c5649283409eca2684f70fef4c41e8
parent84122098aad7083caaaffd83ac606c7d5db74491 (diff)
fix(internals): Fixed bug where linebrakig could panic.
-rw-r--r--headers/src/header_components/unstructured.rs12
-rw-r--r--internals/src/encoder/mod.rs26
2 files changed, 25 insertions, 13 deletions
diff --git a/headers/src/header_components/unstructured.rs b/headers/src/header_components/unstructured.rs
index 84a4912..76d1da6 100644
--- a/headers/src/header_components/unstructured.rs
+++ b/headers/src/header_components/unstructured.rs
@@ -191,4 +191,16 @@ mod test {
MarkFWS,
Text " \t "
]}
+
+ ec_test!{ long_mixed_input, {
+ Unstructured::try_from("Subject: …. AAAAAAAAAAAAAAAAAAA….. AA…")?
+ } => ascii => [
+ Text "Subject:",
+ MarkFWS,
+ Text " =?utf8?Q?=E2=80=A6=2E?=",
+ MarkFWS,
+ Text " =?utf8?Q?AAAAAAAAAAAAAAAAAAA=E2=80=A6=2E=2E?=",
+ MarkFWS,
+ Text " =?utf8?Q?AA=E2=80=A6?="
+ ]}
} \ No newline at end of file
diff --git a/internals/src/encoder/mod.rs b/internals/src/encoder/mod.rs
index 52a9fb2..b7703e5 100644
--- a/internals/src/encoder/mod.rs
+++ b/internals/src/encoder/mod.rs
@@ -47,6 +47,9 @@ pub const LINE_LEN_SOFT_LIMIT: usize = 78;
/// as specified in RFC 5322 (mail) + RFC 5321 (smtp) not including CRLF
pub const LINE_LEN_HARD_LIMIT: usize = 998;
+pub const NEWLINE: &str = "\r\n";
+pub const NEWLINE_WITH_SPACE: &str = "\r\n ";
+
/// EncodingBuffer for a Mail providing a buffer for encodable traits.
pub struct EncodingBuffer {
@@ -113,7 +116,7 @@ impl EncodingBuffer {
pub fn write_blank_line(&mut self) {
//TODO/BENCH push_str vs. extends(&[u8])
- self.buffer.extend("\r\n".as_bytes());
+ self.buffer.extend(NEWLINE.as_bytes());
#[cfg(feature="traceing")]
{ self.trace.push(TraceToken::BlankLine); }
}
@@ -122,8 +125,8 @@ impl EncodingBuffer {
pub fn write_body_unchecked(&mut self, body: &impl AsRef<[u8]>) {
let slice = body.as_ref();
self.buffer.extend(slice);
- if !slice.ends_with(b"\r\n") {
- self.buffer.extend(b"\r\n");
+ if !slice.ends_with(NEWLINE.as_bytes()) {
+ self.buffer.extend(NEWLINE.as_bytes());
}
}
@@ -648,20 +651,17 @@ impl<'inner> EncodingWriter<'inner> {
fn break_line_on_fws(&mut self) -> bool {
if self.content_before_fws && self.last_fws_idx > self.line_start_idx {
- //INDEX_SAFE: self.content_before_fws is only true if there is at last one char
- // if so self.last_ws_idx does not point at the end of the buffer but inside
- let newline = match self.buffer[self.last_fws_idx] {
- b' ' | b'\t' => "\r\n",
- _ => "\r\n "
- };
+
+ let newline = self.buffer.get(self.last_fws_idx)
+ .map(|bch| match bch {
+ b' ' | b'\t' => NEWLINE,
+ _ => NEWLINE_WITH_SPACE
+ })
+ .unwrap_or(NEWLINE_WITH_SPACE);
vec_insert_bytes(&mut self.buffer, self.last_fws_idx, newline.as_bytes());
self.line_start_idx = self.last_fws_idx + 2;
- // no need last_fws can be < line_start but
- //self.last_fws_idx = self.line_start_idx;
self.content_before_fws = false;
- // stays the same:
- //self.content_since_fws = self.content_since_fws
true
} else {
false