suunto eon steel: fix file reading special case

The "receive_data()" function would continue to try to read packets as
long as the previous packet was full-sized, but with just the right size
of file and the right chunking, the file might end at a packet boundary.
Then receive_data() would try to read more data, which fails - there are
no more packets, despite the last packet being full.

This never triggered for me, but Robert Helling forwarded a data dump of
a filure to read a dive due to this.

Since I don't trigger this case, I can't really test it, but I did check
that the new "stop early" logic works for me (ie never triggers ;).

Reported-by: Robert C. Helling <helling@atdotde.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Linus Torvalds 2015-05-20 14:16:56 -07:00 committed by Jef Driesen
parent 58f7235bb9
commit 8e3cb0542f

View File

@ -131,7 +131,7 @@ static int receive_data(suunto_eonsteel_device_t *eon, unsigned char *buffer, in
unsigned char buf[64];
int ret = 0;
for (;;) {
while (size > 0) {
int rc, transferred, len;
rc = libusb_interrupt_transfer(eon->handle, InEndpoint, buf, sizeof(buf), &transferred, 5000);
@ -233,12 +233,15 @@ static int send_receive(suunto_eonsteel_device_t *eon,
unsigned int len_out, const unsigned char *out,
unsigned int len_in, unsigned char *in)
{
int len, actual;
int len, actual, max;
unsigned char buf[2048];
if (send_cmd(eon, cmd, len_out, out) < 0)
return -1;
len = receive_data(eon, buf, sizeof(buf));
max = len_in + 12;
if (max > sizeof(buf))
max = sizeof(buf);
len = receive_data(eon, buf, max);
if (len < 10) {
ERROR(eon->base.context, "short command reply (%d)", len);
return -1;
@ -316,7 +319,7 @@ static int read_file(suunto_eonsteel_device_t *eon, const char *filename, dc_buf
put_le32(ask, cmdbuf+4); // Size of read
rc = send_receive(eon, FILE_READ_CMD,
8, cmdbuf,
sizeof(result), result);
ask+8, result);
if (rc < 0) {
ERROR(eon->base.context, "unable to read %s", filename);
return -1;