Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/search
diff options
context:
space:
mode:
authorLev Dragunov <l.dragunov@corp.mail.ru>2015-08-24 14:08:55 +0300
committerAlex Zolotarev <alex@maps.me>2015-09-23 03:02:33 +0300
commit8de09846d1fb62e1bb6105199881a1262005f303 (patch)
tree1f1dde0d8a68566fa7d008e3f519e38ccfed0d03 /search
parent930b2c9f9d6471e53a30bef4427c3e96095f40df (diff)
[search] History corruption handling.
Diffstat (limited to 'search')
-rw-r--r--search/query_saver.cpp49
-rw-r--r--search/query_saver.hpp4
-rw-r--r--search/search_tests/query_saver_tests.cpp15
3 files changed, 58 insertions, 10 deletions
diff --git a/search/query_saver.cpp b/search/query_saver.cpp
index c5a4acce7c..a67b785c66 100644
--- a/search/query_saver.cpp
+++ b/search/query_saver.cpp
@@ -6,6 +6,8 @@
#include "coding/reader.hpp"
#include "coding/writer.hpp"
+#include "base/logging.hpp"
+
namespace
{
size_t constexpr kMaxSuggestCount = 10;
@@ -44,10 +46,10 @@ void QuerySaver::Clear()
Settings::Delete(kSettingsKey);
}
-void QuerySaver::Serialize(vector<uint8_t> & data) const
+void QuerySaver::Serialize(string & data) const
{
- data.clear();
- MemWriter<vector<uint8_t>> writer(data);
+ vector<uint8_t> rawData;
+ MemWriter<vector<uint8_t>> writer(rawData);
TLength size = m_topQueries.size();
writer.Write(&size, kLengthTypeSize);
for (auto const & query : m_topQueries)
@@ -56,20 +58,53 @@ void QuerySaver::Serialize(vector<uint8_t> & data) const
writer.Write(&size, kLengthTypeSize);
writer.Write(query.c_str(), size);
}
+ data = ToHex(&rawData[0], rawData.size());
+}
+
+void QuerySaver::EmergencyReset()
+{
+ Clear();
+ LOG(LWARNING, ("Search history data corrupted! Creating new one."));
}
void QuerySaver::Deserialize(string const & data)
{
- MemReader rawReader(data.c_str(), data.size());
+ string decodedData;
+ try
+ {
+ decodedData = FromHex(data);
+ }
+ catch (RootException const & ex)
+ {
+ EmergencyReset();
+ return;
+ }
+ MemReader rawReader(decodedData.c_str(), decodedData.size());
ReaderSource<MemReader> reader(rawReader);
TLength queriesCount;
reader.Read(&queriesCount, kLengthTypeSize);
+ if (queriesCount > kMaxSuggestCount)
+ {
+ EmergencyReset();
+ return;
+ }
+
for (TLength i = 0; i < queriesCount; ++i)
{
TLength stringLength;
+ if (reader.Size() < kLengthTypeSize)
+ {
+ EmergencyReset();
+ return;
+ }
reader.Read(&stringLength, kLengthTypeSize);
+ if (reader.Size() < stringLength)
+ {
+ EmergencyReset();
+ return;
+ }
vector<char> str(stringLength);
reader.Read(&str[0], stringLength);
m_topQueries.emplace_back(&str[0], stringLength);
@@ -78,9 +113,9 @@ void QuerySaver::Deserialize(string const & data)
void QuerySaver::Save()
{
- vector<uint8_t> data;
+ string data;
Serialize(data);
- Settings::Set(kSettingsKey, ToHex(&data[0], data.size()));
+ Settings::Set(kSettingsKey, data);
}
void QuerySaver::Load()
@@ -89,6 +124,6 @@ void QuerySaver::Load()
Settings::Get(kSettingsKey, hexData);
if (hexData.empty())
return;
- Deserialize(FromHex(hexData));
+ Deserialize(hexData);
}
} // namesapce search
diff --git a/search/query_saver.hpp b/search/query_saver.hpp
index 78d858c113..ccc603f796 100644
--- a/search/query_saver.hpp
+++ b/search/query_saver.hpp
@@ -18,12 +18,14 @@ public:
private:
friend void UnitTest_QuerySaverSerializerTest();
- void Serialize(vector<uint8_t> & data) const;
+ friend void UnitTest_QuerySaverCorruptedStringTest();
+ void Serialize(string & data) const;
void Deserialize(string const & data);
void Save();
void Load();
+ void EmergencyReset();
list<string> m_topQueries;
};
} // namespace search
diff --git a/search/search_tests/query_saver_tests.cpp b/search/search_tests/query_saver_tests.cpp
index 169cd5df54..7d8216fc3d 100644
--- a/search/search_tests/query_saver_tests.cpp
+++ b/search/search_tests/query_saver_tests.cpp
@@ -62,12 +62,12 @@ UNIT_TEST(QuerySaverSerializerTest)
saver.Clear();
saver.Add(record1);
saver.Add(record2);
- vector<uint8_t> data;
+ string data;
saver.Serialize(data);
TEST_GREATER(data.size(), 0, ());
saver.Clear();
TEST_EQUAL(saver.Get().size(), 0, ());
- saver.Deserialize(string(data.begin(), data.end()));
+ saver.Deserialize(data);
list<string> const & result = saver.Get();
TEST_EQUAL(result.size(), 2, ());
@@ -75,6 +75,17 @@ UNIT_TEST(QuerySaverSerializerTest)
TEST_EQUAL(result.front(), record2, ());
}
+UNIT_TEST(QuerySaverCorruptedStringTest)
+{
+ // We can't catch the ASEERT exception on the DEBUG build.
+ // So we check only valid HEX string case.
+ QuerySaver saver;
+ string corrupted("DEADBEEF");
+ saver.Deserialize(corrupted);
+ list<string> const & result = saver.Get();
+ TEST_EQUAL(result.size(), 0, ());
+}
+
UNIT_TEST(QuerySaverPersistanceStore)
{
{