formdata.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937
  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
  9. *
  10. * This software is licensed as described in the file COPYING, which
  11. * you should have received as part of this distribution. The terms
  12. * are also available at https://curl.se/docs/copyright.html.
  13. *
  14. * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  15. * copies of the Software, and permit persons to whom the Software is
  16. * furnished to do so, under the terms of the COPYING file.
  17. *
  18. * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  19. * KIND, either express or implied.
  20. *
  21. * SPDX-License-Identifier: curl
  22. *
  23. ***************************************************************************/
  24. #include "curl_setup.h"
  25. #include <curl/curl.h>
  26. struct Curl_easy;
  27. #include "formdata.h"
  28. #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_FORM_API)
  29. #include "urldata.h" /* for struct Curl_easy */
  30. #include "mime.h"
  31. #include "vtls/vtls.h"
  32. #include "sendf.h"
  33. #include "strdup.h"
  34. #include "rand.h"
  35. #include "curlx/fopen.h"
  36. #include "curlx/warnless.h"
  37. /* The last 2 #include files should be in this order */
  38. #include "curl_memory.h"
  39. #include "memdebug.h"
  40. #define HTTPPOST_PTRNAME CURL_HTTPPOST_PTRNAME
  41. #define HTTPPOST_FILENAME CURL_HTTPPOST_FILENAME
  42. #define HTTPPOST_PTRCONTENTS CURL_HTTPPOST_PTRCONTENTS
  43. #define HTTPPOST_READFILE CURL_HTTPPOST_READFILE
  44. #define HTTPPOST_PTRBUFFER CURL_HTTPPOST_PTRBUFFER
  45. #define HTTPPOST_CALLBACK CURL_HTTPPOST_CALLBACK
  46. #define HTTPPOST_BUFFER CURL_HTTPPOST_BUFFER
  47. /***************************************************************************
  48. *
  49. * AddHttpPost()
  50. *
  51. * Adds an HttpPost structure to the list, if parent_post is given becomes
  52. * a subpost of parent_post instead of a direct list element.
  53. *
  54. * Returns newly allocated HttpPost on success and NULL if malloc failed.
  55. *
  56. ***************************************************************************/
  57. static struct curl_httppost *
  58. AddHttpPost(struct FormInfo *src,
  59. struct curl_httppost *parent_post,
  60. struct curl_httppost **httppost,
  61. struct curl_httppost **last_post)
  62. {
  63. struct curl_httppost *post;
  64. size_t namelength = src->namelength;
  65. if(!namelength && src->name)
  66. namelength = strlen(src->name);
  67. if((src->bufferlength > LONG_MAX) || (namelength > LONG_MAX))
  68. /* avoid overflow in typecasts below */
  69. return NULL;
  70. post = calloc(1, sizeof(struct curl_httppost));
  71. if(post) {
  72. post->name = src->name;
  73. post->namelength = (long)namelength;
  74. post->contents = src->value;
  75. post->contentlen = src->contentslength;
  76. post->buffer = src->buffer;
  77. post->bufferlength = (long)src->bufferlength;
  78. post->contenttype = src->contenttype;
  79. post->flags = src->flags | CURL_HTTPPOST_LARGE;
  80. post->contentheader = src->contentheader;
  81. post->showfilename = src->showfilename;
  82. post->userp = src->userp;
  83. }
  84. else
  85. return NULL;
  86. if(parent_post) {
  87. /* now, point our 'more' to the original 'more' */
  88. post->more = parent_post->more;
  89. /* then move the original 'more' to point to ourselves */
  90. parent_post->more = post;
  91. }
  92. else {
  93. /* make the previous point to this */
  94. if(*last_post)
  95. (*last_post)->next = post;
  96. else
  97. (*httppost) = post;
  98. (*last_post) = post;
  99. }
  100. return post;
  101. }
  102. /***************************************************************************
  103. *
  104. * AddFormInfo()
  105. *
  106. * Adds a FormInfo structure to the list presented by parent_form_info.
  107. *
  108. * Returns newly allocated FormInfo on success and NULL if malloc failed/
  109. * parent_form_info is NULL.
  110. *
  111. ***************************************************************************/
  112. static struct FormInfo *AddFormInfo(char *value,
  113. char *contenttype,
  114. struct FormInfo *parent_form_info)
  115. {
  116. struct FormInfo *form_info;
  117. form_info = calloc(1, sizeof(struct FormInfo));
  118. if(!form_info)
  119. return NULL;
  120. if(value)
  121. form_info->value = value;
  122. if(contenttype)
  123. form_info->contenttype = contenttype;
  124. form_info->flags = HTTPPOST_FILENAME;
  125. if(parent_form_info) {
  126. /* now, point our 'more' to the original 'more' */
  127. form_info->more = parent_form_info->more;
  128. /* then move the original 'more' to point to ourselves */
  129. parent_form_info->more = form_info;
  130. }
  131. return form_info;
  132. }
  133. static void free_formlist(struct FormInfo *ptr)
  134. {
  135. for(; ptr != NULL; ptr = ptr->more) {
  136. if(ptr->name_alloc) {
  137. Curl_safefree(ptr->name);
  138. ptr->name_alloc = FALSE;
  139. }
  140. if(ptr->value_alloc) {
  141. Curl_safefree(ptr->value);
  142. ptr->value_alloc = FALSE;
  143. }
  144. if(ptr->contenttype_alloc) {
  145. Curl_safefree(ptr->contenttype);
  146. ptr->contenttype_alloc = FALSE;
  147. }
  148. if(ptr->showfilename_alloc) {
  149. Curl_safefree(ptr->showfilename);
  150. ptr->showfilename_alloc = FALSE;
  151. }
  152. }
  153. }
  154. /***************************************************************************
  155. *
  156. * FormAdd()
  157. *
  158. * Stores a formpost parameter and builds the appropriate linked list.
  159. *
  160. * Has two principal functionalities: using files and byte arrays as
  161. * post parts. Byte arrays are either copied or just the pointer is stored
  162. * (as the user requests) while for files only the filename and not the
  163. * content is stored.
  164. *
  165. * While you may have only one byte array for each name, multiple filenames
  166. * are allowed (and because of this feature CURLFORM_END is needed after
  167. * using CURLFORM_FILE).
  168. *
  169. * Examples:
  170. *
  171. * Simple name/value pair with copied contents:
  172. * curl_formadd(&post, &last, CURLFORM_COPYNAME, "name",
  173. * CURLFORM_COPYCONTENTS, "value", CURLFORM_END);
  174. *
  175. * name/value pair where only the content pointer is remembered:
  176. * curl_formadd(&post, &last, CURLFORM_COPYNAME, "name",
  177. * CURLFORM_PTRCONTENTS, ptr, CURLFORM_CONTENTSLENGTH, 10,
  178. * CURLFORM_END);
  179. * (if CURLFORM_CONTENTSLENGTH is missing strlen () is used)
  180. *
  181. * storing a filename (CONTENTTYPE is optional!):
  182. * curl_formadd(&post, &last, CURLFORM_COPYNAME, "name",
  183. * CURLFORM_FILE, "filename1", CURLFORM_CONTENTTYPE, "plain/text",
  184. * CURLFORM_END);
  185. *
  186. * storing multiple filenames:
  187. * curl_formadd(&post, &last, CURLFORM_COPYNAME, "name",
  188. * CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2",
  189. * CURLFORM_END);
  190. *
  191. * Returns:
  192. * CURL_FORMADD_OK on success
  193. * CURL_FORMADD_MEMORY if the FormInfo allocation fails
  194. * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form
  195. * CURL_FORMADD_NULL if a null pointer was given for a char
  196. * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed
  197. * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
  198. * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error)
  199. * CURL_FORMADD_MEMORY if an HttpPost struct cannot be allocated
  200. * CURL_FORMADD_MEMORY if some allocation for string copying failed.
  201. * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array
  202. *
  203. ***************************************************************************/
  204. static CURLFORMcode FormAddCheck(struct FormInfo *first_form,
  205. struct curl_httppost **httppost,
  206. struct curl_httppost **last_post)
  207. {
  208. const char *prevtype = NULL;
  209. struct FormInfo *form = NULL;
  210. struct curl_httppost *post = NULL;
  211. /* go through the list, check for completeness and if everything is
  212. * alright add the HttpPost item otherwise set retval accordingly */
  213. for(form = first_form;
  214. form != NULL;
  215. form = form->more) {
  216. if(((!form->name || !form->value) && !post) ||
  217. ( (form->contentslength) &&
  218. (form->flags & HTTPPOST_FILENAME) ) ||
  219. ( (form->flags & HTTPPOST_FILENAME) &&
  220. (form->flags & HTTPPOST_PTRCONTENTS) ) ||
  221. ( (!form->buffer) &&
  222. (form->flags & HTTPPOST_BUFFER) &&
  223. (form->flags & HTTPPOST_PTRBUFFER) ) ||
  224. ( (form->flags & HTTPPOST_READFILE) &&
  225. (form->flags & HTTPPOST_PTRCONTENTS) )
  226. ) {
  227. return CURL_FORMADD_INCOMPLETE;
  228. }
  229. if(((form->flags & HTTPPOST_FILENAME) ||
  230. (form->flags & HTTPPOST_BUFFER)) &&
  231. !form->contenttype) {
  232. char *f = (form->flags & HTTPPOST_BUFFER) ?
  233. form->showfilename : form->value;
  234. char const *type;
  235. type = Curl_mime_contenttype(f);
  236. if(!type)
  237. type = prevtype;
  238. if(!type)
  239. type = FILE_CONTENTTYPE_DEFAULT;
  240. /* our contenttype is missing */
  241. form->contenttype = strdup(type);
  242. if(!form->contenttype)
  243. return CURL_FORMADD_MEMORY;
  244. form->contenttype_alloc = TRUE;
  245. }
  246. if(form->name && form->namelength) {
  247. if(memchr(form->name, 0, form->namelength))
  248. return CURL_FORMADD_NULL;
  249. }
  250. if(!(form->flags & HTTPPOST_PTRNAME) && form->name) {
  251. /* Note that there is small risk that form->name is NULL here if the app
  252. passed in a bad combo, so we check for that. */
  253. /* copy name (without strdup; possibly not null-terminated) */
  254. char *dupname = Curl_memdup0(form->name, form->namelength ?
  255. form->namelength : strlen(form->name));
  256. if(!dupname)
  257. return CURL_FORMADD_MEMORY;
  258. form->name = dupname;
  259. form->name_alloc = TRUE;
  260. }
  261. if(!(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE |
  262. HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
  263. HTTPPOST_CALLBACK)) && form->value) {
  264. /* copy value (without strdup; possibly contains null characters) */
  265. size_t clen = (size_t) form->contentslength;
  266. if(!clen)
  267. clen = strlen(form->value) + 1;
  268. form->value = Curl_memdup(form->value, clen);
  269. if(!form->value)
  270. return CURL_FORMADD_MEMORY;
  271. form->value_alloc = TRUE;
  272. }
  273. post = AddHttpPost(form, post, httppost, last_post);
  274. if(!post)
  275. return CURL_FORMADD_MEMORY;
  276. if(form->contenttype)
  277. prevtype = form->contenttype;
  278. }
  279. return CURL_FORMADD_OK;
  280. }
  281. /* Shallow cleanup. Remove the newly created chain, the structs only and not
  282. the content they point to */
  283. static void free_chain(struct curl_httppost *c)
  284. {
  285. while(c) {
  286. struct curl_httppost *next = c->next;
  287. if(c->more)
  288. free_chain(c->more);
  289. free(c);
  290. c = next;
  291. }
  292. }
  293. static
  294. CURLFORMcode FormAdd(struct curl_httppost **httppost,
  295. struct curl_httppost **last_post,
  296. va_list params)
  297. {
  298. struct FormInfo *first_form, *curr, *form = NULL;
  299. CURLFORMcode retval = CURL_FORMADD_OK;
  300. CURLformoption option;
  301. struct curl_forms *forms = NULL;
  302. char *avalue = NULL;
  303. struct curl_httppost *newchain = NULL;
  304. struct curl_httppost *lastnode = NULL;
  305. /* This is a state variable, that if TRUE means that we are parsing an
  306. array that we got passed to us. If FALSE we are parsing the input
  307. va_list arguments. */
  308. bool array_state = FALSE;
  309. /*
  310. * We need to allocate the first struct to fill in.
  311. */
  312. first_form = calloc(1, sizeof(struct FormInfo));
  313. if(!first_form)
  314. return CURL_FORMADD_MEMORY;
  315. curr = first_form;
  316. /*
  317. * Loop through all the options set. Break if we have an error to report.
  318. */
  319. while(retval == CURL_FORMADD_OK) {
  320. /* first see if we have more parts of the array param */
  321. if(array_state && forms) {
  322. /* get the upcoming option from the given array */
  323. option = forms->option;
  324. avalue = (char *)CURL_UNCONST(forms->value);
  325. forms++; /* advance this to next entry */
  326. if(CURLFORM_END == option) {
  327. /* end of array state */
  328. array_state = FALSE;
  329. continue;
  330. }
  331. }
  332. else {
  333. /* This is not array-state, get next option. This gets an 'int' with
  334. va_arg() because CURLformoption might be a smaller type than int and
  335. might cause compiler warnings and wrong behavior. */
  336. option = (CURLformoption)va_arg(params, int);
  337. if(CURLFORM_END == option)
  338. break;
  339. }
  340. switch(option) {
  341. case CURLFORM_ARRAY:
  342. if(array_state)
  343. /* we do not support an array from within an array */
  344. retval = CURL_FORMADD_ILLEGAL_ARRAY;
  345. else {
  346. forms = va_arg(params, struct curl_forms *);
  347. if(forms)
  348. array_state = TRUE;
  349. else
  350. retval = CURL_FORMADD_NULL;
  351. }
  352. break;
  353. /*
  354. * Set the Name property.
  355. */
  356. case CURLFORM_PTRNAME:
  357. curr->flags |= HTTPPOST_PTRNAME; /* fall through */
  358. FALLTHROUGH();
  359. case CURLFORM_COPYNAME:
  360. if(curr->name)
  361. retval = CURL_FORMADD_OPTION_TWICE;
  362. else {
  363. if(!array_state)
  364. avalue = va_arg(params, char *);
  365. if(avalue)
  366. curr->name = avalue; /* store for the moment */
  367. else
  368. retval = CURL_FORMADD_NULL;
  369. }
  370. break;
  371. case CURLFORM_NAMELENGTH:
  372. if(curr->namelength)
  373. retval = CURL_FORMADD_OPTION_TWICE;
  374. else
  375. curr->namelength =
  376. array_state ? (size_t)avalue : (size_t)va_arg(params, long);
  377. break;
  378. /*
  379. * Set the contents property.
  380. */
  381. case CURLFORM_PTRCONTENTS:
  382. curr->flags |= HTTPPOST_PTRCONTENTS;
  383. FALLTHROUGH();
  384. case CURLFORM_COPYCONTENTS:
  385. if(curr->value)
  386. retval = CURL_FORMADD_OPTION_TWICE;
  387. else {
  388. if(!array_state)
  389. avalue = va_arg(params, char *);
  390. if(avalue)
  391. curr->value = avalue; /* store for the moment */
  392. else
  393. retval = CURL_FORMADD_NULL;
  394. }
  395. break;
  396. case CURLFORM_CONTENTSLENGTH:
  397. curr->contentslength =
  398. array_state ? (size_t)avalue : (size_t)va_arg(params, long);
  399. break;
  400. case CURLFORM_CONTENTLEN:
  401. curr->flags |= CURL_HTTPPOST_LARGE;
  402. curr->contentslength =
  403. array_state ? (curl_off_t)(size_t)avalue :
  404. va_arg(params, curl_off_t);
  405. break;
  406. /* Get contents from a given filename */
  407. case CURLFORM_FILECONTENT:
  408. if(curr->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_READFILE))
  409. retval = CURL_FORMADD_OPTION_TWICE;
  410. else {
  411. if(!array_state)
  412. avalue = va_arg(params, char *);
  413. if(avalue) {
  414. curr->value = strdup(avalue);
  415. if(!curr->value)
  416. retval = CURL_FORMADD_MEMORY;
  417. else {
  418. curr->flags |= HTTPPOST_READFILE;
  419. curr->value_alloc = TRUE;
  420. }
  421. }
  422. else
  423. retval = CURL_FORMADD_NULL;
  424. }
  425. break;
  426. /* We upload a file */
  427. case CURLFORM_FILE:
  428. if(!array_state)
  429. avalue = va_arg(params, char *);
  430. if(curr->value) {
  431. if(curr->flags & HTTPPOST_FILENAME) {
  432. if(avalue) {
  433. char *fname = strdup(avalue);
  434. if(!fname)
  435. retval = CURL_FORMADD_MEMORY;
  436. else {
  437. form = AddFormInfo(fname, NULL, curr);
  438. if(!form) {
  439. free(fname);
  440. retval = CURL_FORMADD_MEMORY;
  441. }
  442. else {
  443. form->value_alloc = TRUE;
  444. curr = form;
  445. form = NULL;
  446. }
  447. }
  448. }
  449. else
  450. retval = CURL_FORMADD_NULL;
  451. }
  452. else
  453. retval = CURL_FORMADD_OPTION_TWICE;
  454. }
  455. else {
  456. if(avalue) {
  457. curr->value = strdup(avalue);
  458. if(!curr->value)
  459. retval = CURL_FORMADD_MEMORY;
  460. else {
  461. curr->flags |= HTTPPOST_FILENAME;
  462. curr->value_alloc = TRUE;
  463. }
  464. }
  465. else
  466. retval = CURL_FORMADD_NULL;
  467. }
  468. break;
  469. case CURLFORM_BUFFERPTR:
  470. curr->flags |= HTTPPOST_PTRBUFFER|HTTPPOST_BUFFER;
  471. if(curr->buffer)
  472. retval = CURL_FORMADD_OPTION_TWICE;
  473. else {
  474. if(!array_state)
  475. avalue = va_arg(params, char *);
  476. if(avalue) {
  477. curr->buffer = avalue; /* store for the moment */
  478. curr->value = avalue; /* make it non-NULL to be accepted
  479. as fine */
  480. }
  481. else
  482. retval = CURL_FORMADD_NULL;
  483. }
  484. break;
  485. case CURLFORM_BUFFERLENGTH:
  486. if(curr->bufferlength)
  487. retval = CURL_FORMADD_OPTION_TWICE;
  488. else
  489. curr->bufferlength =
  490. array_state ? (size_t)avalue : (size_t)va_arg(params, long);
  491. break;
  492. case CURLFORM_STREAM:
  493. curr->flags |= HTTPPOST_CALLBACK;
  494. if(curr->userp)
  495. retval = CURL_FORMADD_OPTION_TWICE;
  496. else {
  497. if(!array_state)
  498. avalue = va_arg(params, char *);
  499. if(avalue) {
  500. curr->userp = avalue;
  501. curr->value = avalue; /* this is not strictly true but we derive a
  502. value from this later on and we need this
  503. non-NULL to be accepted as a fine form
  504. part */
  505. }
  506. else
  507. retval = CURL_FORMADD_NULL;
  508. }
  509. break;
  510. case CURLFORM_CONTENTTYPE:
  511. if(!array_state)
  512. avalue = va_arg(params, char *);
  513. if(curr->contenttype) {
  514. if(curr->flags & HTTPPOST_FILENAME) {
  515. if(avalue) {
  516. char *type = strdup(avalue);
  517. if(!type)
  518. retval = CURL_FORMADD_MEMORY;
  519. else {
  520. form = AddFormInfo(NULL, type, curr);
  521. if(!form) {
  522. free(type);
  523. retval = CURL_FORMADD_MEMORY;
  524. }
  525. else {
  526. form->contenttype_alloc = TRUE;
  527. curr = form;
  528. form = NULL;
  529. }
  530. }
  531. }
  532. else
  533. retval = CURL_FORMADD_NULL;
  534. }
  535. else
  536. retval = CURL_FORMADD_OPTION_TWICE;
  537. }
  538. else {
  539. if(avalue) {
  540. curr->contenttype = strdup(avalue);
  541. if(!curr->contenttype)
  542. retval = CURL_FORMADD_MEMORY;
  543. else
  544. curr->contenttype_alloc = TRUE;
  545. }
  546. else
  547. retval = CURL_FORMADD_NULL;
  548. }
  549. break;
  550. case CURLFORM_CONTENTHEADER:
  551. {
  552. /* this "cast increases required alignment of target type" but
  553. we consider it OK anyway */
  554. struct curl_slist *list = array_state ?
  555. (struct curl_slist *)(void *)avalue :
  556. va_arg(params, struct curl_slist *);
  557. if(curr->contentheader)
  558. retval = CURL_FORMADD_OPTION_TWICE;
  559. else
  560. curr->contentheader = list;
  561. break;
  562. }
  563. case CURLFORM_FILENAME:
  564. case CURLFORM_BUFFER:
  565. if(!array_state)
  566. avalue = va_arg(params, char *);
  567. if(curr->showfilename)
  568. retval = CURL_FORMADD_OPTION_TWICE;
  569. else {
  570. curr->showfilename = strdup(avalue);
  571. if(!curr->showfilename)
  572. retval = CURL_FORMADD_MEMORY;
  573. else
  574. curr->showfilename_alloc = TRUE;
  575. }
  576. break;
  577. default:
  578. retval = CURL_FORMADD_UNKNOWN_OPTION;
  579. break;
  580. }
  581. }
  582. if(!retval)
  583. retval = FormAddCheck(first_form, &newchain, &lastnode);
  584. if(retval)
  585. /* On error, free allocated fields for all nodes of the FormInfo linked
  586. list without deallocating nodes. List nodes are deallocated later on */
  587. free_formlist(first_form);
  588. /* Always deallocate FormInfo linked list nodes without touching node
  589. fields given that these have either been deallocated or are owned
  590. now by the httppost linked list */
  591. while(first_form) {
  592. struct FormInfo *ptr = first_form->more;
  593. free(first_form);
  594. first_form = ptr;
  595. }
  596. if(!retval) {
  597. /* Only if all is fine, link the new chain into the provided list */
  598. if(*last_post)
  599. (*last_post)->next = newchain;
  600. else
  601. (*httppost) = newchain;
  602. (*last_post) = lastnode;
  603. }
  604. else
  605. free_chain(newchain);
  606. return retval;
  607. }
  608. /*
  609. * curl_formadd() is a public API to add a section to the multipart formpost.
  610. *
  611. * @unittest: 1308
  612. */
  613. CURLFORMcode curl_formadd(struct curl_httppost **httppost,
  614. struct curl_httppost **last_post,
  615. ...)
  616. {
  617. va_list arg;
  618. CURLFORMcode result;
  619. va_start(arg, last_post);
  620. result = FormAdd(httppost, last_post, arg);
  621. va_end(arg);
  622. return result;
  623. }
  624. /*
  625. * curl_formget()
  626. * Serialize a curl_httppost struct.
  627. * Returns 0 on success.
  628. *
  629. * @unittest: 1308
  630. */
  631. int curl_formget(struct curl_httppost *form, void *arg,
  632. curl_formget_callback append)
  633. {
  634. CURLcode result;
  635. curl_mimepart toppart;
  636. Curl_mime_initpart(&toppart); /* default form is empty */
  637. result = Curl_getformdata(NULL, &toppart, form, NULL);
  638. if(!result)
  639. result = Curl_mime_prepare_headers(NULL, &toppart, "multipart/form-data",
  640. NULL, MIMESTRATEGY_FORM);
  641. while(!result) {
  642. char buffer[8192];
  643. size_t nread = Curl_mime_read(buffer, 1, sizeof(buffer), &toppart);
  644. if(!nread)
  645. break;
  646. if(nread > sizeof(buffer) || append(arg, buffer, nread) != nread) {
  647. result = CURLE_READ_ERROR;
  648. if(nread == CURL_READFUNC_ABORT)
  649. result = CURLE_ABORTED_BY_CALLBACK;
  650. }
  651. }
  652. Curl_mime_cleanpart(&toppart);
  653. return (int) result;
  654. }
  655. /*
  656. * curl_formfree() is an external function to free up a whole form post
  657. * chain
  658. */
  659. void curl_formfree(struct curl_httppost *form)
  660. {
  661. struct curl_httppost *next;
  662. if(!form)
  663. /* no form to free, just get out of this */
  664. return;
  665. do {
  666. next = form->next; /* the following form line */
  667. /* recurse to sub-contents */
  668. curl_formfree(form->more);
  669. if(!(form->flags & HTTPPOST_PTRNAME))
  670. free(form->name); /* free the name */
  671. if(!(form->flags &
  672. (HTTPPOST_PTRCONTENTS|HTTPPOST_BUFFER|HTTPPOST_CALLBACK))
  673. )
  674. free(form->contents); /* free the contents */
  675. free(form->contenttype); /* free the content type */
  676. free(form->showfilename); /* free the faked filename */
  677. free(form); /* free the struct */
  678. form = next;
  679. } while(form); /* continue */
  680. }
  681. /* Set mime part name, taking care of non null-terminated name string. */
  682. static CURLcode setname(curl_mimepart *part, const char *name, size_t len)
  683. {
  684. char *zname;
  685. CURLcode res;
  686. if(!name || !len)
  687. return curl_mime_name(part, name);
  688. zname = Curl_memdup0(name, len);
  689. if(!zname)
  690. return CURLE_OUT_OF_MEMORY;
  691. res = curl_mime_name(part, zname);
  692. free(zname);
  693. return res;
  694. }
  695. /*
  696. * Curl_getformdata() converts a linked list of "meta data" into a mime
  697. * structure. The input list is in 'post', while the output is stored in
  698. * mime part at '*finalform'.
  699. *
  700. * This function will not do a failf() for the potential memory failures but
  701. * should for all other errors it spots. Just note that this function MAY get
  702. * a NULL pointer in the 'data' argument.
  703. */
  704. CURLcode Curl_getformdata(CURL *data,
  705. curl_mimepart *finalform,
  706. struct curl_httppost *post,
  707. curl_read_callback fread_func)
  708. {
  709. CURLcode result = CURLE_OK;
  710. curl_mime *form = NULL;
  711. curl_mimepart *part;
  712. struct curl_httppost *file;
  713. Curl_mime_cleanpart(finalform); /* default form is empty */
  714. if(!post)
  715. return result; /* no input => no output! */
  716. form = curl_mime_init(data);
  717. if(!form)
  718. result = CURLE_OUT_OF_MEMORY;
  719. if(!result)
  720. result = curl_mime_subparts(finalform, form);
  721. /* Process each top part. */
  722. for(; !result && post; post = post->next) {
  723. /* If we have more than a file here, create a mime subpart and fill it. */
  724. curl_mime *multipart = form;
  725. if(post->more) {
  726. part = curl_mime_addpart(form);
  727. if(!part)
  728. result = CURLE_OUT_OF_MEMORY;
  729. if(!result)
  730. result = setname(part, post->name, post->namelength);
  731. if(!result) {
  732. multipart = curl_mime_init(data);
  733. if(!multipart)
  734. result = CURLE_OUT_OF_MEMORY;
  735. }
  736. if(!result)
  737. result = curl_mime_subparts(part, multipart);
  738. }
  739. /* Generate all the part contents. */
  740. for(file = post; !result && file; file = file->more) {
  741. /* Create the part. */
  742. part = curl_mime_addpart(multipart);
  743. if(!part)
  744. result = CURLE_OUT_OF_MEMORY;
  745. /* Set the headers. */
  746. if(!result)
  747. result = curl_mime_headers(part, file->contentheader, 0);
  748. /* Set the content type. */
  749. if(!result && file->contenttype)
  750. result = curl_mime_type(part, file->contenttype);
  751. /* Set field name. */
  752. if(!result && !post->more)
  753. result = setname(part, post->name, post->namelength);
  754. /* Process contents. */
  755. if(!result) {
  756. curl_off_t clen = post->contentslength;
  757. if(post->flags & CURL_HTTPPOST_LARGE)
  758. clen = post->contentlen;
  759. if(post->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE)) {
  760. if(!strcmp(file->contents, "-")) {
  761. /* There are a few cases where the code below will not work; in
  762. particular, freopen(stdin) by the caller is not guaranteed
  763. to result as expected. This feature has been kept for backward
  764. compatibility: use of "-" pseudo filename should be avoided. */
  765. #if defined(__clang__) && __clang_major__ >= 16
  766. #pragma clang diagnostic push
  767. #pragma clang diagnostic ignored "-Wcast-function-type-strict"
  768. #endif
  769. result = curl_mime_data_cb(part, (curl_off_t) -1,
  770. (curl_read_callback) fread,
  771. curlx_fseek,
  772. NULL, (void *) stdin);
  773. #if defined(__clang__) && __clang_major__ >= 16
  774. #pragma clang diagnostic pop
  775. #endif
  776. }
  777. else
  778. result = curl_mime_filedata(part, file->contents);
  779. if(!result && (post->flags & HTTPPOST_READFILE))
  780. result = curl_mime_filename(part, NULL);
  781. }
  782. else if(post->flags & HTTPPOST_BUFFER)
  783. result = curl_mime_data(part, post->buffer,
  784. post->bufferlength ?
  785. post->bufferlength : -1);
  786. else if(post->flags & HTTPPOST_CALLBACK) {
  787. /* the contents should be read with the callback and the size is set
  788. with the contentslength */
  789. if(!clen)
  790. clen = -1;
  791. result = curl_mime_data_cb(part, clen,
  792. fread_func, NULL, NULL, post->userp);
  793. }
  794. else {
  795. size_t uclen;
  796. if(!clen)
  797. uclen = CURL_ZERO_TERMINATED;
  798. else
  799. uclen = (size_t)clen;
  800. result = curl_mime_data(part, post->contents, uclen);
  801. }
  802. }
  803. /* Set fake filename. */
  804. if(!result && post->showfilename)
  805. if(post->more || (post->flags & (HTTPPOST_FILENAME | HTTPPOST_BUFFER |
  806. HTTPPOST_CALLBACK)))
  807. result = curl_mime_filename(part, post->showfilename);
  808. }
  809. }
  810. if(result)
  811. Curl_mime_cleanpart(finalform);
  812. return result;
  813. }
  814. #else
  815. /* if disabled */
  816. CURLFORMcode curl_formadd(struct curl_httppost **httppost,
  817. struct curl_httppost **last_post,
  818. ...)
  819. {
  820. (void)httppost;
  821. (void)last_post;
  822. return CURL_FORMADD_DISABLED;
  823. }
  824. int curl_formget(struct curl_httppost *form, void *arg,
  825. curl_formget_callback append)
  826. {
  827. (void)form;
  828. (void)arg;
  829. (void)append;
  830. return CURL_FORMADD_DISABLED;
  831. }
  832. void curl_formfree(struct curl_httppost *form)
  833. {
  834. (void)form;
  835. /* Nothing to do. */
  836. }
  837. #endif /* if disabled */