diff options
author | Dan Fandrich <dan@coneharvesters.com> | 2006-03-20 22:15:22 +0000 |
---|---|---|
committer | Dan Fandrich <dan@coneharvesters.com> | 2006-03-20 22:15:22 +0000 |
commit | a63f9887b9523a5d73ed9348539919c175c1756a (patch) | |
tree | 04786738030d80c104aa44199f356f249cc99472 | |
parent | 1282aad4a5122e391fccaee7de11f923b269ef45 (diff) |
Fixed a bug whereby a received file whose length was a multiple of
512 bytes could have random garbage appended. Also, stop processing TFTP
packets which are too short to be legal.
-rw-r--r-- | lib/tftp.c | 56 |
1 files changed, 33 insertions, 23 deletions
diff --git a/lib/tftp.c b/lib/tftp.c index 6560a484d..9af1cf9b5 100644 --- a/lib/tftp.c +++ b/lib/tftp.c @@ -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 */ |