Commit 2621dd42 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

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
parent 2c8c4661
Loading
Loading
Loading
Loading
+27 −26
Original line number Diff line number Diff line
@@ -1661,12 +1661,23 @@ 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;
  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;
    }

    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)) {
    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
@@ -1674,22 +1685,12 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, ssize_t nread)
      */
      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;
      }
    }
    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;
      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) {