diff --git a/test/source/scwx/awips/coded_location.test.cpp b/test/source/scwx/awips/coded_location.test.cpp index 00caa845..3666ae29 100644 --- a/test/source/scwx/awips/coded_location.test.cpp +++ b/test/source/scwx/awips/coded_location.test.cpp @@ -228,5 +228,29 @@ TEST(CodedLocation, MalformedData) EXPECT_EQ(dataValid, false); } +TEST(CodedLocation, InvalidWFOToken) +{ + std::vector data = { + "LAT...LON abcd 14509 1371 18195 1348 14463 1325 14492"}; + + CodedLocation location; + bool dataValid = location.Parse(data); + + EXPECT_EQ(dataValid, false); +} + +TEST(CodedLocation, InvalidNCToken) +{ + std::vector data = { + "LAT...LON 4731abcd 47216795 46466767 45436766 44756779", + " 44216834 43816943 43706970 43837006 44497009", + " 45306974 46356946 46976921"}; + + CodedLocation location; + bool dataValid = location.Parse(data); + + EXPECT_EQ(dataValid, false); +} + } // namespace awips } // namespace scwx diff --git a/test/source/scwx/awips/coded_time_motion_location.test.cpp b/test/source/scwx/awips/coded_time_motion_location.test.cpp index 8c09bcb4..b533c714 100644 --- a/test/source/scwx/awips/coded_time_motion_location.test.cpp +++ b/test/source/scwx/awips/coded_time_motion_location.test.cpp @@ -106,5 +106,38 @@ TEST(CodedTimeMotionLocation, MalformedData) EXPECT_EQ(dataValid, false); } +TEST(CodedTimeMotionLocation, InvalidDirection) +{ + std::vector data = { + "TIME...MOT...LOC 1959Z ZZZDEG 0KT 3253 11464"}; + + CodedTimeMotionLocation tml; + bool dataValid = tml.Parse(data); + + EXPECT_EQ(dataValid, false); +} + +TEST(CodedTimeMotionLocation, InvalidSpeed) +{ + std::vector data = { + "TIME...MOT...LOC 1959Z 254DEG ZKT 3253 11464"}; + + CodedTimeMotionLocation tml; + bool dataValid = tml.Parse(data); + + EXPECT_EQ(dataValid, false); +} + +TEST(CodedTimeMotionLocation, InvalidLocation) +{ + std::vector data = { + "TIME...MOT...LOC 1959Z 254DEG 0KT ZZZZ 11464"}; + + CodedTimeMotionLocation tml; + bool dataValid = tml.Parse(data); + + EXPECT_EQ(dataValid, false); +} + } // namespace awips } // namespace scwx diff --git a/wxdata/source/scwx/awips/coded_location.cpp b/wxdata/source/scwx/awips/coded_location.cpp index d1bea57f..c2b8fb00 100644 --- a/wxdata/source/scwx/awips/coded_location.cpp +++ b/wxdata/source/scwx/awips/coded_location.cpp @@ -82,9 +82,23 @@ bool CodedLocation::Parse(const StringRange& lines, const std::string& wfo) for (auto token = tokenList.cbegin() + 1; token != tokenList.cend(); ++token) { - double latitude = std::stod(*token) * 0.01; - ++token; - double longitude = std::stod(*token) * 0.01; + double latitude = 0.0; + double longitude = 0.0; + + try + { + latitude = std::stod(*token) * 0.01; + ++token; + longitude = std::stod(*token) * 0.01; + } + catch (const std::exception& ex) + { + BOOST_LOG_TRIVIAL(warning) + << logPrefix_ << "Invalid WFO location token: \"" << *token + << "\" (" << ex.what() << ")"; + dataValid = false; + break; + } // If a given product straddles 180 degrees longitude, those points // west of 180 degrees will be given as if they were west longitude @@ -99,7 +113,7 @@ bool CodedLocation::Parse(const StringRange& lines, const std::string& wfo) p->coordinates_.push_back({latitude, longitude}); } - if (!wfoIsWest && straddlesDateLine) + if (dataValid && !wfoIsWest && straddlesDateLine) { for (auto& coordinate : p->coordinates_) { @@ -123,8 +137,22 @@ bool CodedLocation::Parse(const StringRange& lines, const std::string& wfo) break; } - double latitude = std::stod(token->substr(0, 4)) * 0.01; - double longitude = std::stod(token->substr(4, 4)) * -0.01; + double latitude = 0.0; + double longitude = 0.0; + + try + { + latitude = std::stod(token->substr(0, 4)) * 0.01; + longitude = std::stod(token->substr(4, 4)) * -0.01; + } + catch (const std::exception& ex) + { + BOOST_LOG_TRIVIAL(warning) + << logPrefix_ << "Invalid National Center location token: \"" + << *token << "\" (" << ex.what() << ")"; + dataValid = false; + break; + } // Longitudes of greater than 100 degrees will drop the leading 1; // i.e., 105.22 W would be coded as 0522. This is ambiguous diff --git a/wxdata/source/scwx/awips/coded_time_motion_location.cpp b/wxdata/source/scwx/awips/coded_time_motion_location.cpp index 4e70afae..da402858 100644 --- a/wxdata/source/scwx/awips/coded_time_motion_location.cpp +++ b/wxdata/source/scwx/awips/coded_time_motion_location.cpp @@ -122,8 +122,18 @@ bool CodedTimeMotionLocation::Parse(const StringRange& lines, std::string direction = tokenList.at(2); if (direction.size() == 6 && direction.ends_with("DEG")) { - p->direction_ = - static_cast(std::stoul(direction.substr(0, 3))); + try + { + p->direction_ = + static_cast(std::stoul(direction.substr(0, 3))); + } + catch (const std::exception& ex) + { + BOOST_LOG_TRIVIAL(warning) + << logPrefix_ << "Invalid direction: \"" << direction << "\" (" + << ex.what() << ")"; + dataValid = false; + } } else { @@ -136,8 +146,17 @@ bool CodedTimeMotionLocation::Parse(const StringRange& lines, std::string speed = tokenList.at(3); if (speed.size() >= 3 && speed.size() <= 4 && speed.ends_with("KT")) { - p->speed_ = - static_cast(std::stoul(speed.substr(0, speed.size() - 2))); + try + { + p->speed_ = static_cast( + std::stoul(speed.substr(0, speed.size() - 2))); + } + catch (const std::exception& ex) + { + BOOST_LOG_TRIVIAL(warning) << logPrefix_ << "Invalid speed: \"" + << speed << "\" (" << ex.what() << ")"; + dataValid = false; + } } else { @@ -150,9 +169,23 @@ bool CodedTimeMotionLocation::Parse(const StringRange& lines, for (auto token = tokenList.cbegin() + 4; token != tokenList.cend(); ++token) { - double latitude = std::stod(*token) * 0.01; - ++token; - double longitude = std::stod(*token) * 0.01; + double latitude = 0.0; + double longitude = 0.0; + + try + { + latitude = std::stod(*token) * 0.01; + ++token; + longitude = std::stod(*token) * 0.01; + } + catch (const std::exception& ex) + { + BOOST_LOG_TRIVIAL(warning) + << logPrefix_ << "Invalid location token: \"" << *token << "\" (" + << ex.what() << ")"; + dataValid = false; + break; + } // If a given product straddles 180 degrees longitude, those points // west of 180 degrees will be given as if they were west longitude