From 3948e6b783c15f3d3a2f1a2a89aaef3f5b0a26ee Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 24 Aug 2017 17:23:52 +0100 Subject: In the event of an error handling/processing SI table data, discard any progress so far before propergating the exception --- p2pvr/daemon/unittests/testErrorHandling.cpp | 17 ++++++++++ p2pvr/dvb/siParsers/table.impl.h | 47 ++++++++++++++++------------ 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/p2pvr/daemon/unittests/testErrorHandling.cpp b/p2pvr/daemon/unittests/testErrorHandling.cpp index 5b53999..be44ebc 100644 --- a/p2pvr/daemon/unittests/testErrorHandling.cpp +++ b/p2pvr/daemon/unittests/testErrorHandling.cpp @@ -66,6 +66,14 @@ class FailingTestNetworkParser : public SiNetworkInformationParser { throw DataHandlingException(); } }; + +class BrokenTestNetworkParser : public SiNetworkInformationParser { + public: + bool HandleTable(const ::DVBSI::NetworkPtr &) override + { + throw std::runtime_error("Unexpected"); + } +}; } } @@ -109,5 +117,14 @@ BOOST_AUTO_TEST_CASE(TestParserWithError) BOOST_REQUIRE_THROW(devices->SendNetworkInformation(del, a), DataHandlingException); } +BOOST_AUTO_TEST_CASE(TestParserBroken) +{ + BOOST_TEST_CHECKPOINT("Setup"); + auto del = si->GetDeliveryForSi(); + TemporaryIceAdapterObject a(getAdapter(), new BrokenTestNetworkParser()); + BOOST_TEST_CHECKPOINT("Make failing call"); + BOOST_REQUIRE_THROW(devices->SendNetworkInformation(del, a), Ice::UnknownException); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/p2pvr/dvb/siParsers/table.impl.h b/p2pvr/dvb/siParsers/table.impl.h index aa2fa1e..6e8bd0f 100644 --- a/p2pvr/dvb/siParsers/table.impl.h +++ b/p2pvr/dvb/siParsers/table.impl.h @@ -40,29 +40,36 @@ namespace P2PVR { if (!obj) { obj = TargetType(new typename TargetType::element_type()); } - ParseSiTable(siTable, obj); - seen.insert(sectionNumber); - bool complete = true; - for (int tid = FirstTableId(siTable); tid <= LastTableId(siTable); tid += 1) { - TableTargetSections::const_iterator tts = targetTableSections.find(tid); - if (tts == targetTableSections.end()) { - complete = false; - break; + try { + ParseSiTable(siTable, obj); + seen.insert(sectionNumber); + bool complete = true; + for (int tid = FirstTableId(siTable); tid <= LastTableId(siTable); tid += 1) { + TableTargetSections::const_iterator tts = targetTableSections.find(tid); + if (tts == targetTableSections.end()) { + complete = false; + break; + } + if (boost::get<1>(tts->second).size() <= boost::get<0>(tts->second)) { + complete = false; + break; + } } - if (boost::get<1>(tts->second).size() <= boost::get<0>(tts->second)) { - complete = false; - break; + if (complete) { + if (HandleTable(obj)) { + targetTableSections.clear(); + } + else { + obj = TargetType(); + } + parents.erase(contentId); + completed = parents.empty(); } } - if (complete) { - if (HandleTable(obj)) { - targetTableSections.clear(); - } - else { - obj = TargetType(); - } - parents.erase(contentId); - completed = parents.empty(); + catch (...) { + seen.clear(); + obj = TargetType(); + throw; } } } -- cgit v1.2.3