Commit 9885c950 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

formpost: avoid silent snprintf() truncation

The previous use of snprintf() could make libcurl silently truncate some
input data and not report that back on overly large input, which could
make data get sent over the network in a bad format.

Example:

 $ curl --form 'a=b' -H "Content-Type: $(perl -e 'print "A"x4100')"
parent f74baaf3
Loading
Loading
Loading
Loading
+25 −10
Original line number Diff line number Diff line
@@ -845,7 +845,7 @@ static CURLcode AddFormData(struct FormData **formp,
      goto error;
    }
#endif

    if(type != FORM_DATAMEM) {
      newform->line = malloc((size_t)length+1);
      if(!newform->line) {
        result = CURLE_OUT_OF_MEMORY;
@@ -853,8 +853,15 @@ static CURLcode AddFormData(struct FormData **formp,
      }
      alloc2 = newform->line;
      memcpy(newform->line, line, (size_t)length);

      /* zero terminate for easier debugging */
      newform->line[(size_t)length]=0;
    }
    else {
      newform->line = (char *)line;
      type = FORM_DATA; /* in all other aspects this is just FORM_DATA */
    }
    newform->length = (size_t)length;
    newform->line[(size_t)length]=0; /* zero terminate for easier debugging */
  }
  else
    /* For callbacks and files we don't have any actual data so we just keep a
@@ -907,13 +914,21 @@ static CURLcode AddFormDataf(struct FormData **formp,
                             curl_off_t *size,
                             const char *fmt, ...)
{
  char s[4096];
  char *s;
  CURLcode result;
  va_list ap;
  va_start(ap, fmt);
  vsnprintf(s, sizeof(s), fmt, ap);
  s = curl_mvaprintf(fmt, ap);
  va_end(ap);

  return AddFormData(formp, FORM_DATA, s, 0, size);
  if(!s)
    return CURLE_OUT_OF_MEMORY;

  result = AddFormData(formp, FORM_DATAMEM, s, 0, size);
  if(result)
    free(s);

  return result;
}

/*
+1 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
 ***************************************************************************/

enum formtype {
  FORM_DATAMEM, /* already allocated FORM_DATA memory */
  FORM_DATA,    /* form metadata (convert to network encoding if necessary) */
  FORM_CONTENT, /* form content  (never convert) */
  FORM_CALLBACK, /* 'line' points to the custom pointer we pass to the callback