From 34a979096c69e3700907e896c96bf47827b71499 Mon Sep 17 00:00:00 2001 From: Rainer Clasen Date: Tue, 8 Jul 2014 06:49:28 +0200 Subject: [PATCH 1/3] SrmRideFile: don't assert() on bad file version replaced assert() of file version with graceful error handling. --- src/SrmRideFile.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/SrmRideFile.cpp b/src/SrmRideFile.cpp index 4a02becbc..9b498788e 100644 --- a/src/SrmRideFile.cpp +++ b/src/SrmRideFile.cpp @@ -268,8 +268,7 @@ RideFile *SrmFileReader::openRideFile(QFile &file, QStringList &errorStrings, QL watts = (ps[1] & 0x0f) | (ps[2] << 0x4); alt = 0.0; } - else { - assert(version == 7); + else if (version == 7 ){ watts = readShort(in); cad = readByte(in); hr = readByte(in); @@ -280,6 +279,11 @@ RideFile *SrmFileReader::openRideFile(QFile &file, QStringList &errorStrings, QL alt = readSignedLong(in); temp = 0.1 * readSignedShort(in); } + else { + errorStrings << QString("unsupported SRM file version: %1") + .arg( version ); + return NULL; + } if (i == 0) { result->setStartTime(blockhdrs[blknum].dt); From fd5d7cfd7b0ac0cd0abf723ffe589931c5915cbb Mon Sep 17 00:00:00 2001 From: Rainer Clasen Date: Tue, 8 Jul 2014 06:51:08 +0200 Subject: [PATCH 2/3] SrmRideFile: handle EOF while reading chunks code was blindly trusting datacnt... and kept reading past EOF. That's bad as datacnt occasionally isn't matching the available data (overflow, corruption, ...) --- src/SrmRideFile.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/SrmRideFile.cpp b/src/SrmRideFile.cpp index 9b498788e..8ff5d074f 100644 --- a/src/SrmRideFile.cpp +++ b/src/SrmRideFile.cpp @@ -285,6 +285,11 @@ RideFile *SrmFileReader::openRideFile(QFile &file, QStringList &errorStrings, QL return NULL; } + if( in.status() != QDataStream::Ok ){ + errorStrings << QString("premature end of file" ); + break; + } + if (i == 0) { result->setStartTime(blockhdrs[blknum].dt); } From 7b42b863a1ba10e22caa02d802bf7e8ee798d842 Mon Sep 17 00:00:00 2001 From: Rainer Clasen Date: Tue, 8 Jul 2014 06:53:13 +0200 Subject: [PATCH 3/3] SrmRideFile: handle datacnt overflow datacnt is 16bits so it overflows easily for large files (9 hours with 0.5sec recint). I've also seen datacnt and block sum to be inconsistent in other cases. To handle this more graceful, we're now taking the max of both counts and let the EOF detection do it's job when one of them is wrong. We do have to use one of these limits as some SRM files have junk after their last chunk (so, just reading chunks till we get EOF retunrs this junk, too). --- src/SrmRideFile.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/SrmRideFile.cpp b/src/SrmRideFile.cpp index 8ff5d074f..160e39fb2 100644 --- a/src/SrmRideFile.cpp +++ b/src/SrmRideFile.cpp @@ -207,6 +207,7 @@ RideFile *SrmFileReader::openRideFile(QFile &file, QStringList &errorStrings, QL } blockhdr *blockhdrs = new blockhdr[blockcnt+1]; + int blockchunkcnt = 0; for (int i = 0; i < blockcnt; ++i) { // In the .srm files generated by Rainer Clasen's srmcmd, // hsecsincemidn is a *signed* 32-bit integer. I haven't seen a @@ -217,6 +218,7 @@ RideFile *SrmFileReader::openRideFile(QFile &file, QStringList &errorStrings, QL blockhdrs[i].chunkcnt = readShort(in); blockhdrs[i].dt = QDateTime(date); blockhdrs[i].dt = blockhdrs[i].dt.addMSecs(hsecsincemidn * 10); + blockchunkcnt += blockhdrs[i].chunkcnt; } // fail early to tell devs whats wrong with file @@ -247,6 +249,13 @@ RideFile *SrmFileReader::openRideFile(QFile &file, QStringList &errorStrings, QL blockhdrs[0].dt = QDateTime(date); } + // datacnt might overflow at 64k - so, use sum from blocks, instead + if( datacnt > blockchunkcnt ){ + blockchunkcnt = datacnt; + errorStrings << QString("inconsistent chunk count total=%1, blocks=%2") + .arg(datacnt) + .arg(blockchunkcnt); + } int blknum = 0, blkidx = 0, mrknum = 0, interval = 0; double km = 0.0, secs = 0.0; @@ -254,7 +263,7 @@ RideFile *SrmFileReader::openRideFile(QFile &file, QStringList &errorStrings, QL if (markercnt > 0) mrknum = 1; - for (int i = 0; i < datacnt; ++i) { + for (int i = 0; i < blockchunkcnt; ++i) { int cad, hr, watts; double kph, alt; double temp=-255;