Commit f009bbe1 authored by Patrick Monnerat's avatar Patrick Monnerat
Browse files

curl_easy_reset: release mime-related data.

Move curl_mime_initpart() and curl_mime_cleanpart() calls to lower-level
functions dealing with UserDefined structure contents.
This avoids memory leakages on curl-generated part mime headers.
New test 2073 checks this using the cli tool --next option: it
triggers a valgrind error if bug is present.

Bug: https://curl.haxx.se/mail/lib-2017-12/0060.html
Reported-by: Martin Galvan
parent 4acc9d3d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -998,7 +998,7 @@ void curl_easy_reset(struct Curl_easy *data)
  /* zero out UserDefined data: */
  Curl_freeset(data);
  memset(&data->set, 0, sizeof(struct UserDefined));
  (void)Curl_init_userdefined(&data->set);
  (void)Curl_init_userdefined(data);

  /* zero out Progress data: */
  memset(&data->progress, 0, sizeof(struct Progress));
+7 −6
Original line number Diff line number Diff line
@@ -293,6 +293,8 @@ void Curl_freeset(struct Curl_easy *data)
    data->change.url_alloc = FALSE;
  }
  data->change.url = NULL;

  Curl_mime_cleanpart(&data->set.mimepost);
}

/*
@@ -382,8 +384,6 @@ CURLcode Curl_close(struct Curl_easy *data)
  Curl_http2_cleanup_dependencies(data);
  Curl_convert_close(data);

  Curl_mime_cleanpart(&data->set.mimepost);

  /* No longer a dirty share, if it exists */
  if(data->share) {
    Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
@@ -402,8 +402,9 @@ CURLcode Curl_close(struct Curl_easy *data)
 * Initialize the UserDefined fields within a Curl_easy.
 * This may be safely called on a new or existing Curl_easy.
 */
CURLcode Curl_init_userdefined(struct UserDefined *set)
CURLcode Curl_init_userdefined(struct Curl_easy *data)
{
  struct UserDefined *set = &data->set;
  CURLcode result = CURLE_OK;

  set->out = stdout; /* default output to stdout */
@@ -453,6 +454,8 @@ CURLcode Curl_init_userdefined(struct UserDefined *set)
  /* make libcurl quiet by default: */
  set->hide_progress = TRUE;  /* CURLOPT_NOPROGRESS changes these */

  Curl_mime_initpart(&set->mimepost, data);

  /*
   * libcurl 7.10 introduced SSL verification *by default*! This needs to be
   * switched off unless wanted.
@@ -569,15 +572,13 @@ CURLcode Curl_open(struct Curl_easy **curl)
    result = CURLE_OUT_OF_MEMORY;
  }
  else {
    Curl_mime_initpart(&data->set.mimepost, data);

    data->state.headerbuff = malloc(HEADERSIZE);
    if(!data->state.headerbuff) {
      DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n"));
      result = CURLE_OUT_OF_MEMORY;
    }
    else {
      result = Curl_init_userdefined(&data->set);
      result = Curl_init_userdefined(data);

      data->state.headersize = HEADERSIZE;
      Curl_convert_init(data);
+1 −1
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@

CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn);
CURLcode Curl_open(struct Curl_easy **curl);
CURLcode Curl_init_userdefined(struct UserDefined *set);
CURLcode Curl_init_userdefined(struct Curl_easy *data);
CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
                     va_list arg);
CURLcode Curl_dupset(struct Curl_easy * dst, struct Curl_easy * src);
+1 −1
Original line number Diff line number Diff line
@@ -189,4 +189,4 @@ test2048 test2049 test2050 test2051 test2052 test2053 test2054 test2055 \
test2056 test2057 test2058 test2059 test2060 test2061 test2062 test2063 \
test2064 test2065 test2066 test2067 test2068 test2069 \
\
test2070 test2071 test2072
test2070 test2071 test2072 test2073

tests/data/test2073

0 → 100644
+68 −0
Original line number Diff line number Diff line
<testcase>
<info>
<keywords>
HTTP
HTTP FORMPOST
</keywords>
</info>
#
# Server-side
<reply>
<data>
HTTP/1.1 200 OK
Date: Thu, 09 Nov 2010 14:49:00 GMT
Content-Length: 10

contents1
</data>
<data1>
HTTP/1.1 200 OK
Date: Thu, 09 Nov 2010 14:49:00 GMT
Content-Length: 10

contents2
</data1>
</reply>

#
# Client-side
<client>
<server>
http
</server>
 <name>
HTTP form posts with handle reset
 </name>
 <command>
http://%HOSTIP:%HTTPPORT/2073 -F 'name=a;filename=a.pdf' --next http://%HOSTIP:%HTTPPORT/2073 -F 'name=b;filename=b.jpg'
</command>
</client>

#
# Verify data after the test has been "shot"
<verify>
<strip>
^(User-Agent:|Content-Type: multipart/form-data;|------------).*
</strip>
<protocol>
POST /2073 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Accept: */*
Content-Length: 189

Content-Disposition: form-data; name="name"; filename="a.pdf"
Content-Type: application/pdf

a
POST /2073 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Accept: */*
Content-Length: 184

Content-Disposition: form-data; name="name"; filename="b.jpg"
Content-Type: image/jpeg

b
</protocol>
</verify>
</testcase>