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

cli tool: fix mime post with --disable-libcurl-option configure option

Reported-by: Marcel Raad
Fixes #3576
Closes #3583
parent d8b0318a
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -144,10 +144,10 @@ static void free_config_fields(struct OperationConfig *config)
  curl_slist_free_all(config->headers);
  curl_slist_free_all(config->proxyheaders);

  if(config->mimepost) {
    tool_mime_free(config->mimepost);
  curl_mime_free(config->mimepost);
  config->mimepost = NULL;
  }
  tool_mime_free(config->mimeroot);
  config->mimeroot = NULL;
  config->mimecurrent = NULL;

  curl_slist_free_all(config->telnet_options);
+2 −1
Original line number Diff line number Diff line
@@ -178,8 +178,9 @@ struct OperationConfig {
  curl_off_t condtime;
  struct curl_slist *headers;
  struct curl_slist *proxyheaders;
  tool_mime *mimepost;
  tool_mime *mimeroot;
  tool_mime *mimecurrent;
  curl_mime *mimepost;
  struct curl_slist *telnet_options;
  struct curl_slist *resolve;
  struct curl_slist *connect_to;
+109 −5
Original line number Diff line number Diff line
@@ -166,7 +166,6 @@ void tool_mime_free(tool_mime *mime)
      tool_mime_free(mime->subparts);
    if(mime->prev)
      tool_mime_free(mime->prev);
    curl_mime_free(mime->handle);
    CONST_SAFEFREE(mime->name);
    CONST_SAFEFREE(mime->filename);
    CONST_SAFEFREE(mime->type);
@@ -237,6 +236,109 @@ int tool_mime_stdin_seek(void *instream, curl_off_t offset, int whence)
  return CURL_SEEKFUNC_OK;
}

/* Translate an internal mime tree into a libcurl mime tree. */

static CURLcode tool2curlparts(CURL *curl, tool_mime *m, curl_mime *mime)
{
  CURLcode ret = CURLE_OK;
  curl_mimepart *part = NULL;
  curl_mime *submime = NULL;
  const char *filename = NULL;

  if(m) {
    ret = tool2curlparts(curl, m->prev, mime);
    if(!ret) {
      part = curl_mime_addpart(mime);
      if(!part)
        ret = CURLE_OUT_OF_MEMORY;
    }
    if(!ret) {
      filename = m->filename;
      switch(m->kind) {
      case TOOLMIME_PARTS:
        ret = tool2curlmime(curl, m, &submime);
        if(!ret) {
          ret = curl_mime_subparts(part, submime);
          if(ret)
            curl_mime_free(submime);
        }
        break;

      case TOOLMIME_DATA:
#ifdef CURL_DOES_CONVERSIONS
        /* Our data is always textual: convert it to ASCII. */
        {
          size_t size = strlen(m->data);
          char *cp = malloc(size + 1);

          if(!cp)
            ret = CURLE_OUT_OF_MEMORY;
          else {
            memcpy(cp, m->data, size + 1);
            ret = convert_to_network(cp, size);
            if(!ret)
              ret = curl_mime_data(part, cp, CURL_ZERO_TERMINATED);
            free(cp);
          }
        }
#else
        ret = curl_mime_data(part, m->data, CURL_ZERO_TERMINATED);
#endif
        break;

      case TOOLMIME_FILE:
      case TOOLMIME_FILEDATA:
        ret = curl_mime_filedata(part, m->data);
        if(!ret && m->kind == TOOLMIME_FILEDATA && !filename)
          ret = curl_mime_filename(part, NULL);
        break;

      case TOOLMIME_STDIN:
        if(!filename)
          filename = "-";
        /* FALLTHROUGH */
      case TOOLMIME_STDINDATA:
        ret = curl_mime_data_cb(part, m->size,
                                (curl_read_callback) tool_mime_stdin_read,
                                (curl_seek_callback) tool_mime_stdin_seek,
                                NULL, m);
        break;

      default:
        /* Other cases not possible in this context. */
        break;
      }
    }
    if(!ret && filename)
      ret = curl_mime_filename(part, filename);
    if(!ret)
      ret = curl_mime_type(part, m->type);
    if(!ret)
      ret = curl_mime_headers(part, m->headers, 0);
    if(!ret)
      ret = curl_mime_encoder(part, m->encoder);
    if(!ret)
      ret = curl_mime_name(part, m->name);
  }
  return ret;
}

