]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
TFTP: Fix upload problem with piped input
authorSerj Kalichev <serj.kalichev@gmail.com>
Tue, 2 Aug 2016 22:29:09 +0000 (00:29 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Wed, 3 Aug 2016 22:30:31 +0000 (00:30 +0200)
When input stream for curl is stdin and input stream is not a file but
generated by a script then curl can truncate data transfer to arbitrary
size since a partial packet is treated as end of transfer by TFTP.

Fixes #857

lib/tftp.c

index d7ff94f739915187e7d7284e8871a6e311e589e9..c97039620465501b43fb0c59ae51ee9052dca52d 100644 (file)
@@ -705,6 +705,7 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
   int rblock;
   CURLcode result = CURLE_OK;
   struct SingleRequest *k = &data->req;
+  int cb; /* Bytes currently read */
 
   switch(event) {
 
@@ -762,9 +763,20 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
       return CURLE_OK;
     }
 
-    result = Curl_fillreadbuffer(state->conn, state->blksize, &state->sbytes);
-    if(result)
-      return result;
+    /* TFTP considers data block size < 512 bytes as an end of session. So
+     * in some cases we must wait for additional data to build full (512 bytes)
+     * data block.
+     * */
+    state->sbytes = 0;
+    state->conn->data->req.upload_fromhere = (char *)state->spacket.data+4;
+    do {
+      result = Curl_fillreadbuffer(state->conn, state->blksize - state->sbytes,
+                                   &cb);
+      if(result)
+        return result;
+      state->sbytes += cb;
+      state->conn->data->req.upload_fromhere += cb;
+    } while(state->sbytes < state->blksize && cb != 0);
 
     sbytes = sendto(state->sockfd, (void *) state->spacket.data,
                     4 + state->sbytes, SEND_4TH_ARG,