]> granicus.if.org Git - curl/commitdiff
INFILESIZE: fields in UserDefined must not be changed run-time
authorDaniel Stenberg <daniel@haxx.se>
Tue, 15 Apr 2014 11:49:18 +0000 (13:49 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Sat, 26 Apr 2014 16:17:10 +0000 (18:17 +0200)
set.infilesize in this case was modified in several places, which could
lead to repeated requests using the same handle to get unintendent/wrong
consequences based on what the previous request did!

13 files changed:
lib/curl_rtmp.c
lib/file.c
lib/ftp.c
lib/http.c
lib/imap.c
lib/multi.c
lib/rtsp.c
lib/smtp.c
lib/ssh.c
lib/tftp.c
lib/transfer.c
lib/url.c
lib/urldata.h

index 45da35ca01febddaf1c84cf9beb7147d4621cfad..e0c24b036c4668622b34ede5f14de657348a4f55 100644 (file)
@@ -5,6 +5,7 @@
  *                | (__| |_| |  _ <| |___
  *                 \___|\___/|_| \_\_____|
  *
+ * Copyright (C) 2012 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
  * Copyright (C) 2010, Howard Chu, <hyc@highlandsun.com>
  *
  * This software is licensed as described in the file COPYING, which
@@ -240,7 +241,7 @@ static CURLcode rtmp_do(struct connectdata *conn, bool *done)
     return CURLE_FAILED_INIT;
 
   if(conn->data->set.upload) {
-    Curl_pgrsSetUploadSize(conn->data, conn->data->set.infilesize);
+    Curl_pgrsSetUploadSize(conn->data, conn->data->state.infilesize);
     Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
   }
   else
index 043cccd4746f98d7a66aa6cea49916acf94ec1ab..73df42e026aa4cac0aba5f278fd78675108c3749 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2014, 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
@@ -336,9 +336,9 @@ static CURLcode file_upload(struct connectdata *conn)
     return CURLE_WRITE_ERROR;
   }
 
-  if(-1 != data->set.infilesize)
+  if(-1 != data->state.infilesize)
     /* known size of data to "upload" */
-    Curl_pgrsSetUploadSize(data, data->set.infilesize);
+    Curl_pgrsSetUploadSize(data, data->state.infilesize);
 
   /* treat the negative resume offset value as the case of "-" */
   if(data->state.resume_from < 0) {
index e8ac363c862b387d2920f8820b52ccf683a13af4..cadec10f52ae841be9ac101025badb87e2550939 100644 (file)
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -507,7 +507,7 @@ static CURLcode InitiateTransfer(struct connectdata *conn)
     /* When we know we're uploading a specified file, we can get the file
        size prior to the actual upload. */
 
-    Curl_pgrsSetUploadSize(data, data->set.infilesize);
+    Curl_pgrsSetUploadSize(data, data->state.infilesize);
 
     /* set the SO_SNDBUF for the secondary socket for those who need it */
     Curl_sndbufset(conn->sock[SECONDARYSOCKET]);
@@ -1683,10 +1683,10 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn,
       }
     }
     /* now, decrease the size of the read */