CURLcode tool2curlmime(CURL *curl, tool_mime *m, curl_mime **mime)
{
  CURLcode ret = CURLE_OK;

  *mime = curl_mime_init(curl);
  if(!*mime)
    ret = CURLE_OUT_OF_MEMORY;
  else
    ret = tool2curlparts(curl, m->subparts, *mime);
  if(ret) {
    curl_mime_free(*mime);
    *mime = NULL;
  }
  return ret;
}

/*
 * helper function to get a word from form param
 * after call get_parm_word, str either point to string end
@@ -633,7 +735,7 @@ static int get_param_part(struct OperationConfig *config, char endchar,

int formparse(struct OperationConfig *config,
              const char *input,
              tool_mime **mimepost,
              tool_mime **mimeroot,
              tool_mime **mimecurrent,
              bool literal_value)
{
@@ -652,8 +754,8 @@ int formparse(struct OperationConfig *config,

  /* Allocate the main mime structure if needed. */
  if(!*mimecurrent) {
    NULL_CHECK(*mimepost, tool_mime_new_parts(NULL), 1);
    *mimecurrent = *mimepost;
    NULL_CHECK(*mimeroot, tool_mime_new_parts(NULL), 1);
    *mimecurrent = *mimeroot;
  }

  /* Make a copy we can overwrite. */
@@ -683,7 +785,7 @@ int formparse(struct OperationConfig *config,
    }
    else if(!name && !strcmp(contp, ")") && !literal_value) {
      /* Ending a multipart. */
      if(*mimecurrent == *mimepost) {
      if(*mimecurrent == *mimeroot) {
        warnf(config->global, "no multipart to terminate!\n");
        Curl_safefree(contents);
        return 6;
@@ -721,6 +823,7 @@ int formparse(struct OperationConfig *config,
                   tool_mime_new_filedata(subparts, data, TRUE, &res), 9);
        part->headers = headers;
        headers = NULL;
        part->config = config->global;
        if(res == CURLE_READ_ERROR) {
            /* An error occurred while reading stdin: if read has started,
               issue the error now. Else, delay it until processed by
@@ -758,6 +861,7 @@ int formparse(struct OperationConfig *config,
                                                &res), 15);
        part->headers = headers;
        headers = NULL;
        part->config = config->global;
        if(res == CURLE_READ_ERROR) {
            /* An error occurred while reading stdin: if read has started,
               issue the error now. Else, delay it until processed by
+2 −2
Original line number Diff line number Diff line
@@ -50,7 +50,6 @@ struct tool_mime {
  struct curl_slist *headers;   /* User-defined headers. */
  /* TOOLMIME_PARTS fields. */
  tool_mime *subparts;          /* Part's subparts. */
  curl_mime *handle;            /* Libcurl mime handle. */
  /* TOOLMIME_STDIN/TOOLMIME_STDINDATA fields. */
  curl_off_t origin;            /* Stdin read origin offset. */
  curl_off_t size;              /* Stdin data size. */
@@ -64,9 +63,10 @@ int tool_mime_stdin_seek(void *instream, curl_off_t offset, int whence);

int formparse(struct OperationConfig *config,
              const char *input,
              tool_mime **mimepost,
              tool_mime **mimeroot,
              tool_mime **mimecurrent,
              bool literal_value);
CURLcode tool2curlmime(CURL *curl, tool_mime *m, curl_mime **mime);
void tool_mime_free(tool_mime *mime);

#endif /* HEADER_CURL_TOOL_FORMPARSE_H */
+2 −2
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
 * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
@@ -1691,7 +1691,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
         to sort this out slowly and carefully */
      if(formparse(config,
                   nextarg,
                   &config->mimepost,
                   &config->mimeroot,
                   &config->mimecurrent,
                   (subletter == 's')?TRUE:FALSE)) /* 's' is literal string */
        return PARAM_BAD_USE;
Loading