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

mime: improve unbinding top multipart from easy handle.

Also avoid dangling pointers in referencing parts.
parent dd97fd3b
Loading
Loading
Loading
Loading
+41 −10
Original line number Diff line number Diff line
@@ -1069,13 +1069,6 @@ static int mime_subparts_seek(void *instream, curl_off_t offset, int whence)
  return result;
}

static void mime_subparts_free(void *ptr)
{
  curl_mime *mime = (curl_mime *) ptr;
  curl_mime_free(mime);
}


/* Release part content. */
static void cleanup_part_content(curl_mimepart *part)
{
@@ -1094,6 +1087,30 @@ static void cleanup_part_content(curl_mimepart *part)
  part->kind = MIMEKIND_NONE;
}

static void mime_subparts_free(void *ptr)
{
  curl_mime *mime = (curl_mime *) ptr;

  if(mime && mime->parent) {
    mime->parent->freefunc = NULL;  /* Be sure we won't be called again. */
    cleanup_part_content(mime->parent);  /* Avoid dangling pointer in part. */
  }
  curl_mime_free(mime);
}

/* Do not free subparts: unbind them. This is used for the top level only. */
static void mime_subparts_unbind(void *ptr)
{
  curl_mime *mime = (curl_mime *) ptr;

  if(mime && mime->parent) {
    mime->parent->freefunc = NULL;  /* Be sure we won't be called again. */
    cleanup_part_content(mime->parent);  /* Avoid dangling pointer in part. */
    mime->parent = NULL;
  }
}


void Curl_mime_cleanpart(curl_mimepart *part)
{
  cleanup_part_content(part);
@@ -1390,8 +1407,8 @@ CURLcode curl_mime_data_cb(curl_mimepart *part, curl_off_t datasize,
}

/* Set mime part content from subparts. */
CURLcode curl_mime_subparts(curl_mimepart *part,
                            curl_mime *subparts)
CURLcode Curl_mime_set_subparts(curl_mimepart *part,
                                curl_mime *subparts, int take_ownership)
{
  if(!part)
    return CURLE_BAD_FUNCTION_ARGUMENT;
@@ -1414,7 +1431,7 @@ CURLcode curl_mime_subparts(curl_mimepart *part,
    subparts->parent = part;
    part->readfunc = mime_subparts_read;
    part->seekfunc = mime_subparts_seek;
    part->freefunc = mime_subparts_free;
    part->freefunc = take_ownership? mime_subparts_free: mime_subparts_unbind;
    part->arg = subparts;
    part->datasize = -1;
    part->kind = MIMEKIND_MULTIPART;
@@ -1423,6 +1440,11 @@ CURLcode curl_mime_subparts(curl_mimepart *part,
  return CURLE_OK;
}

CURLcode curl_mime_subparts(curl_mimepart *part, curl_mime *subparts)
{
  return Curl_mime_set_subparts(part, subparts, TRUE);
}


/* Readback from top mime. */
/* Argument is the dummy top part. */
@@ -1817,6 +1839,15 @@ void Curl_mime_cleanpart(curl_mimepart *part)
  (void) part;
}

CURLcode Curl_mime_set_subparts(curl_mimepart *part,
                                curl_mime *subparts, int take_ownership)
{
  (void) part;
  (void) subparts;
  (void) take_ownership;
  return CURLE_NOT_BUILT_IN;
}

CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
                                   const char *contenttype,
                                   const char *disposition,
+2 −0
Original line number Diff line number Diff line
@@ -122,6 +122,8 @@ struct curl_mimepart_s {
/* Prototypes. */
void Curl_mime_initpart(curl_mimepart *part, struct Curl_easy *easy);
void Curl_mime_cleanpart(curl_mimepart *part);
CURLcode Curl_mime_set_subparts(curl_mimepart *part,
                                curl_mime *subparts, int take_ownership);
CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
                                   const char *contenttype,
                                   const char *disposition,
+2 −3
Original line number Diff line number Diff line
@@ -1158,10 +1158,9 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
    /*
     * Set to make us do MIME/form POST
     */
    result = curl_mime_subparts(&data->set.mimepost,
                                va_arg(param, curl_mime *));
    result = Curl_mime_set_subparts(&data->set.mimepost,
                                    va_arg(param, curl_mime *), FALSE);
    if(!result) {
      data->set.mimepost.freefunc = NULL; /* Avoid free upon easy cleanup. */
      data->set.httpreq = HTTPREQ_POST_MIME;
      data->set.opt_no_body = FALSE; /* this is implied */
    }