-    if(data->set.infilesize>0) {
-      data->set.infilesize -= data->state.resume_from;
+    if(data->state.infilesize>0) {
+      data->state.infilesize -= data->state.resume_from;
 
-      if(data->set.infilesize <= 0) {
+      if(data->state.infilesize <= 0) {
         infof(data, "File already completely uploaded\n");
 
         /* no data to transfer */
@@ -3382,13 +3382,13 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
        use checking further */
     ;
   else if(data->set.upload) {
-    if((-1 != data->set.infilesize) &&
-       (data->set.infilesize != *ftp->bytecountp) &&
+    if((-1 != data->state.infilesize) &&
+       (data->state.infilesize != *ftp->bytecountp) &&
        !data->set.crlf &&
        (ftp->transfer == FTPTRANSFER_BODY)) {
       failf(data, "Uploaded unaligned file size (%" CURL_FORMAT_CURL_OFF_T
             " out of %" CURL_FORMAT_CURL_OFF_T " bytes)",
-            *ftp->bytecountp, data->set.infilesize);
+            *ftp->bytecountp, data->state.infilesize);
       result = CURLE_PARTIAL_FILE;
     }
   }
index abcdd6ab818b9181002d93129f089a31b198a290..fb433496646d1ad3c04671df0a18087266460726 100644 (file)
@@ -405,8 +405,8 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
         expectsend = (curl_off_t)strlen(data->set.postfields);
       break;
     case HTTPREQ_PUT:
-      if(data->set.infilesize != -1)
-        expectsend = data->set.infilesize;
+      if(data->state.infilesize != -1)
+        expectsend = data->state.infilesize;
       break;
     case HTTPREQ_POST_FORM:
       expectsend = http->postsize;
@@ -1885,7 +1885,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
     else {
       if((conn->handler->protocol&PROTO_FAMILY_HTTP) &&
          data->set.upload &&
-         (data->set.infilesize == -1)) {
+         (data->state.infilesize == -1)) {
         if(conn->bits.authneg)
           /* don't enable chunked during auth neg */
           ;
@@ -2123,10 +2123,10 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
       }
 
       /* now, decrease the size of the read */
-      if(data->set.infilesize>0) {
-        data->set.infilesize -= data->state.resume_from;
+      if(data->state.infilesize>0) {
+        data->state.infilesize -= data->state.resume_from;
 
-        if(data->set.infilesize <= 0) {
+        if(data->state.infilesize <= 0) {
           failf(data, "File already completely uploaded");
           return CURLE_PARTIAL_FILE;
         }
@@ -2162,13 +2162,13 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
         conn->allocptr.rangeline =
           aprintf("Content-Range: bytes 0-%" CURL_FORMAT_CURL_OFF_T
                   "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
-                  data->set.infilesize - 1, data->set.infilesize);
+                  data->state.infilesize - 1, data->state.infilesize);
 
       }
       else if(data->state.resume_from) {
         /* This is because "resume" was selected */
         curl_off_t total_expected_size=
-          data->state.resume_from + data->set.infilesize;
+          data->state.resume_from + data->state.infilesize;
         conn->allocptr.rangeline =
           aprintf("Content-Range: bytes %s%" CURL_FORMAT_CURL_OFF_T
                   "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
@@ -2180,7 +2180,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
            append total size */
         conn->allocptr.rangeline =
           aprintf("Content-Range: bytes %s/%" CURL_FORMAT_CURL_OFF_T "\r\n",
-                  data->state.range, data->set.infilesize);
+                  data->state.range, data->state.infilesize);
       }
       if(!conn->allocptr.rangeline)
         return CURLE_OUT_OF_MEMORY;
@@ -2455,7 +2455,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
     if(conn->bits.authneg)
       postsize = 0;
     else
-      postsize = data->set.infilesize;
+      postsize = data->state.infilesize;
 
     if((postsize != -1) && !data->req.upload_chunky &&
        !Curl_checkheaders(conn, "Content-Length:")) {
index fc162b6c8fe630d68385ad7677a45524b240a08a..713060352cb36bd74c54c5757552fd5ec3724d6e 100644 (file)
@@ -775,7 +775,7 @@ static CURLcode imap_perform_append(struct connectdata *conn)
   }
 
   /* Check we know the size of the upload */
-  if(conn->data->set.infilesize < 0) {
+  if(conn->data->state.infilesize < 0) {
     failf(conn->data, "Cannot APPEND with unknown input file size\n");
     return CURLE_UPLOAD_FAILED;
   }
@@ -787,7 +787,7 @@ static CURLcode imap_perform_append(struct connectdata *conn)
 
   /* Send the APPEND command */
   result = imap_sendf(conn, "APPEND %s (\\Seen) {%" CURL_FORMAT_CURL_OFF_T "}",
-                      mailbox, conn->data->set.infilesize);
+                      mailbox, conn->data->state.infilesize);
 
   Curl_safefree(mailbox);
 
@@ -1618,7 +1618,7 @@ static CURLcode imap_state_append_resp(struct connectdata *conn, int imapcode,
   }
   else {
     /* Set the progress upload size */
-    Curl_pgrsSetUploadSize(data, data->set.infilesize);
+    Curl_pgrsSetUploadSize(data, data->state.infilesize);
 
     /* IMAP upload */
     Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
index bc932640ac9acba6a1499c2a6d776cf7f35c8f13..7720c957a96269f05ea0a97768e86840d9b2e155 100644 (file)
@@ -404,6 +404,8 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
   /* Point to the multi's connection cache */
   data->state.conn_cache = multi->conn_cache;
 
+  data->state.infilesize = data->set.filesize;
+
   /* This adds the new entry at the 'end' of the doubly-linked circular
      list of SessionHandle structs to try and maintain a FIFO queue so
      the pipelined requests are in order. */
index e746fb1b190e21dd86111e299a05794913d0e717..029738d9b6d77f6454ec0dc061fd55be4620cf8d 100644 (file)
@@ -493,7 +493,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
      rtspreq == RTSPREQ_GET_PARAMETER) {
 
     if(data->set.upload) {
-      putsize = data->set.infilesize;
+      putsize = data->state.infilesize;
       data->set.httpreq = HTTPREQ_PUT;
 
     }
index d367d94b8c583f2f4b32fbf3c2c71040d798085c..762a8d16a65956d39a8b81aa75c175a51f619456 100644 (file)
@@ -583,8 +583,8 @@ static CURLcode smtp_perform_mail(struct connectdata *conn)
   }
 
   /* Calculate the optional SIZE parameter */
-  if(conn->proto.smtpc.size_supported && conn->data->set.infilesize > 0) {
-    size = aprintf("%" CURL_FORMAT_CURL_OFF_T, data->set.infilesize);
+  if(conn->proto.smtpc.size_supported && conn->data->state.infilesize > 0) {
+    size = aprintf("%" CURL_FORMAT_CURL_OFF_T, data->state.infilesize);
 
     if(!size) {
       Curl_safefree(from);
@@ -1356,7 +1356,7 @@ static CURLcode smtp_state_data_resp(struct connectdata *conn, int smtpcode,
   }
   else {
     /* Set the progress upload size */
-    Curl_pgrsSetUploadSize(data, data->set.infilesize);
+    Curl_pgrsSetUploadSize(data, data->state.infilesize);
 
     /* SMTP upload */
     Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
@@ -1659,7 +1659,7 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
        is "no mail data". RFC-5321, sect. 4.1.1.4. */
     eob = SMTP_EOB;
     len = SMTP_EOB_LEN;
-    if(smtp->trailing_crlf || !conn->data->set.infilesize) {
+    if(smtp->trailing_crlf || !conn->data->state.infilesize) {
       eob += 2;
       len -= 2;
     }
index ad6d3226eea60403489e76cd63400ec6c232f9be..5e18ca7224ce775fddec4a88f33795a7c6fcf72b 100644 (file)
--- a/lib/ssh.c
+++ b/lib/ssh.c
@@ -1717,17 +1717,17 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
         }
 
         /* now, decrease the size of the read */
-        if(data->set.infilesize > 0) {
-          data->set.infilesize -= data->state.resume_from;
-          data->req.size = data->set.infilesize;
-          Curl_pgrsSetUploadSize(data, data->set.infilesize);
+        if(data->state.infilesize > 0) {
+          data->state.infilesize -= data->state.resume_from;
+          data->req.size = data->state.infilesize;
+          Curl_pgrsSetUploadSize(data, data->state.infilesize);
         }
 
         SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
       }
-      if(data->set.infilesize > 0) {
-        data->req.size = data->set.infilesize;
-        Curl_pgrsSetUploadSize(data, data->set.infilesize);
+      if(data->state.infilesize > 0) {
+        data->req.size = data->state.infilesize;
+        Curl_pgrsSetUploadSize(data, data->state.infilesize);
       }
       /* upload data */
       Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
@@ -2256,7 +2256,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       }
 
       if(data->set.upload) {
-        if(data->set.infilesize < 0) {
+        if(data->state.infilesize < 0) {
           failf(data, "SCP requires a known file size for upload");
           sshc->actualcode = CURLE_UPLOAD_FAILED;
           state(conn, SSH_SCP_CHANNEL_FREE);
@@ -2278,7 +2278,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
        */
       sshc->ssh_channel =
         SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
-                 data->set.infilesize);
+                 data->state.infilesize);
       if(!sshc->ssh_channel) {
         if(libssh2_session_last_errno(sshc->ssh_session) ==
            LIBSSH2_ERROR_EAGAIN) {
index 03a84e6311eab6b81789cd952474ddcc62e7237b..d19f48029f83fa8121bb0f2b832e1ecea339f020 100644 (file)
@@ -477,8 +477,8 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
       setpacketevent(&state->spacket, TFTP_EVENT_WRQ);
       state->conn->data->req.upload_fromhere =
         (char *)state->spacket.data+4;
-      if(data->set.infilesize != -1)
-        Curl_pgrsSetUploadSize(data, data->set.infilesize);
+      if(data->state.infilesize != -1)
+        Curl_pgrsSetUploadSize(data, data->state.infilesize);
     }
     else {
       /* If we are downloading, send an RRQ */
@@ -498,9 +498,9 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
     sbytes = 4 + strlen(filename) + strlen(mode);
 
     /* add tsize option */
-    if(data->set.upload && (data->set.infilesize != -1))
+    if(data->set.upload && (data->state.infilesize != -1))
       snprintf(buf, sizeof(buf), "%" CURL_FORMAT_CURL_OFF_T,
-               data->set.infilesize);
+               data->state.infilesize);
     else
       strcpy(buf, "0"); /* the destination is large enough */
 
index 46e55fbb5e8f4da3e71d4d259114a5ee35f5cd77..c1cdde60bf19aa7d31c66eca96a82d6b224d2e90 100644 (file)
@@ -926,7 +926,7 @@ static CURLcode readwrite_upload(struct SessionHandle *data,
             if(!data->set.crlf) {
               /* we're here only because FTP is in ASCII mode...
                  bump infilesize for the LF we just added */
-              data->set.infilesize++;
+              data->state.infilesize++;
             }
           }
           else
@@ -967,7 +967,7 @@ static CURLcode readwrite_upload(struct SessionHandle *data,
 
     k->writebytecount += bytes_written;
 
-    if(k->writebytecount == data->set.infilesize) {
+    if(k->writebytecount == data->state.infilesize) {
       /* we have sent all data we were supposed to */
       k->upload_done = TRUE;
       infof(data, "We are completely uploaded and fine\n");
index 409085f93199c201c37eccf2ee91bb2de9d68787..5952a9bec3b9402eb9e986eb02c24bc3fa192d40 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -485,7 +485,7 @@ CURLcode Curl_init_userdefined(struct UserDefined *set)
   set->convtonetwork   = ZERO_NULL;
   set->convfromutf8    = ZERO_NULL;
 
-  set->infilesize = -1;      /* we don't know any size */
+  set->filesize = -1;        /* we don't know the size */
   set->postfieldsize = -1;   /* unknown size */
   set->maxredirs = -1;       /* allow any amount by default */
 
@@ -1491,14 +1491,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
      * If known, this should inform curl about the file size of the
      * to-be-uploaded file.
      */
-    data->set.infilesize = va_arg(param, long);
+    data->set.filesize = va_arg(param, long);
     break;
   case CURLOPT_INFILESIZE_LARGE:
     /*
      * If known, this should inform curl about the file size of the
      * to-be-uploaded file.
      */
-    data->set.infilesize = va_arg(param, curl_off_t);
+    data->set.filesize = va_arg(param, curl_off_t);
     break;
   case CURLOPT_LOW_SPEED_LIMIT:
     /*
@@ -4100,16 +4100,17 @@ static CURLcode setup_connection_internals(struct connectdata *conn)
 {
   const struct Curl_handler * p;
   CURLcode result;
+  struct SessionHandle *data = conn->data;
 
   /* in some case in the multi state-machine, we go back to the CONNECT state
      and then a second (or third or...) call to this function will be made
      without doing a DISCONNECT or DONE in between (since the connection is
      yet in place) and therefore this function needs to first make sure
      there's no lingering previous data allocated. */
-  Curl_free_request_state(conn->data);
+  Curl_free_request_state(data);
 
-  memset(&conn->data->req, 0, sizeof(struct SingleRequest));
-  conn->data->req.maxdownload = -1;
+  memset(&data->req, 0, sizeof(struct SingleRequest));
+  data->req.maxdownload = -1;
 
   conn->socktype = SOCK_STREAM; /* most of them are TCP streams */
 
index 16f08d30e6e172bb7c8602ad6bc86484f90c660c..e62ea19304296b165cce38638ca9ccd5bddb1b24 100644 (file)
@@ -1306,6 +1306,8 @@ struct UrlState {
 
   /* if true, force SSL connection retry (workaround for certain servers) */
   bool ssl_connect_retry;
+  curl_off_t infilesize; /* size of file to upload, -1 means unknown.
+                            Copied from set.filesize at start of operation */
 };
 
 
@@ -1467,7 +1469,7 @@ struct UserDefined {
   long accepttimeout;   /* in milliseconds, 0 means no timeout */
   long server_response_timeout; /* in milliseconds, 0 means no timeout */
   long tftp_blksize ; /* in bytes, 0 means use default */
-  curl_off_t infilesize;      /* size of file to upload, -1 means unknown */
+  curl_off_t filesize;  /* size of file to upload, -1 means unknown */
   long low_speed_limit; /* bytes/second */
   long low_speed_time;  /* number of seconds */
   curl_off_t max_send_speed; /* high speed limit in bytes/second for upload */