diff options
author | Daniel Stenberg <daniel@haxx.se> | 2011-10-20 00:13:09 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2011-10-20 00:13:09 +0200 |
commit | 2621dd42a4d3e510e68f7d6a31ba325634d87ee6 (patch) | |
tree | b13e22ce533a45a70d698cfb7cea366280bea842 | |
parent | 2c8c46619b4386ecbce8104e6962852889e5e86f (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.c | 53 |
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) { |