encoding: in Block::blockFromValue(), fail early if TLV length is zero
Also add a test for the boost::asio::const_buffer conversion operator
Change-Id: I312e8cba21ee1e6c29f3fb90485fa2932a2e5fb2
diff --git a/ndn-cxx/encoding/block.cpp b/ndn-cxx/encoding/block.cpp
index 8314c7d..2c40fdb 100644
--- a/ndn-cxx/encoding/block.cpp
+++ b/ndn-cxx/encoding/block.cpp
@@ -313,8 +313,9 @@
Block
Block::blockFromValue() const
{
- if (!hasValue())
- NDN_THROW(Error("Block has no TLV-VALUE"));
+ if (value_size() == 0) {
+ NDN_THROW(Error("Cannot construct block from empty TLV-VALUE"));
+ }
return Block(*this, m_valueBegin, m_valueEnd, true);
}
@@ -327,12 +328,11 @@
if (!m_elements.empty() || value_size() == 0)
return;
- Buffer::const_iterator begin = value_begin();
- Buffer::const_iterator end = value_end();
+ auto begin = value_begin();
+ auto end = value_end();
while (begin != end) {
- Buffer::const_iterator pos = begin;
-
+ auto pos = begin;
uint32_t type = tlv::readType(pos, end);
uint64_t length = tlv::readVarNumber(pos, end);
if (length > static_cast<uint64_t>(end - pos)) {
@@ -342,7 +342,7 @@
}
// pos now points to TLV-VALUE of sub element
- Buffer::const_iterator subEnd = pos + length;
+ auto subEnd = pos + length;
m_elements.emplace_back(m_buffer, type, begin, subEnd, pos, subEnd);
begin = subEnd;
@@ -471,7 +471,7 @@
Block::operator boost::asio::const_buffer() const
{
- return boost::asio::const_buffer(wire(), size());
+ return {wire(), size()};
}
bool
diff --git a/tests/unit/encoding/block.t.cpp b/tests/unit/encoding/block.t.cpp
index fda45ca..b6a841b 100644
--- a/tests/unit/encoding/block.t.cpp
+++ b/tests/unit/encoding/block.t.cpp
@@ -24,6 +24,7 @@
#include "tests/boost-test.hpp"
+#include <boost/asio/buffer.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/test/data/test_case.hpp>
@@ -419,6 +420,28 @@
BOOST_AUTO_TEST_SUITE_END() // Construction
+BOOST_AUTO_TEST_CASE(BlockFromValue)
+{
+ Block b1(301);
+ BOOST_CHECK_EXCEPTION(b1.blockFromValue(), Block::Error, [] (const auto& e) {
+ return e.what() == "Cannot construct block from empty TLV-VALUE"s;
+ });
+
+ Block b2(302, make_shared<Buffer>());
+ BOOST_CHECK_EXCEPTION(b2.blockFromValue(), Block::Error, [] (const auto& e) {
+ return e.what() == "Cannot construct block from empty TLV-VALUE"s;
+ });
+
+ b1.encode();
+ Block b3(303, b1);
+ b3.encode();
+ Block nested = b3.blockFromValue();
+ BOOST_CHECK_EQUAL(nested.type(), 301);
+ BOOST_CHECK_EQUAL(nested.size(), 4);
+ BOOST_CHECK_EQUAL(nested.value_size(), 0);
+ BOOST_CHECK(nested == b1);
+}
+
BOOST_AUTO_TEST_SUITE(SubElements)
BOOST_AUTO_TEST_CASE(Parse)
@@ -600,6 +623,14 @@
BOOST_AUTO_TEST_SUITE_END() // SubElements
+BOOST_AUTO_TEST_CASE(ToAsioConstBuffer)
+{
+ Block block = "0101A0"_block;
+ boost::asio::const_buffer buffer(block);
+ BOOST_CHECK_EQUAL(boost::asio::buffer_cast<const uint8_t*>(buffer), block.wire());
+ BOOST_CHECK_EQUAL(boost::asio::buffer_size(buffer), block.size());
+}
+
BOOST_AUTO_TEST_CASE(Equality)
{
const uint8_t one[] = {0x08, 0x00};