From cbc1d465538ef84a200c3e78399b085ce0ea3cf6 Mon Sep 17 00:00:00 2001 From: Maxim Pimenov Date: Fri, 9 Dec 2016 14:15:28 +0300 Subject: [PATCH 1/2] [coding] Added a version with exceptions to MemReader. --- coding/reader.cpp | 16 ---------------- coding/reader.hpp | 43 +++++++++++++++++++++++++++++++++---------- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/coding/reader.cpp b/coding/reader.cpp index 81cbdcced5..6b94af3bc7 100644 --- a/coding/reader.cpp +++ b/coding/reader.cpp @@ -19,19 +19,3 @@ bool Reader::IsEqual(string const & name1, string const & name2) return (name1 == name2); #endif } - -namespace -{ - bool AssertPosAndSizeImpl(uint64_t pos, uint64_t size, uint64_t readerSize) - { - bool const ret1 = (pos + size <= readerSize); - bool const ret2 = (size <= static_cast(-1)); - ASSERT ( ret1 && ret2, (pos, size, readerSize) ); - return (ret1 && ret2); - } -} - -bool MemReader::AssertPosAndSize(uint64_t pos, uint64_t size) const -{ - return AssertPosAndSizeImpl(pos, size, Size()); -} diff --git a/coding/reader.hpp b/coding/reader.hpp index c96088d0ff..34d2d98ac0 100644 --- a/coding/reader.hpp +++ b/coding/reader.hpp @@ -32,13 +32,12 @@ public: }; // Reader from memory. -class MemReader : public Reader +template +class MemReaderTemplate : public Reader { - bool AssertPosAndSize(uint64_t pos, uint64_t size) const; - public: // Construct from block of memory. - MemReader(void const * pData, size_t size) + MemReaderTemplate(void const * pData, size_t size) : m_pData(static_cast(pData)), m_size(size) { } @@ -50,27 +49,51 @@ public: inline void Read(uint64_t pos, void * p, size_t size) const override { - ASSERT ( AssertPosAndSize(pos, size), () ); + AssertPosAndSize(pos, size); memcpy(p, m_pData + pos, size); } - inline MemReader SubReader(uint64_t pos, uint64_t size) const + inline MemReaderTemplate SubReader(uint64_t pos, uint64_t size) const { - ASSERT ( AssertPosAndSize(pos, size), () ); - return MemReader(m_pData + pos, static_cast(size)); + AssertPosAndSize(pos, size); + return MemReaderTemplate(m_pData + pos, static_cast(size)); } inline unique_ptr CreateSubReader(uint64_t pos, uint64_t size) const override { - ASSERT ( AssertPosAndSize(pos, size), () ); - return make_unique(m_pData + pos, static_cast(size)); + AssertPosAndSize(pos, size); + return make_unique(m_pData + pos, static_cast(size)); } private: + bool GoodPosAndSize(uint64_t pos, uint64_t size) const + { + uint64_t const readerSize = Size(); + bool const ret1 = (pos + size <= readerSize); + bool const ret2 = (size <= static_cast(-1)); + return ret1 && ret2; + } + + void AssertPosAndSize(uint64_t pos, uint64_t size) const + { + if (WithExceptions) + { + if (!GoodPosAndSize(pos, size)) + MYTHROW(Reader::SizeException, (pos, size, Size())); + } + else + { + ASSERT(GoodPosAndSize(pos, size), (pos, size, Size())); + } + } + char const * m_pData; size_t m_size; }; +using MemReader = MemReaderTemplate; +using MemReaderWithExceptions = MemReaderTemplate; + // Reader wrapper to hold the pointer to a polymorfic reader. // Common use: ReaderSource >. // Note! It takes the ownership of Reader. From e989a95ad258bc0b1d4accc4cdb6d03eaf8b2c93 Mon Sep 17 00:00:00 2001 From: Maxim Pimenov Date: Fri, 9 Dec 2016 14:16:18 +0300 Subject: [PATCH 2/2] [traffic] Exceptions in readers. --- traffic/traffic_info.cpp | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/traffic/traffic_info.cpp b/traffic/traffic_info.cpp index 23138ba085..d8ba284675 100644 --- a/traffic/traffic_info.cpp +++ b/traffic/traffic_info.cpp @@ -97,6 +97,11 @@ TrafficInfo::TrafficInfo(MwmSet::MwmId const & mwmId, int64_t currentDataVersion : m_mwmId(mwmId) , m_currentDataVersion(currentDataVersion) { + if (!mwmId.IsAlive()) + { + LOG(LWARNING, ("Attempt to create a traffic info for dead mwm.")); + return; + } string const mwmPath = mwmId.GetInfo()->GetLocalFile().GetPath(MapOptions::Map); try { @@ -107,7 +112,21 @@ TrafficInfo::TrafficInfo(MwmSet::MwmId const & mwmId, int64_t currentDataVersion vector buf(reader.Size()); reader.Read(0, buf.data(), buf.size()); LOG(LINFO, ("Reading keys for", mwmId, "from section")); - DeserializeTrafficKeys(buf, m_keys); + try + { + DeserializeTrafficKeys(buf, m_keys); + } + catch (Reader::Exception const & e) + { + auto const info = mwmId.GetInfo(); + LOG(LINFO, ("Could not read traffic keys from section. MWM:", info->GetCountryName(), + "Version:", info->GetVersion())); + + alohalytics::LogEvent( + "$TrafficReadSectionError", + alohalytics::TStringMap({{"mwm", info->GetCountryName()}, + {"version", strings::to_string(info->GetVersion())}})); + } } else { @@ -268,7 +287,7 @@ void TrafficInfo::SerializeTrafficKeys(vector const & keys, vecto void TrafficInfo::DeserializeTrafficKeys(vector const & data, vector & result) { - MemReader memReader(data.data(), data.size()); + MemReaderWithExceptions memReader(data.data(), data.size()); ReaderSource src(memReader); auto const version = ReadPrimitiveFromSource(src); CHECK_EQUAL(version, kLatestKeysVersion, ("Unsupported version of traffic values.")); @@ -343,7 +362,7 @@ void TrafficInfo::DeserializeTrafficValues(vector const & data, vector decompressedData; coding::ZLib::Inflate(data.data(), data.size(), back_inserter(decompressedData)); - MemReader memReader(decompressedData.data(), decompressedData.size()); + MemReaderWithExceptions memReader(decompressedData.data(), decompressedData.size()); ReaderSource src(memReader); auto const version = ReadPrimitiveFromSource(src); @@ -364,6 +383,8 @@ void TrafficInfo::DeserializeTrafficValues(vector const & data, // todo(@m) This is a temporary method. Do not refactor it. bool TrafficInfo::ReceiveTrafficKeys() { + if (!m_mwmId.IsAlive()) + return false; auto const & info = m_mwmId.GetInfo(); if (!info) return false; @@ -400,6 +421,8 @@ bool TrafficInfo::ReceiveTrafficKeys() bool TrafficInfo::ReceiveTrafficValues(string & etag, vector & values) { + if (!m_mwmId.IsAlive()) + return false; auto const & info = m_mwmId.GetInfo(); if (!info) return false;