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 Original line 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
  /* This loop can be improved by some kind of Boyer-Moore style of
     approach but that is saved for later... */
     approach but that is saved for later... */
  for(i = 0, si = 0; i < nread; i++, si++) {
  for(i = 0, si = 0; i < nread; i++) {
    ssize_t left = 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(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
      /* It matched, copy the replacement data to the target buffer
         instead. Note that the replacement does not contain the
         instead. Note that the replacement does not contain the
         trailing CRLF but we instead continue to match on that one
         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,
      memcpy(&data->state.scratch[si], SMTP_EOB_REPL,
             SMTP_EOB_REPL_LEN);
             SMTP_EOB_REPL_LEN);
        si += SMTP_EOB_REPL_LEN - 1; /* minus one since the for() increments
      si += SMTP_EOB_REPL_LEN;
                                        it */
      smtpc->eob = 2; /* start over at two bytes */
        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;
    }
    }
    else if(!smtpc->eob)
      data->state.scratch[si++] = data->req.upload_fromhere[i];


    data->state.scratch[si] = data->req.upload_fromhere[i];
  } /* for() */
  } /* for() */


  if(si != nread) {
  if(si != nread) {