aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2011-10-20 00:13:09 +0200
committerDaniel Stenberg <daniel@haxx.se>2011-10-20 00:13:09 +0200
commit2621dd42a4d3e510e68f7d6a31ba325634d87ee6 (patch)
treeb13e22ce533a45a70d698cfb7cea366280bea842
parent2c8c46619b4386ecbce8104e6962852889e5e86f (diff)
Curl_smtp_escape_eob: fix EOB escaping
As the EOB string can come byte by byte over a series of writes we must match byte-wise. Bug: http://curl.haxx.se/mail/lib-2011-10/0172.html
-rw-r--r--lib/smtp.c53
1 files changed, 27 insertions, 26 deletions
diff --git a/lib/smtp.c b/lib/smtp.c
index 141b04a0c..9a34a05f7 100644
--- a/lib/smtp.c
+++ b/lib/smtp.c
@@ -1661,35 +1661,36 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, ssize_t nread)
}
/* 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++, si++) {
- ssize_t left = nread - i;
-
- if(left >= (ssize_t)(SMTP_EOB_LEN - smtpc->eob)) {
- if(!memcmp(SMTP_EOB + smtpc->eob, &data->req.upload_fromhere[i],
- SMTP_EOB_LEN - smtpc->eob)) {
- /* It matched, copy the replacement data to the target buffer
- instead. Note that the replacement does not contain the
- trailing CRLF but we instead continue to match on that one
- to deal with repeated sequences. Like CRLF.CRLF.CRLF etc
- */
- memcpy(&data->state.scratch[si], SMTP_EOB_REPL,
- SMTP_EOB_REPL_LEN);
- si += SMTP_EOB_REPL_LEN - 1; /* minus one since the for() increments
- it */
- i += SMTP_EOB_LEN - smtpc->eob - 1 - 2;
- smtpc->eob = 0; /* start over */
- continue;
- }
+ for(i = 0, si = 0; i < nread; i++) {
+
+ if(SMTP_EOB[smtpc->eob] == data->req.upload_fromhere[i])
+ smtpc->eob++;
+ else if(smtpc->eob) {
+ /* previously a substring matched, output that first */
+ memcpy(&data->state.scratch[si], SMTP_EOB, smtpc->eob);
+ si += smtpc->eob;
+
+ /* then compare the first byte */
+ if(SMTP_EOB[smtpc->eob] == data->req.upload_fromhere[i])
+ smtpc->eob=1;
+ else
+ smtpc->eob = 0;
}
- else if(!memcmp(SMTP_EOB + smtpc->eob, &data->req.upload_fromhere[i],
- left)) {
- /* the last piece of the data matches the EOB so we can't send that
- until we know the rest of it */
- smtpc->eob += left;
- break;
+
+ if(SMTP_EOB_LEN == smtpc->eob) {
+ /* It matched, copy the replacement data to the target buffer
+ instead. Note that the replacement does not contain the
+ trailing CRLF but we instead continue to match on that one
+ to deal with repeated sequences. Like CRLF.CRLF.CRLF etc
+ */
+ memcpy(&data->state.scratch[si], SMTP_EOB_REPL,
+ SMTP_EOB_REPL_LEN);
+ si += SMTP_EOB_REPL_LEN;
+ smtpc->eob = 2; /* start over at two bytes */
}
+ else if(!smtpc->eob)
+ data->state.scratch[si++] = data->req.upload_fromhere[i];
- data->state.scratch[si] = data->req.upload_fromhere[i];
} /* for() */
if(si != nread) {