From 8e3cb0542f478ee94f49ac6abe25c50a0c63efac Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 20 May 2015 14:16:56 -0700 Subject: [PATCH] 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 Signed-off-by: Linus Torvalds Signed-off-by: Dirk Hohndel --- src/suunto_eonsteel.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/suunto_eonsteel.c b/src/suunto_eonsteel.c index ab090bf..3524903 100644 --- a/src/suunto_eonsteel.c +++ b/src/suunto_eonsteel.c @@ -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;