diff options
author | Steve Holme <steve_holme@hotmail.com> | 2014-12-12 18:37:06 +0000 |
---|---|---|
committer | Steve Holme <steve_holme@hotmail.com> | 2014-12-12 19:15:08 +0000 |
commit | f0ecdd04d3cd3c8814a296c3a9d2211086b7abd8 (patch) | |
tree | a1bb00a7c1cb804254aabc74beb4316ad3f8c01f | |
parent | 2f5c70b2b0f0fbdc1d0afcc2e148bc3e167ac6c7 (diff) |
smtp: Fixed dot stuffing when EOL characters were at end of input buffers
Fixed a problem with the CRLF. detection when multiple buffers were
used to upload an email to libcurl and the line ending character(s)
appeared at the end of each buffer. This meant any lines which started
with . would not be escaped into .. and could be interpreted as the end
of transmission string instead.
This only affected libcurl based applications that used a read function
and wasn't reproducible with the curl command-line tool.
Bug: http://curl.haxx.se/bug/view.cgi?id=1456
Assisted-by: Patrick Monnerat
-rw-r--r-- | lib/smtp.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/lib/smtp.c b/lib/smtp.c index d57e62723..5c0b0a495 100644 --- a/lib/smtp.c +++ b/lib/smtp.c @@ -2322,6 +2322,7 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread) struct SMTP *smtp = data->req.protop; char *scratch = data->state.scratch; char *oldscratch = NULL; + size_t eob_sent; /* Do we need to allocate a scratch buffer? */ if(!scratch || data->set.crlf) { @@ -2335,6 +2336,9 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread) } } + /* Have we already sent part of the EOB? */ + eob_sent = smtp->eob; + /* This loop can be improved by some kind of Boyer-Moore style of approach but that is saved for later... */ for(i = 0, si = 0; i < nread; i++) { @@ -2349,8 +2353,8 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread) } else if(smtp->eob) { /* A previous substring matched so output that first */ - memcpy(&scratch[si], SMTP_EOB, smtp->eob); - si += smtp->eob; + memcpy(&scratch[si], SMTP_EOB + eob_sent, smtp->eob - eob_sent); + si += smtp->eob - eob_sent; /* Then compare the first byte */ if(SMTP_EOB[0] == data->req.upload_fromhere[i]) @@ -2358,6 +2362,8 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread) else smtp->eob = 0; + eob_sent = 0; + /* Reset the trailing CRLF flag as there was more data */ smtp->trailing_crlf = FALSE; } @@ -2365,19 +2371,19 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread) /* Do we have a match for CRLF. as per RFC-5321, sect. 4.5.2 */ if(SMTP_EOB_FIND_LEN == smtp->eob) { /* Copy the replacement data to the target buffer */ - memcpy(&scratch[si], SMTP_EOB_REPL, SMTP_EOB_REPL_LEN); - si += SMTP_EOB_REPL_LEN; + memcpy(&scratch[si], SMTP_EOB_REPL + eob_sent, SMTP_EOB_REPL_LEN - eob_sent); + si += SMTP_EOB_REPL_LEN - eob_sent; smtp->eob = 0; + eob_sent = 0; } else if(!smtp->eob) scratch[si++] = data->req.upload_fromhere[i]; } - if(smtp->eob) { + if(smtp->eob - eob_sent) { /* A substring matched before processing ended so output that now */ - memcpy(&scratch[si], SMTP_EOB, smtp->eob); - si += smtp->eob; - smtp->eob = 0; + memcpy(&scratch[si], SMTP_EOB + eob_sent, smtp->eob - eob_sent); + si += smtp->eob - eob_sent; } /* Only use the new buffer if we replaced something */ |