exclude: Allow excluding empty name component
Change-Id: I6eb835aec30db7dc0cd36a5b17f0a34693d34c42
Fixes: #2660
diff --git a/src/exclude.cpp b/src/exclude.cpp
index 89d052d..76a6260 100644
--- a/src/exclude.cpp
+++ b/src/exclude.cpp
@@ -24,6 +24,8 @@
#include "exclude.hpp"
#include "util/concepts.hpp"
+#include <boost/range/adaptors.hpp>
+
namespace ndn {
BOOST_CONCEPT_ASSERT((boost::EqualityComparable<Exclude>));
@@ -54,17 +56,14 @@
// Exclude ::= EXCLUDE-TYPE TLV-LENGTH Any? (NameComponent (Any)?)+
// Any ::= ANY-TYPE TLV-LENGTH(=0)
- for (Exclude::const_iterator i = m_exclude.begin(); i != m_exclude.end(); i++)
- {
- if (i->second)
- {
- totalLength += prependBooleanBlock(block, tlv::Any);
- }
- if (!i->first.empty())
- {
- totalLength += i->first.wireEncode(block);
- }
+ for (const auto& item : m_exclude) {
+ if (item.second) {
+ totalLength += prependBooleanBlock(block, tlv::Any);
}
+ if (!item.first.empty() || !item.second) {
+ totalLength += item.first.wireEncode(block);
+ }
+ }
totalLength += block.prependVarNumber(totalLength);
totalLength += block.prependVarNumber(tlv::Exclude);
@@ -112,41 +111,35 @@
// Any ::= ANY-TYPE TLV-LENGTH(=0)
Block::element_const_iterator i = m_wire.elements_begin();
- if (i->type() == tlv::Any)
- {
- appendExclude(name::Component(), true);
- ++i;
+ if (i->type() == tlv::Any) {
+ appendExclude(name::Component(), true);
+ ++i;
+ }
+
+ while (i != m_wire.elements_end()) {
+ name::Component excludedComponent;
+ try {
+ excludedComponent = std::move(name::Component(*i));
+ }
+ catch (const name::Component::Error&) {
+ throw Error("Incorrect format of Exclude filter");
}
- while (i != m_wire.elements_end())
- {
- name::Component excludedComponent;
- try {
- excludedComponent = std::move(name::Component(*i));
- }
- catch (const name::Component::Error&) {
- throw Error("Incorrect format of Exclude filter");
- }
+ ++i;
- ++i;
-
- if (i != m_wire.elements_end())
- {
- if (i->type() == tlv::Any)
- {
- appendExclude(excludedComponent, true);
- ++i;
- }
- else
- {
- appendExclude(excludedComponent, false);
- }
- }
- else
- {
- appendExclude(excludedComponent, false);
- }
+ if (i != m_wire.elements_end()) {
+ if (i->type() == tlv::Any) {
+ appendExclude(excludedComponent, true);
+ ++i;
+ }
+ else {
+ appendExclude(excludedComponent, false);
+ }
}
+ else {
+ appendExclude(excludedComponent, false);
+ }
+ }
}
// example: ANY /b /d ANY /f
@@ -172,18 +165,15 @@
return true;
else
return lowerBound->first == comp;
-
- return false;
}
Exclude&
Exclude::excludeOne(const name::Component& comp)
{
- if (!isExcluded(comp))
- {
- m_exclude.insert(std::make_pair(comp, false));
- m_wire.reset();
- }
+ if (!isExcluded(comp)) {
+ m_exclude.insert(std::make_pair(comp, false));
+ m_wire.reset();
+ }
return *this;
}
@@ -236,9 +226,9 @@
iterator newTo = m_exclude.lower_bound(to); // !newTo cannot be end()
if (newTo == newFrom || !newTo->second) {
- std::pair<iterator, bool> toResult = m_exclude.insert(std::make_pair(to, false));
- newTo = toResult.first;
- ++ newTo;
+ std::pair<iterator, bool> toResult = m_exclude.insert(std::make_pair(to, false));
+ newTo = toResult.first;
+ ++ newTo;
}
// else
// nothing to do really
@@ -276,17 +266,19 @@
std::ostream&
operator<<(std::ostream& os, const Exclude& exclude)
{
- bool empty = true;
- for (Exclude::const_reverse_iterator i = exclude.rbegin(); i != exclude.rend(); i++) {
- if (!i->first.empty()) {
- if (!empty) os << ",";
- os << i->first.toUri();
- empty = false;
+ bool isFirst = true;
+ for (const auto& item : exclude | boost::adaptors::reversed) {
+ if (!item.first.empty() || !item.second) {
+ if (!isFirst)
+ os << ",";
+ os << item.first.toUri();
+ isFirst = false;
}
- if (i->second) {
- if (!empty) os << ",";
+ if (item.second) {
+ if (!isFirst)
+ os << ",";
os << "*";
- empty = false;
+ isFirst = false;
}
}
return os;
diff --git a/src/name-component.hpp b/src/name-component.hpp
index 4e6119b..0ed3759 100644
--- a/src/name-component.hpp
+++ b/src/name-component.hpp
@@ -494,7 +494,7 @@
bool
empty() const
{
- return !hasValue();
+ return !hasValue() || value_size() == 0;
}
Component
diff --git a/tests/unit-tests/exclude.t.cpp b/tests/unit-tests/exclude.t.cpp
index 88b692a..ce2892e 100644
--- a/tests/unit-tests/exclude.t.cpp
+++ b/tests/unit-tests/exclude.t.cpp
@@ -219,6 +219,28 @@
BOOST_CHECK_NO_THROW(exclude.wireDecode(block));
}
+BOOST_AUTO_TEST_CASE(ExcludeEmptyComponent) // Bug #2660
+{
+ Exclude e1, e2;
+
+ e1.excludeOne(name::Component());
+ e2.excludeOne(name::Component(""));
+
+ BOOST_CHECK_EQUAL(e1, e2);
+ BOOST_CHECK_EQUAL(e1.toUri(), e2.toUri());
+ BOOST_CHECK(e1.wireEncode() == e2.wireEncode());
+
+ BOOST_CHECK_EQUAL("...", e1.toUri());
+
+ uint8_t WIRE[] {0x10, 0x02, 0x08, 0x00};
+ BOOST_CHECK_EQUAL_COLLECTIONS(e1.wireEncode().begin(), e1.wireEncode().end(),
+ WIRE, WIRE + sizeof(WIRE));
+
+ Exclude e3(Block(WIRE, sizeof(WIRE)));
+ BOOST_CHECK_EQUAL(e1, e3);
+ BOOST_CHECK_EQUAL(e1.toUri(), e3.toUri());
+}
+
BOOST_AUTO_TEST_SUITE_END()
} // namespace tests