summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAshod Nakashian <ashod.nakashian@collabora.co.uk>2019-02-13 18:18:35 -0500
committerAshod Nakashian <ashnakash@gmail.com>2019-02-22 15:38:09 +0100
commit75be2ba9fb9ab443480903f31b873f4101d1fdc2 (patch)
tree7512fe1fe8838143cfd3dee7d982d181288b1d13
parent8410ce037ab27a38b0449c7666f1676374803496 (diff)
LOK: Validate cached queued callback payloads
And with DBG_UTIL validate and dump LOK queue state. Change-Id: I211ddf89dbcecf17c4f1401e5d96919c4bc966ea Reviewed-on: https://gerrit.libreoffice.org/67893 Tested-by: Jenkins Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
-rw-r--r--desktop/inc/lib/init.hxx6
-rw-r--r--desktop/source/lib/init.cxx47
2 files changed, 53 insertions, 0 deletions
diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx
index f2f6f5399649..be96814820ce 100644
--- a/desktop/inc/lib/init.hxx
+++ b/desktop/inc/lib/init.hxx
@@ -111,8 +111,14 @@ namespace desktop {
/// Return the parsed JSON instance.
const boost::property_tree::ptree& getJson() const;
+ /// Validate that the payload and parsed object match.
+ bool validate() const;
+
int Type;
std::string PayloadString;
+
+ private:
+ /// The parsed payload cache. Update validate() when changing this.
boost::variant<boost::blank, RectangleAndPart, boost::property_tree::ptree> PayloadObject;
};
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 6b7f8d699e8d..c4edf05e16dc 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -464,6 +464,7 @@ RectangleAndPart& CallbackFlushHandler::CallbackData::setRectangleAndPart(const
const RectangleAndPart& CallbackFlushHandler::CallbackData::getRectangleAndPart() const
{
+ assert(PayloadObject.which() == 1);
return boost::get<RectangleAndPart>(PayloadObject);
}
@@ -491,9 +492,38 @@ void CallbackFlushHandler::CallbackData::setJson(const boost::property_tree::ptr
const boost::property_tree::ptree& CallbackFlushHandler::CallbackData::getJson() const
{
+ assert(PayloadObject.which() == 2);
return boost::get<boost::property_tree::ptree>(PayloadObject);
}
+bool CallbackFlushHandler::CallbackData::validate() const
+{
+ switch (PayloadObject.which())
+ {
+ // Not cached.
+ case 0:
+ return true;
+
+ // RectangleAndPart.
+ case 1:
+ return getRectangleAndPart().toString().getStr() == PayloadString;
+
+ // Json.
+ case 2:
+ {
+ std::stringstream aJSONStream;
+ boost::property_tree::write_json(aJSONStream, getJson(), false);
+ const std::string aExpected = boost::trim_copy(aJSONStream.str());
+ return aExpected == PayloadString;
+ }
+
+ default:
+ assert(!"Unknown variant type; please add an entry to validate.");
+ }
+
+ return false;
+}
+
}
namespace {
@@ -886,6 +916,20 @@ void CallbackFlushHandler::queue(const int type, const char* data)
std::string& payload = aCallbackData.PayloadString;
SAL_INFO("lok", "Queue: " << type << " : " << payload);
+#ifdef DBG_UTIL
+ {
+ // Dump the queue state and validate cached data.
+ int i = 1;
+ std::ostringstream oss;
+ oss << '\n';
+ for (const CallbackData& c : m_queue)
+ oss << i++ << ": [" << c.Type << "] [" << c.PayloadString << "].\n";
+ const std::string aQueued = oss.str();
+ SAL_INFO("lok", "Current Queue: " << (aQueued.empty() ? "Empty" : aQueued));
+ for (const CallbackData& c : m_queue)
+ assert(c.validate());
+ }
+#endif
if (m_bPartTilePainting)
{
@@ -1294,6 +1338,7 @@ void CallbackFlushHandler::queue(const int type, const char* data)
aTree.put("rectangle", aNewRect.toString().getStr());
aCallbackData.setJson(aTree);
+ assert(aCallbackData.validate() && "Validation after setJson failed!");
}
}
}
@@ -1301,6 +1346,8 @@ void CallbackFlushHandler::queue(const int type, const char* data)
}
}
+ // Validate that the cached data and the payload string are identical.
+ assert(aCallbackData.validate() && "Cached callback payload object and string mismatch!");
m_queue.emplace_back(aCallbackData);
SAL_INFO("lok", "Queued #" << (m_queue.size() - 1) <<
" [" << type << "]: [" << payload << "] to have " << m_queue.size() << " entries.");