mgmt: fix Dispatcher::processControlCommandInterest memory error
refs #4059
Change-Id: I6655662f925bc5f40a2a2ec2b258a4accc29d58b
diff --git a/src/mgmt/dispatcher.cpp b/src/mgmt/dispatcher.cpp
index b9d62a2..62f9114 100644
--- a/src/mgmt/dispatcher.cpp
+++ b/src/mgmt/dispatcher.cpp
@@ -218,7 +218,7 @@
return;
}
- AcceptContinuation accept = bind(accepted, _1, prefix, interest, parameters.get());
+ AcceptContinuation accept = bind(accepted, _1, prefix, interest, parameters);
RejectContinuation reject = bind(rejected, _1, interest);
authorization(prefix, interest, parameters.get(), accept, reject);
}
@@ -227,7 +227,7 @@
Dispatcher::processAuthorizedControlCommandInterest(const std::string& requester,
const Name& prefix,
const Interest& interest,
- const ControlParameters* parameters,
+ const shared_ptr<ControlParameters>& parameters,
const ValidateParameters& validateParams,
const ControlCommandHandler& handler)
{
diff --git a/src/mgmt/dispatcher.hpp b/src/mgmt/dispatcher.hpp
index 7df61f7..a8b30b4 100644
--- a/src/mgmt/dispatcher.hpp
+++ b/src/mgmt/dispatcher.hpp
@@ -291,7 +291,7 @@
typedef std::function<void(const std::string& requester,
const Name& prefix,
const Interest& interest,
- const ControlParameters*)> AuthorizationAcceptedCallback;
+ const shared_ptr<ControlParameters>&)> AuthorizationAcceptedCallback;
typedef std::function<void(RejectReply act,
const Interest& interest)> AuthorizationRejectedCallback;
@@ -399,7 +399,7 @@
processAuthorizedControlCommandInterest(const std::string& requester,
const Name& prefix,
const Interest& interest,
- const ControlParameters* parameters,
+ const shared_ptr<ControlParameters>& parameters,
const ValidateParameters& validate,
const ControlCommandHandler& handler);
@@ -484,11 +484,11 @@
const ControlCommandHandler& handler)
{
if (!m_topLevelPrefixes.empty()) {
- throw std::domain_error("one or more top-level prefix has been added");
+ BOOST_THROW_EXCEPTION(std::domain_error("one or more top-level prefix has been added"));
}
if (isOverlappedWithOthers(relPrefix)) {
- throw std::out_of_range("relPrefix overlaps with another relPrefix");
+ BOOST_THROW_EXCEPTION(std::out_of_range("relPrefix overlaps with another relPrefix"));
}
ControlParametersParser parser =
diff --git a/tests/unit-tests/mgmt/dispatcher.t.cpp b/tests/unit-tests/mgmt/dispatcher.t.cpp
index a1506a0..96623f5 100644
--- a/tests/unit-tests/mgmt/dispatcher.t.cpp
+++ b/tests/unit-tests/mgmt/dispatcher.t.cpp
@@ -34,9 +34,6 @@
using namespace ndn::tests;
-BOOST_AUTO_TEST_SUITE(Mgmt)
-BOOST_AUTO_TEST_SUITE(TestDispatcher)
-
class DispatcherFixture : public IdentityManagementV1TimeFixture
{
public:
@@ -62,17 +59,17 @@
wireDecode(wire);
}
- virtual Block
+ Block
wireEncode() const final
{
return Block(128);
}
- virtual void
+ void
wireDecode(const Block& wire) final
{
if (wire.type() != 128)
- throw tlv::Error("Expecting TLV type 128");
+ BOOST_THROW_EXCEPTION(tlv::Error("Expecting TLV type 128"));
}
};
@@ -98,7 +95,10 @@
};
}
-BOOST_FIXTURE_TEST_CASE(Basic, DispatcherFixture)
+BOOST_AUTO_TEST_SUITE(Mgmt)
+BOOST_FIXTURE_TEST_SUITE(TestDispatcher, DispatcherFixture)
+
+BOOST_AUTO_TEST_CASE(Basic)
{
BOOST_CHECK_NO_THROW(dispatcher
.addControlCommand<VoidParameters>("test/1", makeAcceptAllAuthorization(),
@@ -145,7 +145,7 @@
BOOST_CHECK_THROW(dispatcher.addNotificationStream("stream/3"), std::domain_error);
}
-BOOST_FIXTURE_TEST_CASE(AddRemoveTopPrefix, DispatcherFixture)
+BOOST_AUTO_TEST_CASE(AddRemoveTopPrefix)
{
std::map<std::string, size_t> nCallbackCalled;
dispatcher
@@ -205,7 +205,7 @@
BOOST_CHECK_EQUAL(nCallbackCalled["test/1"], 4);
}
-BOOST_FIXTURE_TEST_CASE(ControlCommand, DispatcherFixture)
+BOOST_AUTO_TEST_CASE(ControlCommand)
{
size_t nCallbackCalled = 0;
dispatcher
@@ -237,7 +237,73 @@
BOOST_CHECK_EQUAL(nCallbackCalled, 1);
}
-BOOST_FIXTURE_TEST_CASE(StatusDataset, DispatcherFixture)
+class StatefulParameters : public mgmt::ControlParameters
+{
+public:
+ explicit
+ StatefulParameters(const Block& wire)
+ {
+ wireDecode(wire);
+ }
+
+ Block
+ wireEncode() const final
+ {
+ return Block();
+ }
+
+ void
+ wireDecode(const Block& wire) final
+ {
+ m_state = EXPECTED_STATE;
+ }
+
+ bool
+ check() const
+ {
+ return m_state == EXPECTED_STATE;
+ }
+
+private:
+ static constexpr int EXPECTED_STATE = 12602;
+ int m_state = 0;
+};
+
+BOOST_AUTO_TEST_CASE(ControlCommandAsyncAuthorization) // Bug 4059
+{
+ AcceptContinuation authorizationAccept;
+ auto authorization =
+ [&authorizationAccept] (const Name& prefix, const Interest& interest, const ControlParameters* params,
+ AcceptContinuation accept, RejectContinuation reject) {
+ authorizationAccept = accept;
+ };
+
+ auto validateParameters =
+ [] (const ControlParameters& params) {
+ return dynamic_cast<const StatefulParameters&>(params).check();
+ };
+
+ size_t nCallbackCalled = 0;
+ dispatcher
+ .addControlCommand<StatefulParameters>("test",
+ authorization,
+ validateParameters,
+ bind([&nCallbackCalled] { ++nCallbackCalled; }));
+
+ dispatcher.addTopPrefix("/root");
+ advanceClocks(time::milliseconds(1));
+
+ face.receive(*makeInterest("/root/test/%80%00"));
+ BOOST_CHECK_EQUAL(nCallbackCalled, 0);
+ BOOST_REQUIRE(authorizationAccept != nullptr);
+
+ advanceClocks(time::milliseconds(1));
+ authorizationAccept("");
+ advanceClocks(time::milliseconds(1));
+ BOOST_CHECK_EQUAL(nCallbackCalled, 1);
+}
+
+BOOST_AUTO_TEST_CASE(StatusDataset)
{
static Block smallBlock("\x81\x01\0x01", 3);
static Block largeBlock = [] () -> Block {
@@ -369,7 +435,7 @@
BOOST_CHECK_EQUAL(storage.size(), 0); // the nack packet will not be inserted into the in-memory storage
}
-BOOST_FIXTURE_TEST_CASE(NotificationStream, DispatcherFixture)
+BOOST_AUTO_TEST_CASE(NotificationStream)
{
static Block block("\x82\x01\x02", 3);