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
This commit is contained in:
parent
2f5c70b2b0
commit
f0ecdd04d3
22
lib/smtp.c
22
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user