interest+data: forbid unrecognized TLV before Name
Change-Id: Id052b02be0aa3e36064c40872cee37f9c8dd3a78
diff --git a/src/data.cpp b/src/data.cpp
index 169d99c..f72673f 100644
--- a/src/data.cpp
+++ b/src/data.cpp
@@ -121,74 +121,73 @@
void
Data::wireDecode(const Block& wire)
{
+ // Data ::= DATA-TLV TLV-LENGTH
+ // Name
+ // MetaInfo?
+ // Content?
+ // SignatureInfo
+ // SignatureValue
+
m_wire = wire;
m_wire.parse();
- bool hasName = false, hasSigInfo = false;
- m_name.clear();
+
+ auto element = m_wire.elements_begin();
+ if (element == m_wire.elements_end() || element->type() != tlv::Name) {
+ BOOST_THROW_EXCEPTION(Error("Name element is missing or out of order"));
+ }
+ m_name.wireDecode(*element);
+ int lastElement = 1; // last recognized element index, in spec order
+
m_metaInfo = MetaInfo();
m_content = Block(tlv::Content);
m_signature = Signature();
m_fullName.clear();
- int lastEle = 0; // last recognized element index, in spec order
- for (const Block& ele : m_wire.elements()) {
- switch (ele.type()) {
- case tlv::Name: {
- if (lastEle >= 1) {
- BOOST_THROW_EXCEPTION(Error("Name element is out of order"));
- }
- hasName = true;
- m_name.wireDecode(ele);
- lastEle = 1;
- break;
- }
+ for (++element; element != m_wire.elements_end(); ++element) {
+ switch (element->type()) {
case tlv::MetaInfo: {
- if (lastEle >= 2) {
+ if (lastElement >= 2) {
BOOST_THROW_EXCEPTION(Error("MetaInfo element is out of order"));
}
- m_metaInfo.wireDecode(ele);
- lastEle = 2;
+ m_metaInfo.wireDecode(*element);
+ lastElement = 2;
break;
}
case tlv::Content: {
- if (lastEle >= 3) {
+ if (lastElement >= 3) {
BOOST_THROW_EXCEPTION(Error("Content element is out of order"));
}
- m_content = ele;
- lastEle = 3;
+ m_content = *element;
+ lastElement = 3;
break;
}
case tlv::SignatureInfo: {
- if (lastEle >= 4) {
+ if (lastElement >= 4) {
BOOST_THROW_EXCEPTION(Error("SignatureInfo element is out of order"));
}
- hasSigInfo = true;
- m_signature.setInfo(ele);
- lastEle = 4;
+ m_signature.setInfo(*element);
+ lastElement = 4;
break;
}
case tlv::SignatureValue: {
- if (lastEle >= 5) {
+ if (lastElement >= 5) {
BOOST_THROW_EXCEPTION(Error("SignatureValue element is out of order"));
}
- m_signature.setValue(ele);
- lastEle = 5;
+ m_signature.setValue(*element);
+ lastElement = 5;
break;
}
default: {
- if (tlv::isCriticalType(ele.type())) {
+ if (tlv::isCriticalType(element->type())) {
BOOST_THROW_EXCEPTION(Error("unrecognized element of critical type " +
- to_string(ele.type())));
+ to_string(element->type())));
}
break;
}
}
}
- if (!hasName) {
- BOOST_THROW_EXCEPTION(Error("Name element is missing"));
- }
- if (!hasSigInfo) {
+ if (!m_signature) {
BOOST_THROW_EXCEPTION(Error("SignatureInfo element is missing"));
}
}
diff --git a/src/interest.cpp b/src/interest.cpp
index 50f5a13..0e845e3 100644
--- a/src/interest.cpp
+++ b/src/interest.cpp
@@ -305,33 +305,29 @@
// HopLimit?
// Parameters?
- bool hasName = false;
+ auto element = m_wire.elements_begin();
+ if (element == m_wire.elements_end() || element->type() != tlv::Name) {
+ BOOST_THROW_EXCEPTION(Error("Name element is missing or out of order"));
+ }
+ m_name.wireDecode(*element);
+ if (m_name.empty()) {
+ BOOST_THROW_EXCEPTION(Error("Name has zero name components"));
+ }
+ int lastElement = 1; // last recognized element index, in spec order
+
m_selectors = Selectors().setMaxSuffixComponents(1); // CanBePrefix=0
m_nonce.reset();
m_interestLifetime = DEFAULT_INTEREST_LIFETIME;
m_forwardingHint = DelegationList();
m_parameters = Block();
- int lastElement = 0; // last recognized element index, in spec order
- for (const Block& element : m_wire.elements()) {
- switch (element.type()) {
- case tlv::Name: {
- if (lastElement >= 1) {
- BOOST_THROW_EXCEPTION(Error("Name element is out of order"));
- }
- hasName = true;
- m_name.wireDecode(element);
- if (m_name.empty()) {
- BOOST_THROW_EXCEPTION(Error("Name has zero name components"));
- }
- lastElement = 1;
- break;
- }
+ for (++element; element != m_wire.elements_end(); ++element) {
+ switch (element->type()) {
case tlv::CanBePrefix: {
if (lastElement >= 2) {
BOOST_THROW_EXCEPTION(Error("CanBePrefix element is out of order"));
}
- if (element.value_size() != 0) {
+ if (element->value_size() != 0) {
BOOST_THROW_EXCEPTION(Error("CanBePrefix element has non-zero TLV-LENGTH"));
}
m_selectors.setMaxSuffixComponents(-1);
@@ -342,7 +338,7 @@
if (lastElement >= 3) {
BOOST_THROW_EXCEPTION(Error("MustBeFresh element is out of order"));
}
- if (element.value_size() != 0) {
+ if (element->value_size() != 0) {
BOOST_THROW_EXCEPTION(Error("MustBeFresh element has non-zero TLV-LENGTH"));
}
m_selectors.setMustBeFresh(true);
@@ -353,7 +349,7 @@
if (lastElement >= 4) {
BOOST_THROW_EXCEPTION(Error("ForwardingHint element is out of order"));
}
- m_forwardingHint.wireDecode(element);
+ m_forwardingHint.wireDecode(*element);
lastElement = 4;
break;
}
@@ -362,10 +358,10 @@
BOOST_THROW_EXCEPTION(Error("Nonce element is out of order"));
}
uint32_t nonce = 0;
- if (element.value_size() != sizeof(nonce)) {
+ if (element->value_size() != sizeof(nonce)) {
BOOST_THROW_EXCEPTION(Error("Nonce element is malformed"));
}
- std::memcpy(&nonce, element.value(), sizeof(nonce));
+ std::memcpy(&nonce, element->value(), sizeof(nonce));
m_nonce = nonce;
lastElement = 5;
break;
@@ -374,7 +370,7 @@
if (lastElement >= 6) {
BOOST_THROW_EXCEPTION(Error("InterestLifetime element is out of order"));
}
- m_interestLifetime = time::milliseconds(readNonNegativeInteger(element));
+ m_interestLifetime = time::milliseconds(readNonNegativeInteger(*element));
lastElement = 6;
break;
}
@@ -382,7 +378,7 @@
if (lastElement >= 7) {
break; // HopLimit is non-critical, ignore out-of-order appearance
}
- if (element.value_size() != 1) {
+ if (element->value_size() != 1) {
BOOST_THROW_EXCEPTION(Error("HopLimit element is malformed"));
}
// TLV-VALUE is ignored
@@ -393,23 +389,19 @@
if (lastElement >= 8) {
BOOST_THROW_EXCEPTION(Error("Parameters element is out of order"));
}
- m_parameters = element;
+ m_parameters = *element;
lastElement = 8;
break;
}
default: {
- if (tlv::isCriticalType(element.type())) {
+ if (tlv::isCriticalType(element->type())) {
BOOST_THROW_EXCEPTION(Error("unrecognized element of critical type " +
- to_string(element.type())));
+ to_string(element->type())));
}
break;
}
}
}
-
- if (!hasName) {
- BOOST_THROW_EXCEPTION(Error("Name element is missing"));
- }
}
std::string