Commit 0aedccc1 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

curl_formget: fix FILE * leak

Properly deal with the fact that the last fread() call most probably is
a short read, and when using callbacks in fact all calls can be short
reads. No longer consider a file read done until it returns a 0 from the
read function.

Reported by: Aaron Orenstein
Bug: http://curl.haxx.se/mail/lib-2011-06/0048.html
parent 85881f9f
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -891,7 +891,7 @@ int curl_formget(struct curl_httppost *form, void *arg,
          Curl_formclean(&data);
          return -1;
        }
      } while(nread == sizeof(buffer));
      } while(nread);
    }
    else {
      if(ptr->length != append(arg, ptr->line, ptr->length)) {
@@ -1306,6 +1306,11 @@ static size_t readfromfile(struct Form *form, char *buffer,
      return 0;
    else
      nread = form->fread_func(buffer, 1, size, form->data->line);

    if(nread > size)
      /* the read callback can return a value larger than the buffer but
         treat any such as no data in this case */
      nread = 0;
  }
  else {
    if(!form->fp) {
@@ -1316,9 +1321,9 @@ static size_t readfromfile(struct Form *form, char *buffer,
    }
    nread = fread(buffer, 1, size, form->fp);
  }
  if(!nread || nread > size) {
  if(!nread) {
    /* this is the last chunk from the file, move on */
    if(!callback) {
    if(form->fp) {
      fclose(form->fp);
      form->fp = NULL;
    }
+3 −0
Original line number Diff line number Diff line
@@ -23,6 +23,9 @@ formpost unit tests
<tool>
unit1308
</tool>
<file name="log/test-1308">
Piece of the file that is to uploaded as a formpost
</file>
</client>

</testcase>
+17 −0
Original line number Diff line number Diff line
@@ -75,4 +75,21 @@ UNITTEST_START

  curl_formfree(post);

  /* start a new formpost with a file upload and formget */
  post = last = NULL;

  rc = curl_formadd(&post, &last,
                    CURLFORM_PTRNAME, "name of file field",
                    CURLFORM_FILE, "log/test-1308",
                    CURLFORM_FILENAME, "custom named file",
                    CURLFORM_END);

  fail_unless(rc == 0, "curl_formadd returned error");

  rc = curl_formget(post, &total_size, print_httppost_callback);
  fail_unless(rc == 0, "curl_formget returned error");
  fail_unless(total_size == 847, "curl_formget got wrong size back");

  curl_formfree(post);

UNITTEST_STOP