blob: 2c759444d18380ab6679777c34401811fed058e1 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shidb7464d2017-07-13 03:11:17 +00002/*
Davide Pesaventofbea4fc2022-02-08 07:26:04 -05003 * Copyright (c) 2013-2022 Regents of the University of California.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
Alexander Afanasyev233750e2014-02-16 00:50:07 -080020 */
21
Davide Pesavento7e780642018-11-24 15:51:34 -050022#include "ndn-cxx/encoding/block.hpp"
23#include "ndn-cxx/encoding/block-helpers.hpp"
Alexander Afanasyev233750e2014-02-16 00:50:07 -080024
Davide Pesavento7e780642018-11-24 15:51:34 -050025#include "tests/boost-test.hpp"
26
Davide Pesaventoa76ea9a2021-04-24 00:06:02 -040027#include <boost/asio/buffer.hpp>
Junxiao Shi72c0c642018-04-20 15:41:09 +000028#include <boost/lexical_cast.hpp>
Davide Pesavento1a4a7bf2020-12-04 22:30:46 -050029#include <boost/test/data/test_case.hpp>
Davide Pesavento6b330402019-04-24 00:14:01 -040030
Junxiao Shidc4277a2017-07-17 11:34:02 +000031#include <cstring>
32#include <sstream>
Davide Pesaventoeee3e822016-11-26 19:19:34 +010033
Alexander Afanasyev233750e2014-02-16 00:50:07 -080034namespace ndn {
Alexander Afanasyev74633892015-02-08 18:08:46 -080035namespace tests {
Alexander Afanasyev233750e2014-02-16 00:50:07 -080036
Davide Pesaventoeee3e822016-11-26 19:19:34 +010037BOOST_AUTO_TEST_SUITE(Encoding)
38BOOST_AUTO_TEST_SUITE(TestBlock)
Alexander Afanasyev233750e2014-02-16 00:50:07 -080039
Junxiao Shidc4277a2017-07-17 11:34:02 +000040BOOST_AUTO_TEST_SUITE(Construction)
41
42static const uint8_t TEST_BUFFER[] = {
Davide Pesavento6b330402019-04-24 00:14:01 -040043 0x42, 0x01, 0xfa,
44 0x01, 0x01, 0xfb,
45 0xfe, 0xff, 0xff, 0xff, 0xff, 0x00, // bug #4726
Alexander Afanasyev74633892015-02-08 18:08:46 -080046};
Alexander Afanasyev2d0b4572014-02-24 16:02:12 -080047
Davide Pesavento6b330402019-04-24 00:14:01 -040048BOOST_AUTO_TEST_CASE(Default)
Alexander Afanasyev74633892015-02-08 18:08:46 -080049{
Junxiao Shidc4277a2017-07-17 11:34:02 +000050 Block b;
Davide Pesavento6b330402019-04-24 00:14:01 -040051
52 BOOST_CHECK_EQUAL(b.isValid(), false);
Davide Pesavento6b330402019-04-24 00:14:01 -040053 BOOST_CHECK_EQUAL(b.type(), tlv::Invalid);
54 BOOST_CHECK_EQUAL(b.hasValue(), false);
55 BOOST_CHECK_EQUAL(b.value_size(), 0);
Davide Pesavento258d51a2022-02-27 21:26:28 -050056 BOOST_CHECK_EQUAL(b.value_bytes().empty(), true);
Davide Pesavento6b330402019-04-24 00:14:01 -040057 BOOST_CHECK(b.value() == nullptr);
58
Davide Pesavento6b330402019-04-24 00:14:01 -040059 BOOST_CHECK_THROW(b.begin(), Block::Error);
60 BOOST_CHECK_THROW(b.end(), Block::Error);
Davide Pesavento258d51a2022-02-27 21:26:28 -050061 BOOST_CHECK_THROW(b.data(), Block::Error);
62 BOOST_CHECK_THROW(b.size(), Block::Error);
Davide Pesavento6b330402019-04-24 00:14:01 -040063 BOOST_CHECK_THROW(b.blockFromValue(), Block::Error);
Alexander Afanasyev74633892015-02-08 18:08:46 -080064}
Alexander Afanasyev937aa782014-03-21 13:17:57 -070065
Junxiao Shidc4277a2017-07-17 11:34:02 +000066BOOST_AUTO_TEST_CASE(FromEncodingBuffer)
Alexander Afanasyev74633892015-02-08 18:08:46 -080067{
Junxiao Shidc4277a2017-07-17 11:34:02 +000068 EncodingBuffer encoder;
Davide Pesavento5c803b92019-02-02 19:23:48 -050069 BOOST_CHECK_THROW(Block{encoder}, tlv::Error);
70
71 const uint8_t VALUE[] = {0x11, 0x12, 0x13, 0x14};
Davide Pesaventofbea4fc2022-02-08 07:26:04 -050072 size_t length = encoder.prependBytes(VALUE);
Junxiao Shidc4277a2017-07-17 11:34:02 +000073 encoder.prependVarNumber(length);
74 encoder.prependVarNumber(0xe0);
75
76 Block b = encoder.block();
77 BOOST_CHECK_EQUAL(b.type(), 0xe0);
78 BOOST_CHECK_EQUAL(b.value_size(), sizeof(VALUE));
79 BOOST_CHECK_EQUAL_COLLECTIONS(b.value_begin(), b.value_end(),
80 VALUE, VALUE + sizeof(VALUE));
81
82 b = Block(encoder);
83 BOOST_CHECK_EQUAL(b.type(), 0xe0);
84 BOOST_CHECK_EQUAL(b.value_size(), sizeof(VALUE));
85 BOOST_CHECK_EQUAL_COLLECTIONS(b.value_begin(), b.value_end(),
86 VALUE, VALUE + sizeof(VALUE));
Alexander Afanasyev74633892015-02-08 18:08:46 -080087}
Alexander Afanasyev937aa782014-03-21 13:17:57 -070088
Davide Pesaventoeee3e822016-11-26 19:19:34 +010089BOOST_AUTO_TEST_CASE(FromBlock)
Alexander Afanasyev4448d292015-08-09 20:11:37 -070090{
Davide Pesaventofbea4fc2022-02-08 07:26:04 -050091 const uint8_t buf[] = {0x80, 0x06, 0x81, 0x01, 0x01, 0x82, 0x01, 0x01};
92 Block block(buf);
Alexander Afanasyev4448d292015-08-09 20:11:37 -070093
94 Block derivedBlock(block, block.begin(), block.end());
Davide Pesavento258d51a2022-02-27 21:26:28 -050095 BOOST_CHECK_EQUAL(derivedBlock.data(), block.data()); // pointers should match
Davide Pesaventofbea4fc2022-02-08 07:26:04 -050096 BOOST_CHECK_EQUAL(derivedBlock, block); // blocks should match
Alexander Afanasyev4448d292015-08-09 20:11:37 -070097
98 derivedBlock = Block(block, block.begin() + 2, block.begin() + 5);
99 BOOST_CHECK(derivedBlock.begin() == block.begin() + 2);
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500100 BOOST_CHECK_EQUAL(derivedBlock, Block(make_span(buf + 2, 3)));
Alexander Afanasyev4448d292015-08-09 20:11:37 -0700101
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500102 Buffer otherBuffer(buf, sizeof(buf));
Junxiao Shidb7464d2017-07-13 03:11:17 +0000103 BOOST_CHECK_THROW(Block(block, otherBuffer.begin(), block.end()), std::invalid_argument);
104 BOOST_CHECK_THROW(Block(block, block.begin(), otherBuffer.end()), std::invalid_argument);
105 BOOST_CHECK_THROW(Block(block, otherBuffer.begin(), otherBuffer.end()), std::invalid_argument);
Alexander Afanasyev4448d292015-08-09 20:11:37 -0700106}
107
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100108BOOST_AUTO_TEST_CASE(FromBlockCopyOnWriteModifyOriginal)
Eric Newberry6235aac2015-08-13 16:03:47 -0700109{
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500110 const uint8_t buf[] = {
Eric Newberry6235aac2015-08-13 16:03:47 -0700111 0x05, 0x0b, 0x07, 0x03, 0x01, 0x02, 0x03, 0x0a, 0x04, 0x04, 0x05, 0x06, 0x07,
112 };
113
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500114 Block b1(buf);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000115 Block b2(b1, b1.begin(), b1.end());
116 auto buf2 = b2.getBuffer();
Eric Newberry6235aac2015-08-13 16:03:47 -0700117
Junxiao Shidc4277a2017-07-17 11:34:02 +0000118 b1.parse();
119 b1.remove(tlv::Name);
120 b1.encode();
Eric Newberry6235aac2015-08-13 16:03:47 -0700121
Junxiao Shidc4277a2017-07-17 11:34:02 +0000122 b2.parse();
Davide Pesaventodf8fd8a2022-02-21 20:04:21 -0500123 BOOST_TEST(b2 == buf, boost::test_tools::per_element());
124 BOOST_TEST(buf2 == b2.getBuffer()); // check pointers
Eric Newberry6235aac2015-08-13 16:03:47 -0700125}
126
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100127BOOST_AUTO_TEST_CASE(FromBlockCopyOnWriteModifyCopy)
Eric Newberry6235aac2015-08-13 16:03:47 -0700128{
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500129 const uint8_t buf[] = {
Eric Newberry6235aac2015-08-13 16:03:47 -0700130 0x05, 0x0b, 0x07, 0x03, 0x01, 0x02, 0x03, 0x0a, 0x04, 0x04, 0x05, 0x06, 0x07,
131 };
132
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500133 Block b1(buf);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000134 auto buf1 = b1.getBuffer();
Junxiao Shidc4277a2017-07-17 11:34:02 +0000135 Block b2(b1, b1.begin(), b1.end());
Eric Newberry6235aac2015-08-13 16:03:47 -0700136
Junxiao Shidc4277a2017-07-17 11:34:02 +0000137 b2.parse();
138 b2.remove(tlv::Name);
139 b2.encode();
Eric Newberry6235aac2015-08-13 16:03:47 -0700140
Junxiao Shidc4277a2017-07-17 11:34:02 +0000141 b1.parse();
Davide Pesaventodf8fd8a2022-02-21 20:04:21 -0500142 BOOST_TEST(b1 == buf, boost::test_tools::per_element());
143 BOOST_TEST(buf1 == b1.getBuffer()); // check pointers
Eric Newberry6235aac2015-08-13 16:03:47 -0700144}
145
Junxiao Shidc4277a2017-07-17 11:34:02 +0000146BOOST_AUTO_TEST_CASE(FromType)
Alexander Afanasyev233750e2014-02-16 00:50:07 -0800147{
Junxiao Shidc4277a2017-07-17 11:34:02 +0000148 Block b1(4);
Davide Pesavento6b330402019-04-24 00:14:01 -0400149 BOOST_CHECK_EQUAL(b1.isValid(), true);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000150 BOOST_CHECK_EQUAL(b1.type(), 4);
151 BOOST_CHECK_EQUAL(b1.size(), 2); // 1-octet TLV-TYPE and 1-octet TLV-LENGTH
Davide Pesavento5c803b92019-02-02 19:23:48 -0500152 BOOST_CHECK_EQUAL(b1.hasValue(), false);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000153 BOOST_CHECK_EQUAL(b1.value_size(), 0);
Davide Pesavento258d51a2022-02-27 21:26:28 -0500154 BOOST_CHECK_EQUAL(b1.value_bytes().empty(), true);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400155 BOOST_CHECK(b1.value() == nullptr);
Alexander Afanasyev233750e2014-02-16 00:50:07 -0800156
Junxiao Shidc4277a2017-07-17 11:34:02 +0000157 Block b2(258);
Davide Pesavento6b330402019-04-24 00:14:01 -0400158 BOOST_CHECK_EQUAL(b2.isValid(), true);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000159 BOOST_CHECK_EQUAL(b2.type(), 258);
160 BOOST_CHECK_EQUAL(b2.size(), 4); // 3-octet TLV-TYPE and 1-octet TLV-LENGTH
Davide Pesavento5c803b92019-02-02 19:23:48 -0500161 BOOST_CHECK_EQUAL(b2.hasValue(), false);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000162 BOOST_CHECK_EQUAL(b2.value_size(), 0);
Davide Pesavento258d51a2022-02-27 21:26:28 -0500163 BOOST_CHECK_EQUAL(b2.value_bytes().empty(), true);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400164 BOOST_CHECK(b2.value() == nullptr);
Davide Pesavento6b330402019-04-24 00:14:01 -0400165
166 Block b3(tlv::Invalid);
167 BOOST_CHECK_EQUAL(b3.isValid(), false);
168 BOOST_CHECK_EQUAL(b3.type(), tlv::Invalid);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400169 BOOST_CHECK_EXCEPTION(b3.size(), Block::Error, [] (const auto& e) {
170 return e.what() == "Cannot determine size of invalid block"s;
171 });
Davide Pesavento6b330402019-04-24 00:14:01 -0400172 BOOST_CHECK_EQUAL(b3.hasValue(), false);
173 BOOST_CHECK_EQUAL(b3.value_size(), 0);
Davide Pesavento258d51a2022-02-27 21:26:28 -0500174 BOOST_CHECK_EQUAL(b3.value_bytes().empty(), true);
Davide Pesavento6b330402019-04-24 00:14:01 -0400175 BOOST_CHECK(b3.value() == nullptr);
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700176}
177
Davide Pesavento5c803b92019-02-02 19:23:48 -0500178BOOST_AUTO_TEST_CASE(FromTypeAndBuffer)
179{
180 const uint8_t VALUE[] = {0x11, 0x12, 0x13, 0x14};
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500181 auto bufferPtr = std::make_shared<Buffer>(VALUE, sizeof(VALUE));
Davide Pesavento5c803b92019-02-02 19:23:48 -0500182
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400183 Block b1(42, std::move(bufferPtr));
184 BOOST_CHECK_EQUAL(b1.isValid(), true);
185 BOOST_CHECK_EQUAL(b1.type(), 42);
186 BOOST_CHECK_EQUAL(b1.size(), 6);
187 BOOST_CHECK_EQUAL(b1.hasValue(), true);
188 BOOST_CHECK_EQUAL(b1.value_size(), sizeof(VALUE));
Davide Pesavento258d51a2022-02-27 21:26:28 -0500189 BOOST_CHECK_EQUAL(b1.value_bytes().size(), sizeof(VALUE));
190 BOOST_CHECK_EQUAL(b1.value_bytes().front(), 0x11);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400191 BOOST_CHECK(b1.value() != nullptr);
192
193 // empty buffer as TLV-VALUE
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500194 Block b2(63, std::make_shared<Buffer>());
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400195 BOOST_CHECK_EQUAL(b2.isValid(), true);
196 BOOST_CHECK_EQUAL(b2.type(), 63);
197 BOOST_CHECK_EQUAL(b2.size(), 2);
198 BOOST_CHECK_EQUAL(b2.hasValue(), true);
199 BOOST_CHECK_EQUAL(b2.value_size(), 0);
Davide Pesavento258d51a2022-02-27 21:26:28 -0500200 BOOST_CHECK_EQUAL(b2.value_bytes().empty(), true);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400201 BOOST_CHECK(b2.value() == nullptr);
Davide Pesavento5c803b92019-02-02 19:23:48 -0500202}
203
204BOOST_AUTO_TEST_CASE(FromTypeAndBlock)
205{
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500206 const uint8_t buf[] = {0x80, 0x06, 0x81, 0x01, 0x01, 0x82, 0x01, 0x01};
207 Block nested(buf);
Davide Pesavento5c803b92019-02-02 19:23:48 -0500208
209 Block b(84, nested);
Davide Pesavento6b330402019-04-24 00:14:01 -0400210 BOOST_CHECK_EQUAL(b.isValid(), true);
Davide Pesavento5c803b92019-02-02 19:23:48 -0500211 BOOST_CHECK_EQUAL(b.type(), 84);
212 BOOST_CHECK_EQUAL(b.size(), 10);
213 BOOST_CHECK_EQUAL(b.hasValue(), true);
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500214 BOOST_CHECK_EQUAL(b.value_size(), sizeof(buf));
Davide Pesavento258d51a2022-02-27 21:26:28 -0500215 BOOST_CHECK_EQUAL(b.value_bytes().size(), sizeof(buf));
216 BOOST_CHECK_EQUAL(b.value_bytes().front(), 0x80);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400217 BOOST_CHECK(b.value() != nullptr);
Davide Pesavento5c803b92019-02-02 19:23:48 -0500218}
219
Junxiao Shif0da7892015-04-04 22:16:16 -0700220BOOST_AUTO_TEST_CASE(FromStream)
Alexander Afanasyev21ef2392014-03-25 12:40:22 -0700221{
Junxiao Shidc4277a2017-07-17 11:34:02 +0000222 std::stringstream stream;
223 stream.write(reinterpret_cast<const char*>(TEST_BUFFER), sizeof(TEST_BUFFER));
224 stream.seekg(0);
Alexander Afanasyev21ef2392014-03-25 12:40:22 -0700225
Junxiao Shidc4277a2017-07-17 11:34:02 +0000226 Block b = Block::fromStream(stream);
Davide Pesavento6b330402019-04-24 00:14:01 -0400227 BOOST_CHECK_EQUAL(b.type(), 66);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000228 BOOST_CHECK_EQUAL(b.size(), 3);
229 BOOST_CHECK_EQUAL(b.value_size(), 1);
Davide Pesavento258d51a2022-02-27 21:26:28 -0500230 BOOST_CHECK_EQUAL(b.value_bytes().size(), 1);
231 BOOST_CHECK_EQUAL(*b.data(), 0x42);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000232 BOOST_CHECK_EQUAL(*b.value(), 0xfa);
Davide Pesavento258d51a2022-02-27 21:26:28 -0500233 BOOST_CHECK_EQUAL(b.value_bytes().front(), 0xfa);
Alexander Afanasyev21ef2392014-03-25 12:40:22 -0700234
Junxiao Shidc4277a2017-07-17 11:34:02 +0000235 b = Block::fromStream(stream);
236 BOOST_CHECK_EQUAL(b.type(), 1);
237 BOOST_CHECK_EQUAL(b.size(), 3);
238 BOOST_CHECK_EQUAL(b.value_size(), 1);
Davide Pesavento258d51a2022-02-27 21:26:28 -0500239 BOOST_CHECK_EQUAL(b.value_bytes().size(), 1);
240 BOOST_CHECK_EQUAL(*b.data(), 0x01);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000241 BOOST_CHECK_EQUAL(*b.value(), 0xfb);
Davide Pesavento258d51a2022-02-27 21:26:28 -0500242 BOOST_CHECK_EQUAL(b.value_bytes().front(), 0xfb);
Alexander Afanasyev21ef2392014-03-25 12:40:22 -0700243
Davide Pesavento6b330402019-04-24 00:14:01 -0400244 b = Block::fromStream(stream);
245 BOOST_CHECK_EQUAL(b.type(), 0xffffffff);
246 BOOST_CHECK_EQUAL(b.size(), 6);
247 BOOST_CHECK_EQUAL(b.value_size(), 0);
Davide Pesavento258d51a2022-02-27 21:26:28 -0500248 BOOST_CHECK_EQUAL(b.value_bytes().size(), 0);
249 BOOST_CHECK_EQUAL(*b.data(), 0xfe);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400250 BOOST_CHECK(b.value() == nullptr);
Davide Pesavento6b330402019-04-24 00:14:01 -0400251
252 BOOST_CHECK(stream.eof());
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400253 BOOST_CHECK_EXCEPTION(Block::fromStream(stream), tlv::Error, [] (const auto& e) {
254 return e.what() == "Empty buffer during TLV parsing"s;
255 });
Alexander Afanasyev21ef2392014-03-25 12:40:22 -0700256}
257
Junxiao Shif0da7892015-04-04 22:16:16 -0700258BOOST_AUTO_TEST_CASE(FromStreamWhitespace) // Bug 2728
259{
Junxiao Shidc4277a2017-07-17 11:34:02 +0000260 const uint8_t PACKET[] = {
Junxiao Shif0da7892015-04-04 22:16:16 -0700261 0x06, 0x20, // Data
262 0x07, 0x11, // Name
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000263 0x08, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, // GenericNameComponent 'hello'
264 0x08, 0x01, 0x31, // GenericNameComponent '1'
265 0x08, 0x05, 0x77, 0x6f, 0x72, 0x6c, 0x64, // GenericNameComponent 'world'
Junxiao Shif0da7892015-04-04 22:16:16 -0700266 0x14, 0x00, // MetaInfo empty
267 0x15, 0x00, // Content empty
268 0x16, 0x05, // SignatureInfo
Junxiao Shidc4277a2017-07-17 11:34:02 +0000269 0x1b, 0x01, 0x01, // SignatureType RSA
270 0x1c, 0x00, // KeyLocator empty
Junxiao Shif0da7892015-04-04 22:16:16 -0700271 0x17, 0x00 // SignatureValue empty
272 };
273 // TLV-LENGTH of <Data> is 0x20 which happens to be ASCII whitespace
274
275 std::stringstream stream;
276 stream.write(reinterpret_cast<const char*>(PACKET), sizeof(PACKET));
277 stream.seekg(0);
278
Junxiao Shidc4277a2017-07-17 11:34:02 +0000279 Block b = Block::fromStream(stream);
280 BOOST_CHECK_EQUAL(b.type(), 6);
281 BOOST_CHECK_EQUAL(b.value_size(), 32);
282 b.parse();
Davide Pesavento6b330402019-04-24 00:14:01 -0400283 BOOST_CHECK_EQUAL(b.elements_size(), 5);
Junxiao Shif0da7892015-04-04 22:16:16 -0700284}
285
Junxiao Shi760cc7b2017-07-22 19:17:49 +0000286BOOST_AUTO_TEST_CASE(FromStreamZeroLength)
Junxiao Shif0da7892015-04-04 22:16:16 -0700287{
Junxiao Shi760cc7b2017-07-22 19:17:49 +0000288 const uint8_t BUFFER[] = {0x70, 0x00,
289 0x71, 0x03, 0x86, 0x11, 0x24,
290 0x72, 0x00};
Junxiao Shif0da7892015-04-04 22:16:16 -0700291
292 std::stringstream stream;
293 stream.write(reinterpret_cast<const char*>(BUFFER), sizeof(BUFFER));
294 stream.seekg(0);
295
Junxiao Shi760cc7b2017-07-22 19:17:49 +0000296 Block b1 = Block::fromStream(stream);
297 BOOST_CHECK_EQUAL(b1.type(), 0x70);
298 BOOST_CHECK_EQUAL(b1.value_size(), 0);
Davide Pesavento258d51a2022-02-27 21:26:28 -0500299 BOOST_CHECK_EQUAL(b1.value_bytes().size(), 0);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400300 BOOST_CHECK(b1.value() == nullptr);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000301
Junxiao Shi760cc7b2017-07-22 19:17:49 +0000302 Block b2 = Block::fromStream(stream);
303 BOOST_CHECK_EQUAL(b2.type(), 0x71);
304 BOOST_CHECK_EQUAL(b2.value_size(), 3);
Davide Pesavento258d51a2022-02-27 21:26:28 -0500305 BOOST_CHECK_EQUAL(b2.value_bytes().size(), 3);
Junxiao Shi760cc7b2017-07-22 19:17:49 +0000306 const uint8_t EXPECTED_VALUE2[] = {0x86, 0x11, 0x24};
Davide Pesavento258d51a2022-02-27 21:26:28 -0500307 BOOST_TEST(b2.value_bytes() == EXPECTED_VALUE2, boost::test_tools::per_element());
Junxiao Shi760cc7b2017-07-22 19:17:49 +0000308
309 Block b3 = Block::fromStream(stream);
310 BOOST_CHECK_EQUAL(b3.type(), 0x72);
311 BOOST_CHECK_EQUAL(b3.value_size(), 0);
Davide Pesavento258d51a2022-02-27 21:26:28 -0500312 BOOST_CHECK_EQUAL(b3.value_bytes().size(), 0);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400313 BOOST_CHECK(b3.value() == nullptr);
Junxiao Shi760cc7b2017-07-22 19:17:49 +0000314
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400315 BOOST_CHECK_EXCEPTION(Block::fromStream(stream), tlv::Error, [] (const auto& e) {
316 return e.what() == "Empty buffer during TLV parsing"s;
317 });
Junxiao Shi760cc7b2017-07-22 19:17:49 +0000318}
319
320BOOST_AUTO_TEST_CASE(FromStreamPacketTooLarge)
321{
322 const uint8_t BUFFER[] = {0x07, 0xfe, 0x00, 0x01, 0x00, 0x00};
323
324 std::stringstream stream;
325 stream.write(reinterpret_cast<const char*>(BUFFER), sizeof(BUFFER));
326 for (int i = 0; i < 0x10000; ++i) {
327 stream.put('\0');
328 }
329 stream.seekg(0);
330
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400331 BOOST_CHECK_EXCEPTION(Block::fromStream(stream), tlv::Error, [] (const auto& e) {
332 return e.what() == "TLV-LENGTH from stream exceeds limit"s;
333 });
Junxiao Shidc4277a2017-07-17 11:34:02 +0000334}
335
336BOOST_AUTO_TEST_CASE(FromWireBuffer)
337{
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500338 auto buffer = std::make_shared<Buffer>(TEST_BUFFER, sizeof(TEST_BUFFER));
Junxiao Shidc4277a2017-07-17 11:34:02 +0000339
Junxiao Shidc4277a2017-07-17 11:34:02 +0000340 bool isOk = false;
341 Block b;
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500342 std::tie(isOk, b) = Block::fromBuffer(buffer);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000343 BOOST_CHECK(isOk);
Davide Pesavento6b330402019-04-24 00:14:01 -0400344 BOOST_CHECK_EQUAL(b.type(), 66);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000345 BOOST_CHECK_EQUAL(b.size(), 3);
346 BOOST_CHECK_EQUAL(b.value_size(), 1);
Davide Pesavento258d51a2022-02-27 21:26:28 -0500347 BOOST_CHECK_EQUAL(b.value_bytes().size(), 1);
348 BOOST_CHECK_EQUAL(*b.data(), 0x42);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000349 BOOST_CHECK_EQUAL(*b.value(), 0xfa);
Davide Pesavento258d51a2022-02-27 21:26:28 -0500350 BOOST_CHECK_EQUAL(b.value_bytes().front(), 0xfa);
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500351 size_t offset = b.size();
Junxiao Shidc4277a2017-07-17 11:34:02 +0000352
353 std::tie(isOk, b) = Block::fromBuffer(buffer, offset);
354 BOOST_CHECK(isOk);
355 BOOST_CHECK_EQUAL(b.type(), 1);
356 BOOST_CHECK_EQUAL(b.size(), 3);
357 BOOST_CHECK_EQUAL(b.value_size(), 1);
Davide Pesavento258d51a2022-02-27 21:26:28 -0500358 BOOST_CHECK_EQUAL(b.value_bytes().size(), 1);
359 BOOST_CHECK_EQUAL(*b.data(), 0x01);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000360 BOOST_CHECK_EQUAL(*b.value(), 0xfb);
Davide Pesavento258d51a2022-02-27 21:26:28 -0500361 BOOST_CHECK_EQUAL(b.value_bytes().front(), 0xfb);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000362 offset += b.size();
363
364 std::tie(isOk, b) = Block::fromBuffer(buffer, offset);
Davide Pesavento6b330402019-04-24 00:14:01 -0400365 BOOST_CHECK(isOk);
366 BOOST_CHECK_EQUAL(b.type(), 0xffffffff);
367 BOOST_CHECK_EQUAL(b.size(), 6);
368 BOOST_CHECK_EQUAL(b.value_size(), 0);
Davide Pesavento258d51a2022-02-27 21:26:28 -0500369 BOOST_CHECK_EQUAL(b.value_bytes().empty(), true);
370 BOOST_CHECK_EQUAL(*b.data(), 0xfe);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400371 BOOST_CHECK(b.value() == nullptr);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000372}
373
374BOOST_AUTO_TEST_CASE(FromRawBuffer)
375{
Junxiao Shidc4277a2017-07-17 11:34:02 +0000376 bool isOk = false;
377 Block b;
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500378 std::tie(isOk, b) = Block::fromBuffer(TEST_BUFFER);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000379 BOOST_CHECK(isOk);
Davide Pesavento6b330402019-04-24 00:14:01 -0400380 BOOST_CHECK_EQUAL(b.type(), 66);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000381 BOOST_CHECK_EQUAL(b.size(), 3);
382 BOOST_CHECK_EQUAL(b.value_size(), 1);
Davide Pesavento258d51a2022-02-27 21:26:28 -0500383 BOOST_CHECK_EQUAL(b.value_bytes().size(), 1);
384 BOOST_CHECK_EQUAL(*b.data(), 0x42);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000385 BOOST_CHECK_EQUAL(*b.value(), 0xfa);
Davide Pesavento258d51a2022-02-27 21:26:28 -0500386 BOOST_CHECK_EQUAL(b.value_bytes().front(), 0xfa);
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500387 auto offset = b.size();
Junxiao Shidc4277a2017-07-17 11:34:02 +0000388
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500389 std::tie(isOk, b) = Block::fromBuffer(make_span(TEST_BUFFER).subspan(offset));
Junxiao Shidc4277a2017-07-17 11:34:02 +0000390 BOOST_CHECK(isOk);
391 BOOST_CHECK_EQUAL(b.type(), 1);
392 BOOST_CHECK_EQUAL(b.size(), 3);
393 BOOST_CHECK_EQUAL(b.value_size(), 1);
Davide Pesavento258d51a2022-02-27 21:26:28 -0500394 BOOST_CHECK_EQUAL(b.value_bytes().size(), 1);
395 BOOST_CHECK_EQUAL(*b.data(), 0x01);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000396 BOOST_CHECK_EQUAL(*b.value(), 0xfb);
Davide Pesavento258d51a2022-02-27 21:26:28 -0500397 BOOST_CHECK_EQUAL(b.value_bytes().front(), 0xfb);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000398 offset += b.size();
399
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500400 std::tie(isOk, b) = Block::fromBuffer(make_span(TEST_BUFFER).subspan(offset));
Davide Pesavento6b330402019-04-24 00:14:01 -0400401 BOOST_CHECK(isOk);
402 BOOST_CHECK_EQUAL(b.type(), 0xffffffff);
403 BOOST_CHECK_EQUAL(b.size(), 6);
404 BOOST_CHECK_EQUAL(b.value_size(), 0);
Davide Pesavento258d51a2022-02-27 21:26:28 -0500405 BOOST_CHECK_EQUAL(b.value_bytes().empty(), true);
406 BOOST_CHECK_EQUAL(*b.data(), 0xfe);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400407 BOOST_CHECK(b.value() == nullptr);
Davide Pesavento6b330402019-04-24 00:14:01 -0400408}
409
Davide Pesavento1a4a7bf2020-12-04 22:30:46 -0500410static const Buffer MalformedInputs[] = {
411 {0x00, 0x00}, // invalid TLV type (zero)
412 {0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}, // TLV type too large
413 {0x01, 0xff, 0x42, 0x42}, // bad TLV length
414 {0x01, 0x02, 0x03}, // truncated TLV value
Davide Pesavento6b330402019-04-24 00:14:01 -0400415};
416
Davide Pesavento1a4a7bf2020-12-04 22:30:46 -0500417BOOST_DATA_TEST_CASE(Malformed, MalformedInputs)
Davide Pesavento6b330402019-04-24 00:14:01 -0400418{
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500419 // constructor from span
420 BOOST_CHECK_THROW(Block{sample}, tlv::Error);
Davide Pesavento6b330402019-04-24 00:14:01 -0400421
422 // fromStream()
423 std::stringstream stream;
Davide Pesavento1a4a7bf2020-12-04 22:30:46 -0500424 stream.write(sample.template get<char>(), sample.size());
Davide Pesavento6b330402019-04-24 00:14:01 -0400425 stream.seekg(0);
426 BOOST_CHECK_THROW(Block::fromStream(stream), tlv::Error);
427
428 // fromBuffer(), ConstBufferPtr overload
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500429 auto buf = std::make_shared<Buffer>(sample.begin(), sample.end());
Davide Pesavento6b330402019-04-24 00:14:01 -0400430 bool isOk;
431 Block b;
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500432 std::tie(isOk, b) = Block::fromBuffer(buf);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000433 BOOST_CHECK(!isOk);
Davide Pesavento6b330402019-04-24 00:14:01 -0400434 BOOST_CHECK(!b.isValid());
435
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500436 // fromBuffer(), span overload
437 std::tie(isOk, b) = Block::fromBuffer(sample);
Davide Pesavento6b330402019-04-24 00:14:01 -0400438 BOOST_CHECK(!isOk);
439 BOOST_CHECK(!b.isValid());
Junxiao Shif0da7892015-04-04 22:16:16 -0700440}
441
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100442BOOST_AUTO_TEST_SUITE_END() // Construction
443
Davide Pesaventoa76ea9a2021-04-24 00:06:02 -0400444BOOST_AUTO_TEST_CASE(BlockFromValue)
445{
446 Block b1(301);
447 BOOST_CHECK_EXCEPTION(b1.blockFromValue(), Block::Error, [] (const auto& e) {
448 return e.what() == "Cannot construct block from empty TLV-VALUE"s;
449 });
450
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500451 Block b2(302, std::make_shared<Buffer>());
Davide Pesaventoa76ea9a2021-04-24 00:06:02 -0400452 BOOST_CHECK_EXCEPTION(b2.blockFromValue(), Block::Error, [] (const auto& e) {
453 return e.what() == "Cannot construct block from empty TLV-VALUE"s;
454 });
455
456 b1.encode();
457 Block b3(303, b1);
458 b3.encode();
459 Block nested = b3.blockFromValue();
460 BOOST_CHECK_EQUAL(nested.type(), 301);
461 BOOST_CHECK_EQUAL(nested.size(), 4);
462 BOOST_CHECK_EQUAL(nested.value_size(), 0);
463 BOOST_CHECK(nested == b1);
464}
465
Junxiao Shidc4277a2017-07-17 11:34:02 +0000466BOOST_AUTO_TEST_SUITE(SubElements)
467
468BOOST_AUTO_TEST_CASE(Parse)
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700469{
Junxiao Shidc4277a2017-07-17 11:34:02 +0000470 const uint8_t PACKET[] = {
471 0x06, 0x20, // Data
472 0x07, 0x11, // Name
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000473 0x08, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, // GenericNameComponent 'hello'
474 0x08, 0x01, 0x31, // GenericNameComponent '1'
475 0x08, 0x05, 0x77, 0x6f, 0x72, 0x6c, 0x64, // GenericNameComponent 'world'
Junxiao Shidc4277a2017-07-17 11:34:02 +0000476 0x14, 0x00, // MetaInfo empty
477 0x15, 0x00, // Content empty
478 0x16, 0x05, // SignatureInfo
479 0x1b, 0x01, 0x01, // SignatureType RSA
480 0x1c, 0x00, // KeyLocator empty
481 0x17, 0x00 // SignatureValue empty
482 };
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500483 Block data(PACKET);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000484 data.parse();
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700485
Junxiao Shidc4277a2017-07-17 11:34:02 +0000486 BOOST_CHECK_EQUAL(data.elements_size(), 5);
487 BOOST_CHECK_EQUAL(data.elements().at(0).type(), 0x07);
488 BOOST_CHECK_EQUAL(data.elements().at(0).elements().size(), 0); // parse is not recursive
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700489
Junxiao Shidc4277a2017-07-17 11:34:02 +0000490 BOOST_CHECK(data.get(0x15) == data.elements().at(2));
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400491 BOOST_CHECK_EXCEPTION(data.get(0x01), Block::Error, [] (const auto& e) {
492 return e.what() == "No sub-element of type 1 found in block of type 6"s;
493 });
Junxiao Shidc4277a2017-07-17 11:34:02 +0000494
495 BOOST_CHECK(data.find(0x15) == data.elements_begin() + 2);
496 BOOST_CHECK(data.find(0x01) == data.elements_end());
Davide Pesavento6b330402019-04-24 00:14:01 -0400497
498 const uint8_t MALFORMED[] = {
499 // TLV-LENGTH of nested element is greater than TLV-LENGTH of enclosing element
500 0x05, 0x05, 0x07, 0x07, 0x08, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f
501 };
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500502 Block bad(MALFORMED);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400503 BOOST_CHECK_EXCEPTION(bad.parse(), Block::Error, [] (const auto& e) {
504 return e.what() == "TLV-LENGTH of sub-element of type 7 exceeds TLV-VALUE boundary of parent block"s;
505 });
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700506}
507
Joao Pereira7476ebf2015-07-07 14:54:39 -0400508BOOST_AUTO_TEST_CASE(InsertBeginning)
509{
510 Block masterBlock(tlv::Name);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000511 Block firstBlock = makeStringBlock(tlv::GenericNameComponent, "firstName");
512 Block secondBlock = makeStringBlock(tlv::GenericNameComponent, "secondName");
513 Block thirdBlock = makeStringBlock(tlv::GenericNameComponent, "thirdName");
Joao Pereira7476ebf2015-07-07 14:54:39 -0400514
515 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 0);
516 masterBlock.push_back(secondBlock);
517 masterBlock.push_back(thirdBlock);
518 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 2);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000519 Block::element_const_iterator it = masterBlock.find(tlv::GenericNameComponent);
Joao Pereira7476ebf2015-07-07 14:54:39 -0400520 BOOST_CHECK_EQUAL(*it == secondBlock, true);
521
522 it = masterBlock.insert(it, firstBlock);
523
524 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 3);
525 BOOST_CHECK_EQUAL(*(it + 1) == secondBlock, true);
526 BOOST_CHECK_EQUAL(*(masterBlock.elements_begin()) == firstBlock, true);
527}
528
529BOOST_AUTO_TEST_CASE(InsertEnd)
530{
531 Block masterBlock(tlv::Name);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000532 Block firstBlock = makeStringBlock(tlv::GenericNameComponent, "firstName");
533 Block secondBlock = makeStringBlock(tlv::GenericNameComponent, "secondName");
534 Block thirdBlock = makeStringBlock(tlv::GenericNameComponent, "thirdName");
Joao Pereira7476ebf2015-07-07 14:54:39 -0400535
536 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 0);
537 masterBlock.push_back(firstBlock);
538 masterBlock.push_back(secondBlock);
539 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 2);
540 Block::element_const_iterator it = masterBlock.elements_end();
541 BOOST_CHECK_EQUAL(*(it - 1) == secondBlock, true);
542
543 it = masterBlock.insert(it, thirdBlock);
544
545 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 3);
546 BOOST_CHECK_EQUAL(*(it - 1) == secondBlock, true);
547 BOOST_CHECK_EQUAL(*(masterBlock.elements_end() - 1) == thirdBlock, true);
548}
549
550BOOST_AUTO_TEST_CASE(InsertMiddle)
551{
552 Block masterBlock(tlv::Name);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000553 Block firstBlock = makeStringBlock(tlv::GenericNameComponent, "firstName");
554 Block secondBlock = makeStringBlock(tlv::GenericNameComponent, "secondName");
555 Block thirdBlock = makeStringBlock(tlv::GenericNameComponent, "thirdName");
Joao Pereira7476ebf2015-07-07 14:54:39 -0400556
557 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 0);
558 masterBlock.push_back(firstBlock);
559 masterBlock.push_back(thirdBlock);
560 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 2);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000561 Block::element_const_iterator it = masterBlock.find(tlv::GenericNameComponent);
Joao Pereira7476ebf2015-07-07 14:54:39 -0400562 BOOST_CHECK_EQUAL(*it == firstBlock, true);
563
Junxiao Shidc4277a2017-07-17 11:34:02 +0000564 it = masterBlock.insert(it + 1, secondBlock);
Joao Pereira7476ebf2015-07-07 14:54:39 -0400565
566 BOOST_CHECK_EQUAL(*it == secondBlock, true);
567 BOOST_CHECK_EQUAL(*(it + 1) == thirdBlock, true);
568 BOOST_CHECK_EQUAL(*(it - 1) == firstBlock, true);
569}
570
571BOOST_AUTO_TEST_CASE(EraseSingleElement)
572{
573 Block masterBlock(tlv::Name);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000574 Block firstBlock = makeStringBlock(tlv::GenericNameComponent, "firstName");
575 Block secondBlock = makeStringBlock(tlv::GenericNameComponent, "secondName");
576 Block thirdBlock = makeStringBlock(tlv::GenericNameComponent, "thirdName");
Joao Pereira7476ebf2015-07-07 14:54:39 -0400577
578 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 0);
579 masterBlock.push_back(firstBlock);
580 masterBlock.push_back(secondBlock);
581 masterBlock.push_back(thirdBlock);
582 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 3);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000583 Block::element_const_iterator it = masterBlock.find(tlv::GenericNameComponent);
Joao Pereira7476ebf2015-07-07 14:54:39 -0400584 it++;
585 BOOST_CHECK_EQUAL(*it == secondBlock, true);
586
587 it = masterBlock.erase(it);
588
589 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 2);
590 BOOST_CHECK_EQUAL(*(it) == thirdBlock, true);
591 BOOST_CHECK_EQUAL(*(it - 1) == firstBlock, true);
592}
593
594BOOST_AUTO_TEST_CASE(EraseRange)
595{
596 Block masterBlock(tlv::Name);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000597 Block firstBlock = makeStringBlock(tlv::GenericNameComponent, "firstName");
598 Block secondBlock = makeStringBlock(tlv::GenericNameComponent, "secondName");
599 Block thirdBlock = makeStringBlock(tlv::GenericNameComponent, "thirdName");
600 Block fourthBlock = makeStringBlock(tlv::GenericNameComponent, "fourthName");
601 Block fifthBlock = makeStringBlock(tlv::GenericNameComponent, "fifthName");
602 Block sixthBlock = makeStringBlock(tlv::GenericNameComponent, "sixthName");
Joao Pereira7476ebf2015-07-07 14:54:39 -0400603
604 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 0);
605 masterBlock.push_back(firstBlock);
606 masterBlock.push_back(secondBlock);
607 masterBlock.push_back(thirdBlock);
608 masterBlock.push_back(fourthBlock);
609 masterBlock.push_back(fifthBlock);
610 masterBlock.push_back(sixthBlock);
611 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 6);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000612 Block::element_const_iterator itStart = masterBlock.find(tlv::GenericNameComponent);
Joao Pereira7476ebf2015-07-07 14:54:39 -0400613 itStart++;
614 Block::element_const_iterator itEnd = itStart + 3;
615 BOOST_CHECK_EQUAL(*itStart == secondBlock, true);
616 BOOST_CHECK_EQUAL(*itEnd == fifthBlock, true);
617
618 Block::element_const_iterator newIt = masterBlock.erase(itStart, itEnd);
619
620 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 3);
621 BOOST_CHECK_EQUAL(*(newIt) == fifthBlock, true);
622 BOOST_CHECK_EQUAL(*(newIt - 1) == firstBlock, true);
623}
624
Eric Newberrya3d9fc02015-07-26 10:55:44 -0700625BOOST_AUTO_TEST_CASE(Remove)
626{
627 Block block(tlv::Data);
628 block.push_back(makeNonNegativeIntegerBlock(tlv::ContentType, 0));
629 block.push_back(makeNonNegativeIntegerBlock(tlv::FreshnessPeriod, 123));
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400630 block.push_back(makeStringBlock(tlv::Name, "/test-prefix"));
Eric Newberrya3d9fc02015-07-26 10:55:44 -0700631 block.push_back(makeNonNegativeIntegerBlock(tlv::ContentType, 2));
632 block.push_back(makeNonNegativeIntegerBlock(tlv::ContentType, 1));
633
634 BOOST_CHECK_EQUAL(5, block.elements_size());
Davide Pesavento6b330402019-04-24 00:14:01 -0400635 BOOST_CHECK_NO_THROW(block.remove(tlv::ContentType));
636 BOOST_REQUIRE_EQUAL(2, block.elements_size());
Eric Newberrya3d9fc02015-07-26 10:55:44 -0700637
Davide Pesavento6b330402019-04-24 00:14:01 -0400638 auto elements = block.elements();
Eric Newberrya3d9fc02015-07-26 10:55:44 -0700639 BOOST_CHECK_EQUAL(tlv::FreshnessPeriod, elements[0].type());
640 BOOST_CHECK_EQUAL(123, readNonNegativeInteger(elements[0]));
641 BOOST_CHECK_EQUAL(tlv::Name, elements[1].type());
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400642 BOOST_CHECK_EQUAL(readString(elements[1]).compare("/test-prefix"), 0);
Eric Newberrya3d9fc02015-07-26 10:55:44 -0700643}
644
Junxiao Shidc4277a2017-07-17 11:34:02 +0000645BOOST_AUTO_TEST_SUITE_END() // SubElements
646
Davide Pesaventoa76ea9a2021-04-24 00:06:02 -0400647BOOST_AUTO_TEST_CASE(ToAsioConstBuffer)
648{
649 Block block = "0101A0"_block;
650 boost::asio::const_buffer buffer(block);
Davide Pesavento258d51a2022-02-27 21:26:28 -0500651 BOOST_CHECK_EQUAL(boost::asio::buffer_cast<const uint8_t*>(buffer), block.data());
Davide Pesaventoa76ea9a2021-04-24 00:06:02 -0400652 BOOST_CHECK_EQUAL(boost::asio::buffer_size(buffer), block.size());
653}
654
Junxiao Shidc4277a2017-07-17 11:34:02 +0000655BOOST_AUTO_TEST_CASE(Equality)
656{
Davide Pesaventob10024c2017-09-22 01:36:44 -0400657 const uint8_t one[] = {0x08, 0x00};
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500658 Block a(one);
659 Block b(one);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000660 BOOST_CHECK_EQUAL(a == b, true);
661 BOOST_CHECK_EQUAL(a != b, false);
662
Davide Pesaventob10024c2017-09-22 01:36:44 -0400663 const uint8_t two[] = {0x06, 0x00};
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500664 Block c(two);
665 Block d(one);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000666 BOOST_CHECK_EQUAL(c == d, false);
667 BOOST_CHECK_EQUAL(c != d, true);
668
Davide Pesaventob10024c2017-09-22 01:36:44 -0400669 const uint8_t three[] = {0x06, 0x01, 0xcc};
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500670 Block e(two);
671 Block f(three);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000672 BOOST_CHECK_EQUAL(e == f, false);
673 BOOST_CHECK_EQUAL(e != f, true);
674}
675
Junxiao Shi72c0c642018-04-20 15:41:09 +0000676BOOST_AUTO_TEST_CASE(Print)
677{
678 // default constructed
679 Block b;
680 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(b), "[invalid]");
681
682 // zero length
683 b = "0700"_block;
684 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(b), "7[empty]");
685
686 // unparsed
687 b = "0E10FF7E4E6B3B21C902660F16ED589FCCCC"_block;
688 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(b),
689 "14[16]=FF7E4E6B3B21C902660F16ED589FCCCC");
690 // set and restore format flags
691 {
692 std::ostringstream oss;
693 oss << std::showbase << std::hex << 0xd23c4 << b << 0x4981e;
694 BOOST_CHECK_EQUAL(oss.str(), "0xd23c414[16]=FF7E4E6B3B21C902660F16ED589FCCCC0x4981e");
695 }
696
697 // parsed
698 b = "FD010808 0502CADD 59024E42"_block;
699 b.parse();
700 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(b),
701 "264[8]={5[2]=CADD,89[2]=4E42}");
702
703 // parsed then modified: print modified sub-elements
704 b = "FD010808 0502CADD 59024E42"_block;
705 b.parse();
706 b.erase(b.elements_begin());
707 b.push_back("10022386"_block);
708 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(b),
709 "264[8]={89[2]=4E42,16[2]=2386}");
710}
711
Junxiao Shi2b322eb2018-08-24 10:43:27 -0600712BOOST_AUTO_TEST_SUITE(BlockLiteral)
713
714BOOST_AUTO_TEST_CASE(Simple)
715{
Davide Pesavento6b330402019-04-24 00:14:01 -0400716 Block b0 = "4200"_block;
717 BOOST_CHECK_EQUAL(b0.type(), 0x42);
Junxiao Shi2b322eb2018-08-24 10:43:27 -0600718 BOOST_CHECK_EQUAL(b0.value_size(), 0);
719
720 Block b1 = "0101A0"_block;
721 BOOST_CHECK_EQUAL(b1.type(), 0x01);
722 BOOST_REQUIRE_EQUAL(b1.value_size(), 1);
723 BOOST_CHECK_EQUAL(b1.value()[0], 0xA0);
724}
725
726BOOST_AUTO_TEST_CASE(Comment)
727{
728 Block b0 = "a2b0c0d2eBf0G.B 1+"_block;
729 BOOST_CHECK_EQUAL(b0.type(), 0x20);
730 BOOST_REQUIRE_EQUAL(b0.value_size(), 2);
731 BOOST_CHECK_EQUAL(b0.value()[0], 0xB0);
732 BOOST_CHECK_EQUAL(b0.value()[1], 0xB1);
733}
734
735BOOST_AUTO_TEST_CASE(BadInput)
736{
737 BOOST_CHECK_THROW(""_block, std::invalid_argument);
738 BOOST_CHECK_THROW("1"_block, std::invalid_argument);
739 BOOST_CHECK_THROW("333"_block, std::invalid_argument);
Davide Pesavento6b330402019-04-24 00:14:01 -0400740 BOOST_CHECK_THROW("xx yy zz"_block, std::invalid_argument); // only comments
Junxiao Shi2b322eb2018-08-24 10:43:27 -0600741
Davide Pesavento6b330402019-04-24 00:14:01 -0400742 BOOST_CHECK_THROW("0000"_block, tlv::Error); // invalid type
743 BOOST_CHECK_THROW("0202C0"_block, tlv::Error); // truncated value
744 BOOST_CHECK_THROW("0201C0C1"_block, tlv::Error); // trailing garbage
Junxiao Shi2b322eb2018-08-24 10:43:27 -0600745}
746
747BOOST_AUTO_TEST_SUITE_END() // BlockLiteral
748
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100749BOOST_AUTO_TEST_SUITE_END() // TestBlock
750BOOST_AUTO_TEST_SUITE_END() // Encoding
Alexander Afanasyev233750e2014-02-16 00:50:07 -0800751
Alexander Afanasyev74633892015-02-08 18:08:46 -0800752} // namespace tests
Alexander Afanasyev233750e2014-02-16 00:50:07 -0800753} // namespace ndn