From 4ecd8a78ad89e6efd51b110b640cf5eed74fb02d Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Tue, 25 Jun 2019 23:54:55 +0200 Subject: [PATCH] Handled some potentially "dangerous" parsing issues for VATSIM file (no coordinate) https://discordapp.com/channels/539048679160676382/539486489977946112/593081121512751116 --- src/blackcore/vatsim/vatsimdatafilereader.cpp | 29 +++++++++++++++---- src/blackmisc/geo/coordinategeodetic.cpp | 14 ++++++--- src/blackmisc/geo/coordinategeodetic.h | 3 ++ src/blackmisc/pq/physicalquantity.cpp | 12 ++++++-- 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/src/blackcore/vatsim/vatsimdatafilereader.cpp b/src/blackcore/vatsim/vatsimdatafilereader.cpp index 31c862fc8..476f9ead1 100644 --- a/src/blackcore/vatsim/vatsimdatafilereader.cpp +++ b/src/blackcore/vatsim/vatsimdatafilereader.cpp @@ -283,12 +283,28 @@ namespace BlackCore const CUser user(clientPartsMap["cid"], clientPartsMap["realname"], callsign); const QString clientType = clientPartsMap["clienttype"].toLower(); if (clientType.isEmpty()) { break; } // sometimes type is empty - const double lat = clientPartsMap["latitude"].toDouble(); - const double lng = clientPartsMap["longitude"].toDouble(); - const double alt = clientPartsMap["altitude"].toDouble(); + + bool ok; + bool validPos = true; + const double lat = clientPartsMap["latitude"].toDouble(&ok); + QStringList posMsg; + if (!ok) { validPos = false; posMsg << QStringLiteral("latitude: '%1'").arg(clientPartsMap["latitude"]); } + + const double lng = clientPartsMap["longitude"].toDouble(&ok); + if (!ok) { validPos = false; posMsg << QStringLiteral("longitude: '%1'").arg(clientPartsMap["longitude"]); } + + const double alt = clientPartsMap["altitude"].toDouble(&ok); + if (!ok) { validPos = false; posMsg << QStringLiteral("altitude: '%1'").arg(clientPartsMap["altitude"]); } + CCoordinateGeodetic position = validPos ? CCoordinateGeodetic(lat, lng, alt) : CCoordinateGeodetic::null(); + + Q_ASSERT_X((validPos && posMsg.isEmpty()) || (!validPos && !posMsg.isEmpty()), Q_FUNC_INFO, "Inconsisten data"); + if (!posMsg.isEmpty()) + { + // Only info not to flood lof with warning + CLogMessage(this).validationInfo(u"Callsign '%1' %2") << callsign << posMsg.join(", "); + } + const CFrequency frequency = CFrequency(clientPartsMap["frequency"].toDouble(), CFrequencyUnit::MHz()); - CCoordinateGeodetic position(lat, lng, alt); - const CAltitude altitude(alt, CAltitude::MeanSeaLevel, CLengthUnit::ft()); const QString flightPlanRemarks = clientPartsMap["planned_remarks"].trimmed(); // Voice capabilities @@ -326,7 +342,8 @@ namespace BlackCore { // ATC section CLength range; - position.setGeodeticHeight(altitude); // the altitude is elevation for a station + // should be alread have alt/height position.setGeodeticHeight(altitude); + // the altitude is elevation for a station CAtcStation station(user.getCallsign().getStringAsSet(), user, frequency, position, range); station.setOnline(true); atcStations.push_back(station); diff --git a/src/blackmisc/geo/coordinategeodetic.cpp b/src/blackmisc/geo/coordinategeodetic.cpp index 38bbad844..e78a5c9fb 100644 --- a/src/blackmisc/geo/coordinategeodetic.cpp +++ b/src/blackmisc/geo/coordinategeodetic.cpp @@ -40,6 +40,12 @@ namespace BlackMisc return CCoordinateGeodetic(lat, lon, geodeticHeight); } + const CCoordinateGeodetic &CCoordinateGeodetic::null() + { + static const CCoordinateGeodetic n; + return n; + } + CLength calculateGreatCircleDistance(const ICoordinateGeodetic &coordinate1, const ICoordinateGeodetic &coordinate2) { if (coordinate1.isNull() || coordinate2.isNull()) { return CLength::null(); } @@ -177,10 +183,10 @@ namespace BlackMisc const CLatitude lat = this->latitude(); const CLongitude lng = this->longitude(); return QStringLiteral("Geodetic: {%1/%2, %3/%4, %5}").arg(lat.valueRoundedWithUnit(CAngleUnit::deg(), 6, i18n), - lat.valueRoundedWithUnit(CAngleUnit::rad(), 6, i18n), - lng.valueRoundedWithUnit(CAngleUnit::deg(), 6, i18n), - lng.valueRoundedWithUnit(CAngleUnit::rad(), 6, i18n), - this->geodeticHeight().valueRoundedWithUnit(CLengthUnit::ft(), 2, i18n)); + lat.valueRoundedWithUnit(CAngleUnit::rad(), 6, i18n), + lng.valueRoundedWithUnit(CAngleUnit::deg(), 6, i18n), + lng.valueRoundedWithUnit(CAngleUnit::rad(), 6, i18n), + this->geodeticHeight().valueRoundedWithUnit(CLengthUnit::ft(), 2, i18n)); } bool ICoordinateGeodetic::isNaNVector() const diff --git a/src/blackmisc/geo/coordinategeodetic.h b/src/blackmisc/geo/coordinategeodetic.h index 103d83900..f349055f5 100644 --- a/src/blackmisc/geo/coordinategeodetic.h +++ b/src/blackmisc/geo/coordinategeodetic.h @@ -314,6 +314,9 @@ namespace BlackMisc //! Coordinate by WGS84 position data static CCoordinateGeodetic fromWgs84(const QString &latitudeWgs84, const QString &longitudeWgs84, const Aviation::CAltitude &geodeticHeight = {}); + //! null coordinate + static const CCoordinateGeodetic &null(); + //! \copydoc Mixin::String::toQString QString convertToQString(bool i18n = false) const; diff --git a/src/blackmisc/pq/physicalquantity.cpp b/src/blackmisc/pq/physicalquantity.cpp index 8df3c19b5..2ed947ecb 100644 --- a/src/blackmisc/pq/physicalquantity.cpp +++ b/src/blackmisc/pq/physicalquantity.cpp @@ -251,9 +251,17 @@ namespace BlackMisc template PQ &CPhysicalQuantity::switchUnit(const MU &newUnit) { + // NULL check: https://discordapp.com/channels/539048679160676382/539925070550794240/593151683698229258 if (m_unit == newUnit || this->isNull()) { return *derived(); } - m_value = newUnit.convertFrom(m_value, m_unit); - m_unit = newUnit; + if (newUnit.isNull()) + { + this->setNull(); + } + else + { + m_value = newUnit.convertFrom(m_value, m_unit); + m_unit = newUnit; + } return *derived(); }