Fixed a bug whereby a received file whose length was a multiple of
authorDan Fandrich <dan@coneharvesters.com>
Mon, 20 Mar 2006 22:15:22 +0000 (22:15 +0000)
committerDan Fandrich <dan@coneharvesters.com>
Mon, 20 Mar 2006 22:15:22 +0000 (22:15 +0000)
512 bytes could have random garbage appended.  Also, stop processing TFTP
packets which are too short to be legal.

lib/tftp.c

index 6560a48..9af1cf9 100644 (file)
@@ -656,30 +656,40 @@ CURLcode Curl_tftp(struct connectdata *conn, bool *done)
         state->remote_addrlen = fromlen;
       }
 
-      /* The event is given by the TFTP packet time */
-      event = (tftp_event_t)ntohs(state->rpacket.event);
-
-      switch(event) {
-      case TFTP_EVENT_DATA:
-        Curl_client_write(data, CLIENTWRITE_BODY,
-                          (char *)state->rpacket.u.data.data, state->rbytes-4);
-        break;
-      case TFTP_EVENT_ERROR:
-        state->error = (tftp_error_t)ntohs(state->rpacket.u.error.code);
-        infof(conn->data, "%s\n", (char *)state->rpacket.u.error.data);
-        break;
-      case TFTP_EVENT_ACK:
-        break;
-      case TFTP_EVENT_RRQ:
-      case TFTP_EVENT_WRQ:
-      default:
-        failf(conn->data, "%s\n", "Internal error: Unexpected packet");
-        break;
-      }
-
-      /* Update the progress meter */
-      Curl_pgrsUpdate(conn);
+      /* Sanity check packet length */
+      if (state->rbytes < 4)
+      {
+        failf(conn->data, "Received too short packet\n");
+        /* Not a timeout, but how best to handle it? */
+        event = TFTP_EVENT_TIMEOUT;
+      } else {
+
+       /* The event is given by the TFTP packet time */
+       event = (tftp_event_t)ntohs(state->rpacket.event);
+
+       switch(event) {
+       case TFTP_EVENT_DATA:
+         if (state->rbytes > 4)
+           Curl_client_write(data, CLIENTWRITE_BODY,
+                         (char *)state->rpacket.u.data.data, state->rbytes-4);
+         break;
+       case TFTP_EVENT_ERROR:
+         state->error = (tftp_error_t)ntohs(state->rpacket.u.error.code);
+         infof(conn->data, "%s\n", (char *)state->rpacket.u.error.data);
+         break;
+       case TFTP_EVENT_ACK:
+         break;
+       case TFTP_EVENT_RRQ:
+       case TFTP_EVENT_WRQ:
+       default:
+         failf(conn->data, "%s\n", "Internal error: Unexpected packet");
+         break;
+       }
+
+       /* Update the progress meter */
+       Curl_pgrsUpdate(conn);
 
+      }
     }
 
     /* Check for transfer timeout every 10 blocks, or after timeout */