tool_formparse: tool2curlparts is no longer recursive
No binary (build failed)
—
(log yok)
| @@ -251,71 +251,103 @@ static int tool_mime_stdin_seek(void *instream, curl_off_t offset, int whence) | |
| /* Translate an internal mime tree into a libcurl mime tree. */ | |
| + | #define MAX_FORMPARTS 100000 /* arbitrarily picked */ |
| + | |
| static CURLcode tool2curlparts(CURL *curl, struct tool_mime *m, | |
| curl_mime *mime) | |
| { | |
| CURLcode result = CURLE_OK; | |
| - | curl_mimepart *part = NULL; |
| - | curl_mime *submime = NULL; |
| - | const char *filename = NULL; |
| + | struct tool_mime *curr; |
| + | struct tool_mime **nodes = NULL; |
| + | int count; |
| + | int i; |
| + | |
| + | if(!m) |
| + | return CURLE_OK; |
| + | |
| + | for(curr = m, count = 0; curr; curr = curr->prev) { |
| + | if(count > MAX_FORMPARTS) |
| + | return CURLE_BAD_FUNCTION_ARGUMENT; |
| + | count++; |
| + | } |
| - | if(m) { |
| - | result = tool2curlparts(curl, m->prev, mime); |
| - | if(!result) { |
| - | part = curl_mime_addpart(mime); |
| - | if(!part) |
| - | result = CURLE_OUT_OF_MEMORY; |
| - | } |
| - | if(!result) { |
| - | filename = m->filename; |
| - | switch(m->kind) { |
| - | case TOOLMIME_PARTS: |
| - | result = tool2curlmime(curl, m, &submime); |
| - | if(!result) { |
| - | result = curl_mime_subparts(part, submime); |
| - | if(result) |
| - | curl_mime_free(submime); |
| - | } |
| - | break; |
| + | nodes = curlx_malloc(sizeof(struct tool_mime *) * count); |
| + | if(!nodes) |
| + | return CURLE_OUT_OF_MEMORY; |
| - | case TOOLMIME_DATA: |
| - | result = curl_mime_data(part, m->data, CURL_ZERO_TERMINATED); |
| - | break; |
| + | /* populate array from the end to the beginning */ |
| + | curr = m; |
| + | for(i = count - 1; i >= 0; i--) { |
| + | nodes[i] = curr; |
| + | curr = curr->prev; |
| + | } |
| - | case TOOLMIME_FILE: |
| - | case TOOLMIME_FILEDATA: |
| - | result = curl_mime_filedata(part, m->data); |
| - | if(!result && m->kind == TOOLMIME_FILEDATA && !filename) |
| - | result = curl_mime_filename(part, NULL); |
| - | break; |
| + | for(i = 0; i < count; i++) { |
| + | struct tool_mime *node = nodes[i]; |
| + | curl_mimepart *part = NULL; |
| + | curl_mime *submime = NULL; |
| + | const char *filename = node->filename; |
| - | case TOOLMIME_STDIN: |
| - | if(!filename) |
| - | filename = "-"; |
| - | FALLTHROUGH(); |
| - | case TOOLMIME_STDINDATA: |
| - | result = curl_mime_data_cb(part, m->size, |
| - | tool_mime_stdin_read, |
| - | tool_mime_stdin_seek, |
| - | NULL, m); |
| - | break; |
| + | part = curl_mime_addpart(mime); |
| + | if(!part) { |
| + | result = CURLE_OUT_OF_MEMORY; |
| + | break; |
| + | } |
| - | default: |
| - | /* Other cases not possible in this context. */ |
| - | break; |
| + | switch(node->kind) { |
| + | case TOOLMIME_PARTS: |
| + | result = tool2curlmime(curl, node, &submime); |
| + | if(!result) { |
| + | result = curl_mime_subparts(part, submime); |
| + | if(result) |
| + | curl_mime_free(submime); |
| } | |
| + | break; |
| + | |
| + | case TOOLMIME_DATA: |
| + | result = curl_mime_data(part, node->data, CURL_ZERO_TERMINATED); |
| + | break; |
| + | |
| + | case TOOLMIME_FILE: |
| + | case TOOLMIME_FILEDATA: |
| + | result = curl_mime_filedata(part, node->data); |
| + | if(!result && node->kind == TOOLMIME_FILEDATA && !filename) |
| + | result = curl_mime_filename(part, NULL); |
| + | break; |
| + | |
| + | case TOOLMIME_STDIN: |
| + | if(!filename) |
| + | filename = "-"; |
| + | FALLTHROUGH(); |
| + | case TOOLMIME_STDINDATA: |
| + | result = curl_mime_data_cb(part, node->size, |
| + | tool_mime_stdin_read, |
| + | tool_mime_stdin_seek, |
| + | NULL, node); |
| + | break; |
| + | |
| + | default: |
| + | /* Other cases not possible in this context. */ |
| + | break; |
| } | |
| + | |
| + | /* Common part configuration */ |
| if(!result && filename) | |
| result = curl_mime_filename(part, filename); | |
| if(!result) | |
| - | result = curl_mime_type(part, m->type); |
| + | result = curl_mime_type(part, node->type); |
| if(!result) | |
| - | result = curl_mime_headers(part, m->headers, 0); |
| + | result = curl_mime_headers(part, node->headers, 0); |
| if(!result) | |
| - | result = curl_mime_encoder(part, m->encoder); |
| + | result = curl_mime_encoder(part, node->encoder); |
| if(!result) | |
| - | result = curl_mime_name(part, m->name); |
| + | result = curl_mime_name(part, node->name); |
| + | |
| + | if(result) |
| + | break; |
| } | |
| + | |
| + | curlx_free(nodes); |
| return result; | |
| } | |