diff --git a/src/csvparser.cpp b/src/csvparser.cpp index b1504fd2..9987646d 100644 --- a/src/csvparser.cpp +++ b/src/csvparser.cpp @@ -3,9 +3,8 @@ bool CSVParser::loadFile(QFile *file) { bool res; - int ln = 1; - _errorLine = 0; + _errorLine = 1; _errorString.clear(); while (!file->atEnd()) { @@ -13,20 +12,17 @@ bool CSVParser::loadFile(QFile *file) QList list = line.split(','); if (list.size() < 3) { _errorString = "Parse error"; - _errorLine = ln; return false; } qreal lat = list[0].trimmed().toDouble(&res); if (!res || (lat < -90.0 || lat > 90.0)) { _errorString = "Invalid latitude"; - _errorLine = ln; return false; } qreal lon = list[1].trimmed().toDouble(&res); if (!res || (lon < -180.0 || lon > 180.0)) { _errorString = "Invalid longitude"; - _errorLine = ln; return false; } Waypoint wp(Coordinates(lon, lat)); @@ -41,7 +37,7 @@ bool CSVParser::loadFile(QFile *file) } _waypoints.append(wp); - ln++; + _errorLine++; } return true; diff --git a/src/igcparser.cpp b/src/igcparser.cpp index 81e5748e..7689970f 100644 --- a/src/igcparser.cpp +++ b/src/igcparser.cpp @@ -83,32 +83,48 @@ static bool readAltitude(const char *line, qreal &ele) return true; } -bool IGCParser::readDate(const char *line) +static bool readARecord(const char *line, qint64 len) { + if (len < 9 || line[0] != 'A') + return false; + + for (int i = 1; i < 7; i++) + if (!::isprint(line[i])) + return false; + return true; +} + +bool IGCParser::readHRecord(const char *line, qint64 len) +{ + if (len < 10 || ::strncmp(line, "HFDTE", 5)) + return true; + int d = str2int(line + 5, 2); int m = str2int(line + 7, 2); int y = str2int(line + 9, 2); if (y < 0 || m < 0 || d < 0) { - _errorString = "Invalid date"; + _errorString = "Invalid date header format"; return false; } _date = QDate(2000 + y, m, d); + if (!_date.isValid()) { + _errorString = "Invalid date"; + return false; + } return true; } -bool IGCParser::readRecord(const char *line) +bool IGCParser::readBRecord(const char *line, qint64 len) { qreal lat, lon, ele; QDateTime timestamp; - if (_date.isNull()) { - _errorString = "Date header missing"; + if (len < 35) return false; - } int h = str2int(line + 1, 2); int m = str2int(line + 3, 2); @@ -157,44 +173,33 @@ bool IGCParser::loadFile(QFile *file) _tracks.append(TrackData()); _time = QTime(0, 0); - // Read the initial A record - if ((len = file->readLine(line, sizeof(line))) < 0) { - _errorString = "I/O error"; - return false; - } else { - if (len < 9 || len > (qint64)sizeof(line) - 1 || line[0] != 'A') { - _errorString = "Not a IGC file"; - return false; - } - for (int i = 1; i < 7; i++) { - if (!::isprint(line[i])) { - _errorString = "Not a IGC file"; - return false; - } - } - } - _errorLine++; - - // Read header (H) records and data (B) records while ((len = file->readLine(line, sizeof(line))) > 0) { if (len < 0) { _errorString = "I/O error"; return false; - } - if (len > (qint64)sizeof(line) - 1) { + } else if (len > (qint64)sizeof(line) - 1) { _errorString = "Line limit exceeded"; return false; } - if (line[0] == 'B') { - if (len > 35) - if (!readRecord(line)) + if (_errorLine == 1) { + if (!readARecord(line, len)) { + _errorString = "Invalid/missing A record"; + return false; + } + } else { + if (line[0] == 'H') { + if (!readHRecord(line, len)) return false; - } else if (line[0] == 'H') { - if (len > 10 && !::strncmp(line + 1, "FDTE", 4)) - if (!readDate(line)) + } else if (line[0] == 'B') { + if (_date.isNull()) { + _errorString = "Missing date header"; return false; + } + if (!readBRecord(line, len)) + return false; + } } _errorLine++; diff --git a/src/igcparser.h b/src/igcparser.h index 0964cb77..433f2a93 100644 --- a/src/igcparser.h +++ b/src/igcparser.h @@ -18,8 +18,8 @@ public: int errorLine() const {return _errorLine;} private: - bool readDate(const char *line); - bool readRecord(const char *line); + bool readHRecord(const char *line, qint64 len); + bool readBRecord(const char *line, qint64 len); int _errorLine; QString _errorString;