blob: e7c8bac82e7928b32455794d3e502cff764528a9 [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);
56 BOOST_CHECK(b.value() == nullptr);
57
58 BOOST_CHECK_THROW(b.size(), Block::Error);
59 BOOST_CHECK_THROW(b.begin(), Block::Error);
60 BOOST_CHECK_THROW(b.end(), Block::Error);
61 BOOST_CHECK_THROW(b.wire(), Block::Error);
62 BOOST_CHECK_THROW(b.blockFromValue(), Block::Error);
Alexander Afanasyev74633892015-02-08 18:08:46 -080063}
Alexander Afanasyev937aa782014-03-21 13:17:57 -070064
Junxiao Shidc4277a2017-07-17 11:34:02 +000065BOOST_AUTO_TEST_CASE(FromEncodingBuffer)
Alexander Afanasyev74633892015-02-08 18:08:46 -080066{
Junxiao Shidc4277a2017-07-17 11:34:02 +000067 EncodingBuffer encoder;
Davide Pesavento5c803b92019-02-02 19:23:48 -050068 BOOST_CHECK_THROW(Block{encoder}, tlv::Error);
69
70 const uint8_t VALUE[] = {0x11, 0x12, 0x13, 0x14};
Davide Pesaventofbea4fc2022-02-08 07:26:04 -050071 size_t length = encoder.prependBytes(VALUE);
Junxiao Shidc4277a2017-07-17 11:34:02 +000072 encoder.prependVarNumber(length);
73 encoder.prependVarNumber(0xe0);
74
75 Block b = encoder.block();
76 BOOST_CHECK_EQUAL(b.type(), 0xe0);
77 BOOST_CHECK_EQUAL(b.value_size(), sizeof(VALUE));
78 BOOST_CHECK_EQUAL_COLLECTIONS(b.value_begin(), b.value_end(),
79 VALUE, VALUE + sizeof(VALUE));
80
81 b = Block(encoder);
82 BOOST_CHECK_EQUAL(b.type(), 0xe0);
83 BOOST_CHECK_EQUAL(b.value_size(), sizeof(VALUE));
84 BOOST_CHECK_EQUAL_COLLECTIONS(b.value_begin(), b.value_end(),
85 VALUE, VALUE + sizeof(VALUE));
Alexander Afanasyev74633892015-02-08 18:08:46 -080086}
Alexander Afanasyev937aa782014-03-21 13:17:57 -070087
Davide Pesaventoeee3e822016-11-26 19:19:34 +010088BOOST_AUTO_TEST_CASE(FromBlock)
Alexander Afanasyev4448d292015-08-09 20:11:37 -070089{
Davide Pesaventofbea4fc2022-02-08 07:26:04 -050090 const uint8_t buf[] = {0x80, 0x06, 0x81, 0x01, 0x01, 0x82, 0x01, 0x01};
91 Block block(buf);
Alexander Afanasyev4448d292015-08-09 20:11:37 -070092
93 Block derivedBlock(block, block.begin(), block.end());
94 BOOST_CHECK_EQUAL(derivedBlock.wire(), block.wire()); // pointers should match
Davide Pesaventofbea4fc2022-02-08 07:26:04 -050095 BOOST_CHECK_EQUAL(derivedBlock, block); // blocks should match
Alexander Afanasyev4448d292015-08-09 20:11:37 -070096
97 derivedBlock = Block(block, block.begin() + 2, block.begin() + 5);
98 BOOST_CHECK(derivedBlock.begin() == block.begin() + 2);
Davide Pesaventofbea4fc2022-02-08 07:26:04 -050099 BOOST_CHECK_EQUAL(derivedBlock, Block(make_span(buf + 2, 3)));
Alexander Afanasyev4448d292015-08-09 20:11:37 -0700100
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500101 Buffer otherBuffer(buf, sizeof(buf));
Junxiao Shidb7464d2017-07-13 03:11:17 +0000102 BOOST_CHECK_THROW(Block(block, otherBuffer.begin(), block.end()), std::invalid_argument);
103 BOOST_CHECK_THROW(Block(block, block.begin(), otherBuffer.end()), std::invalid_argument);
104 BOOST_CHECK_THROW(Block(block, otherBuffer.begin(), otherBuffer.end()), std::invalid_argument);
Alexander Afanasyev4448d292015-08-09 20:11:37 -0700105}
106
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100107BOOST_AUTO_TEST_CASE(FromBlockCopyOnWriteModifyOriginal)
Eric Newberry6235aac2015-08-13 16:03:47 -0700108{
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500109 const uint8_t buf[] = {
Eric Newberry6235aac2015-08-13 16:03:47 -0700110 0x05, 0x0b, 0x07, 0x03, 0x01, 0x02, 0x03, 0x0a, 0x04, 0x04, 0x05, 0x06, 0x07,
111 };
112
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500113 Block b1(buf);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000114 Block b2(b1, b1.begin(), b1.end());
115 auto buf2 = b2.getBuffer();
Eric Newberry6235aac2015-08-13 16:03:47 -0700116
Junxiao Shidc4277a2017-07-17 11:34:02 +0000117 b1.parse();
118 b1.remove(tlv::Name);
119 b1.encode();
Eric Newberry6235aac2015-08-13 16:03:47 -0700120
Junxiao Shidc4277a2017-07-17 11:34:02 +0000121 b2.parse();
Davide Pesaventodf8fd8a2022-02-21 20:04:21 -0500122 BOOST_TEST(b2 == buf, boost::test_tools::per_element());
123 BOOST_TEST(buf2 == b2.getBuffer()); // check pointers
Eric Newberry6235aac2015-08-13 16:03:47 -0700124}
125
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100126BOOST_AUTO_TEST_CASE(FromBlockCopyOnWriteModifyCopy)
Eric Newberry6235aac2015-08-13 16:03:47 -0700127{
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500128 const uint8_t buf[] = {
Eric Newberry6235aac2015-08-13 16:03:47 -0700129 0x05, 0x0b, 0x07, 0x03, 0x01, 0x02, 0x03, 0x0a, 0x04, 0x04, 0x05, 0x06, 0x07,
130 };
131
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500132 Block b1(buf);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000133 auto buf1 = b1.getBuffer();
Junxiao Shidc4277a2017-07-17 11:34:02 +0000134 Block b2(b1, b1.begin(), b1.end());
Eric Newberry6235aac2015-08-13 16:03:47 -0700135
Junxiao Shidc4277a2017-07-17 11:34:02 +0000136 b2.parse();
137 b2.remove(tlv::Name);
138 b2.encode();
Eric Newberry6235aac2015-08-13 16:03:47 -0700139
Junxiao Shidc4277a2017-07-17 11:34:02 +0000140 b1.parse();
Davide Pesaventodf8fd8a2022-02-21 20:04:21 -0500141 BOOST_TEST(b1 == buf, boost::test_tools::per_element());
142 BOOST_TEST(buf1 == b1.getBuffer()); // check pointers
Eric Newberry6235aac2015-08-13 16:03:47 -0700143}
144
Junxiao Shidc4277a2017-07-17 11:34:02 +0000145BOOST_AUTO_TEST_CASE(FromType)
Alexander Afanasyev233750e2014-02-16 00:50:07 -0800146{
Junxiao Shidc4277a2017-07-17 11:34:02 +0000147 Block b1(4);
Davide Pesavento6b330402019-04-24 00:14:01 -0400148 BOOST_CHECK_EQUAL(b1.isValid(), true);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000149 BOOST_CHECK_EQUAL(b1.type(), 4);
150 BOOST_CHECK_EQUAL(b1.size(), 2); // 1-octet TLV-TYPE and 1-octet TLV-LENGTH
Davide Pesavento5c803b92019-02-02 19:23:48 -0500151 BOOST_CHECK_EQUAL(b1.hasValue(), false);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000152 BOOST_CHECK_EQUAL(b1.value_size(), 0);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400153 BOOST_CHECK(b1.value() == nullptr);
Alexander Afanasyev233750e2014-02-16 00:50:07 -0800154
Junxiao Shidc4277a2017-07-17 11:34:02 +0000155 Block b2(258);
Davide Pesavento6b330402019-04-24 00:14:01 -0400156 BOOST_CHECK_EQUAL(b2.isValid(), true);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000157 BOOST_CHECK_EQUAL(b2.type(), 258);
158 BOOST_CHECK_EQUAL(b2.size(), 4); // 3-octet TLV-TYPE and 1-octet TLV-LENGTH
Davide Pesavento5c803b92019-02-02 19:23:48 -0500159 BOOST_CHECK_EQUAL(b2.hasValue(), false);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000160 BOOST_CHECK_EQUAL(b2.value_size(), 0);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400161 BOOST_CHECK(b2.value() == nullptr);
Davide Pesavento6b330402019-04-24 00:14:01 -0400162
163 Block b3(tlv::Invalid);
164 BOOST_CHECK_EQUAL(b3.isValid(), false);
165 BOOST_CHECK_EQUAL(b3.type(), tlv::Invalid);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400166 BOOST_CHECK_EXCEPTION(b3.size(), Block::Error, [] (const auto& e) {
167 return e.what() == "Cannot determine size of invalid block"s;
168 });
Davide Pesavento6b330402019-04-24 00:14:01 -0400169 BOOST_CHECK_EQUAL(b3.hasValue(), false);
170 BOOST_CHECK_EQUAL(b3.value_size(), 0);
171 BOOST_CHECK(b3.value() == nullptr);
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700172}
173
Davide Pesavento5c803b92019-02-02 19:23:48 -0500174BOOST_AUTO_TEST_CASE(FromTypeAndBuffer)
175{
176 const uint8_t VALUE[] = {0x11, 0x12, 0x13, 0x14};
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500177 auto bufferPtr = std::make_shared<Buffer>(VALUE, sizeof(VALUE));
Davide Pesavento5c803b92019-02-02 19:23:48 -0500178
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400179 Block b1(42, std::move(bufferPtr));
180 BOOST_CHECK_EQUAL(b1.isValid(), true);
181 BOOST_CHECK_EQUAL(b1.type(), 42);
182 BOOST_CHECK_EQUAL(b1.size(), 6);
183 BOOST_CHECK_EQUAL(b1.hasValue(), true);
184 BOOST_CHECK_EQUAL(b1.value_size(), sizeof(VALUE));
185 BOOST_CHECK(b1.value() != nullptr);
186
187 // empty buffer as TLV-VALUE
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500188 Block b2(63, std::make_shared<Buffer>());
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400189 BOOST_CHECK_EQUAL(b2.isValid(), true);
190 BOOST_CHECK_EQUAL(b2.type(), 63);
191 BOOST_CHECK_EQUAL(b2.size(), 2);
192 BOOST_CHECK_EQUAL(b2.hasValue(), true);
193 BOOST_CHECK_EQUAL(b2.value_size(), 0);
194 BOOST_CHECK(b2.value() == nullptr);
Davide Pesavento5c803b92019-02-02 19:23:48 -0500195}
196
197BOOST_AUTO_TEST_CASE(FromTypeAndBlock)
198{
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500199 const uint8_t buf[] = {0x80, 0x06, 0x81, 0x01, 0x01, 0x82, 0x01, 0x01};
200 Block nested(buf);
Davide Pesavento5c803b92019-02-02 19:23:48 -0500201
202 Block b(84, nested);
Davide Pesavento6b330402019-04-24 00:14:01 -0400203 BOOST_CHECK_EQUAL(b.isValid(), true);
Davide Pesavento5c803b92019-02-02 19:23:48 -0500204 BOOST_CHECK_EQUAL(b.type(), 84);
205 BOOST_CHECK_EQUAL(b.size(), 10);
206 BOOST_CHECK_EQUAL(b.hasValue(), true);
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500207 BOOST_CHECK_EQUAL(b.value_size(), sizeof(buf));
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400208 BOOST_CHECK(b.value() != nullptr);
Davide Pesavento5c803b92019-02-02 19:23:48 -0500209}
210
Junxiao Shif0da7892015-04-04 22:16:16 -0700211BOOST_AUTO_TEST_CASE(FromStream)
Alexander Afanasyev21ef2392014-03-25 12:40:22 -0700212{
Junxiao Shidc4277a2017-07-17 11:34:02 +0000213 std::stringstream stream;
214 stream.write(reinterpret_cast<const char*>(TEST_BUFFER), sizeof(TEST_BUFFER));
215 stream.seekg(0);
Alexander Afanasyev21ef2392014-03-25 12:40:22 -0700216
Junxiao Shidc4277a2017-07-17 11:34:02 +0000217 Block b = Block::fromStream(stream);
Davide Pesavento6b330402019-04-24 00:14:01 -0400218 BOOST_CHECK_EQUAL(b.type(), 66);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000219 BOOST_CHECK_EQUAL(b.size(), 3);
220 BOOST_CHECK_EQUAL(b.value_size(), 1);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400221 BOOST_CHECK_EQUAL(*b.wire(), 0x42);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000222 BOOST_CHECK_EQUAL(*b.value(), 0xfa);
Alexander Afanasyev21ef2392014-03-25 12:40:22 -0700223
Junxiao Shidc4277a2017-07-17 11:34:02 +0000224 b = Block::fromStream(stream);
225 BOOST_CHECK_EQUAL(b.type(), 1);
226 BOOST_CHECK_EQUAL(b.size(), 3);
227 BOOST_CHECK_EQUAL(b.value_size(), 1);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400228 BOOST_CHECK_EQUAL(*b.wire(), 0x01);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000229 BOOST_CHECK_EQUAL(*b.value(), 0xfb);
Alexander Afanasyev21ef2392014-03-25 12:40:22 -0700230
Davide Pesavento6b330402019-04-24 00:14:01 -0400231 b = Block::fromStream(stream);
232 BOOST_CHECK_EQUAL(b.type(), 0xffffffff);
233 BOOST_CHECK_EQUAL(b.size(), 6);
234 BOOST_CHECK_EQUAL(b.value_size(), 0);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400235 BOOST_CHECK_EQUAL(*b.wire(), 0xfe);
236 BOOST_CHECK(b.value() == nullptr);
Davide Pesavento6b330402019-04-24 00:14:01 -0400237
238 BOOST_CHECK(stream.eof());
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400239 BOOST_CHECK_EXCEPTION(Block::fromStream(stream), tlv::Error, [] (const auto& e) {
240 return e.what() == "Empty buffer during TLV parsing"s;
241 });
Alexander Afanasyev21ef2392014-03-25 12:40:22 -0700242}
243
Junxiao Shif0da7892015-04-04 22:16:16 -0700244BOOST_AUTO_TEST_CASE(FromStreamWhitespace) // Bug 2728
245{
Junxiao Shidc4277a2017-07-17 11:34:02 +0000246 const uint8_t PACKET[] = {
Junxiao Shif0da7892015-04-04 22:16:16 -0700247 0x06, 0x20, // Data
248 0x07, 0x11, // Name
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000249 0x08, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, // GenericNameComponent 'hello'
250 0x08, 0x01, 0x31, // GenericNameComponent '1'
251 0x08, 0x05, 0x77, 0x6f, 0x72, 0x6c, 0x64, // GenericNameComponent 'world'
Junxiao Shif0da7892015-04-04 22:16:16 -0700252 0x14, 0x00, // MetaInfo empty
253 0x15, 0x00, // Content empty
254 0x16, 0x05, // SignatureInfo
Junxiao Shidc4277a2017-07-17 11:34:02 +0000255 0x1b, 0x01, 0x01, // SignatureType RSA
256 0x1c, 0x00, // KeyLocator empty
Junxiao Shif0da7892015-04-04 22:16:16 -0700257 0x17, 0x00 // SignatureValue empty
258 };
259 // TLV-LENGTH of <Data> is 0x20 which happens to be ASCII whitespace
260
261 std::stringstream stream;
262 stream.write(reinterpret_cast<const char*>(PACKET), sizeof(PACKET));
263 stream.seekg(0);
264
Junxiao Shidc4277a2017-07-17 11:34:02 +0000265 Block b = Block::fromStream(stream);
266 BOOST_CHECK_EQUAL(b.type(), 6);
267 BOOST_CHECK_EQUAL(b.value_size(), 32);
268 b.parse();
Davide Pesavento6b330402019-04-24 00:14:01 -0400269 BOOST_CHECK_EQUAL(b.elements_size(), 5);
Junxiao Shif0da7892015-04-04 22:16:16 -0700270}
271
Junxiao Shi760cc7b2017-07-22 19:17:49 +0000272BOOST_AUTO_TEST_CASE(FromStreamZeroLength)
Junxiao Shif0da7892015-04-04 22:16:16 -0700273{
Junxiao Shi760cc7b2017-07-22 19:17:49 +0000274 const uint8_t BUFFER[] = {0x70, 0x00,
275 0x71, 0x03, 0x86, 0x11, 0x24,
276 0x72, 0x00};
Junxiao Shif0da7892015-04-04 22:16:16 -0700277
278 std::stringstream stream;
279 stream.write(reinterpret_cast<const char*>(BUFFER), sizeof(BUFFER));
280 stream.seekg(0);
281
Junxiao Shi760cc7b2017-07-22 19:17:49 +0000282 Block b1 = Block::fromStream(stream);
283 BOOST_CHECK_EQUAL(b1.type(), 0x70);
284 BOOST_CHECK_EQUAL(b1.value_size(), 0);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400285 BOOST_CHECK(b1.value() == nullptr);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000286
Junxiao Shi760cc7b2017-07-22 19:17:49 +0000287 Block b2 = Block::fromStream(stream);
288 BOOST_CHECK_EQUAL(b2.type(), 0x71);
289 BOOST_CHECK_EQUAL(b2.value_size(), 3);
290 const uint8_t EXPECTED_VALUE2[] = {0x86, 0x11, 0x24};
291 BOOST_CHECK_EQUAL_COLLECTIONS(b2.value_begin(), b2.value_end(),
292 EXPECTED_VALUE2, EXPECTED_VALUE2 + sizeof(EXPECTED_VALUE2));
293
294 Block b3 = Block::fromStream(stream);
295 BOOST_CHECK_EQUAL(b3.type(), 0x72);
296 BOOST_CHECK_EQUAL(b3.value_size(), 0);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400297 BOOST_CHECK(b3.value() == nullptr);
Junxiao Shi760cc7b2017-07-22 19:17:49 +0000298
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400299 BOOST_CHECK_EXCEPTION(Block::fromStream(stream), tlv::Error, [] (const auto& e) {
300 return e.what() == "Empty buffer during TLV parsing"s;
301 });
Junxiao Shi760cc7b2017-07-22 19:17:49 +0000302}
303
304BOOST_AUTO_TEST_CASE(FromStreamPacketTooLarge)
305{
306 const uint8_t BUFFER[] = {0x07, 0xfe, 0x00, 0x01, 0x00, 0x00};
307
308 std::stringstream stream;
309 stream.write(reinterpret_cast<const char*>(BUFFER), sizeof(BUFFER));
310 for (int i = 0; i < 0x10000; ++i) {
311 stream.put('\0');
312 }
313 stream.seekg(0);
314
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400315 BOOST_CHECK_EXCEPTION(Block::fromStream(stream), tlv::Error, [] (const auto& e) {
316 return e.what() == "TLV-LENGTH from stream exceeds limit"s;
317 });
Junxiao Shidc4277a2017-07-17 11:34:02 +0000318}
319
320BOOST_AUTO_TEST_CASE(FromWireBuffer)
321{
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500322 auto buffer = std::make_shared<Buffer>(TEST_BUFFER, sizeof(TEST_BUFFER));
Junxiao Shidc4277a2017-07-17 11:34:02 +0000323
Junxiao Shidc4277a2017-07-17 11:34:02 +0000324 bool isOk = false;
325 Block b;
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500326 std::tie(isOk, b) = Block::fromBuffer(buffer);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000327 BOOST_CHECK(isOk);
Davide Pesavento6b330402019-04-24 00:14:01 -0400328 BOOST_CHECK_EQUAL(b.type(), 66);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000329 BOOST_CHECK_EQUAL(b.size(), 3);
330 BOOST_CHECK_EQUAL(b.value_size(), 1);
Davide Pesavento6b330402019-04-24 00:14:01 -0400331 BOOST_CHECK_EQUAL(*b.wire(), 0x42);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000332 BOOST_CHECK_EQUAL(*b.value(), 0xfa);
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500333 size_t offset = b.size();
Junxiao Shidc4277a2017-07-17 11:34:02 +0000334
335 std::tie(isOk, b) = Block::fromBuffer(buffer, offset);
336 BOOST_CHECK(isOk);
337 BOOST_CHECK_EQUAL(b.type(), 1);
338 BOOST_CHECK_EQUAL(b.size(), 3);
339 BOOST_CHECK_EQUAL(b.value_size(), 1);
340 BOOST_CHECK_EQUAL(*b.wire(), 0x01);
341 BOOST_CHECK_EQUAL(*b.value(), 0xfb);
342 offset += b.size();
343
344 std::tie(isOk, b) = Block::fromBuffer(buffer, offset);
Davide Pesavento6b330402019-04-24 00:14:01 -0400345 BOOST_CHECK(isOk);
346 BOOST_CHECK_EQUAL(b.type(), 0xffffffff);
347 BOOST_CHECK_EQUAL(b.size(), 6);
348 BOOST_CHECK_EQUAL(b.value_size(), 0);
349 BOOST_CHECK_EQUAL(*b.wire(), 0xfe);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400350 BOOST_CHECK(b.value() == nullptr);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000351}
352
353BOOST_AUTO_TEST_CASE(FromRawBuffer)
354{
Junxiao Shidc4277a2017-07-17 11:34:02 +0000355 bool isOk = false;
356 Block b;
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500357 std::tie(isOk, b) = Block::fromBuffer(TEST_BUFFER);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000358 BOOST_CHECK(isOk);
Davide Pesavento6b330402019-04-24 00:14:01 -0400359 BOOST_CHECK_EQUAL(b.type(), 66);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000360 BOOST_CHECK_EQUAL(b.size(), 3);
361 BOOST_CHECK_EQUAL(b.value_size(), 1);
Davide Pesavento6b330402019-04-24 00:14:01 -0400362 BOOST_CHECK_EQUAL(*b.wire(), 0x42);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000363 BOOST_CHECK_EQUAL(*b.value(), 0xfa);
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500364 auto offset = b.size();
Junxiao Shidc4277a2017-07-17 11:34:02 +0000365
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500366 std::tie(isOk, b) = Block::fromBuffer(make_span(TEST_BUFFER).subspan(offset));
Junxiao Shidc4277a2017-07-17 11:34:02 +0000367 BOOST_CHECK(isOk);
368 BOOST_CHECK_EQUAL(b.type(), 1);
369 BOOST_CHECK_EQUAL(b.size(), 3);
370 BOOST_CHECK_EQUAL(b.value_size(), 1);
371 BOOST_CHECK_EQUAL(*b.wire(), 0x01);
372 BOOST_CHECK_EQUAL(*b.value(), 0xfb);
373 offset += b.size();
374
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500375 std::tie(isOk, b) = Block::fromBuffer(make_span(TEST_BUFFER).subspan(offset));
Davide Pesavento6b330402019-04-24 00:14:01 -0400376 BOOST_CHECK(isOk);
377 BOOST_CHECK_EQUAL(b.type(), 0xffffffff);
378 BOOST_CHECK_EQUAL(b.size(), 6);
379 BOOST_CHECK_EQUAL(b.value_size(), 0);
380 BOOST_CHECK_EQUAL(*b.wire(), 0xfe);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400381 BOOST_CHECK(b.value() == nullptr);
Davide Pesavento6b330402019-04-24 00:14:01 -0400382}
383
Davide Pesavento1a4a7bf2020-12-04 22:30:46 -0500384static const Buffer MalformedInputs[] = {
385 {0x00, 0x00}, // invalid TLV type (zero)
386 {0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}, // TLV type too large
387 {0x01, 0xff, 0x42, 0x42}, // bad TLV length
388 {0x01, 0x02, 0x03}, // truncated TLV value
Davide Pesavento6b330402019-04-24 00:14:01 -0400389};
390
Davide Pesavento1a4a7bf2020-12-04 22:30:46 -0500391BOOST_DATA_TEST_CASE(Malformed, MalformedInputs)
Davide Pesavento6b330402019-04-24 00:14:01 -0400392{
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500393 // constructor from span
394 BOOST_CHECK_THROW(Block{sample}, tlv::Error);
Davide Pesavento6b330402019-04-24 00:14:01 -0400395
396 // fromStream()
397 std::stringstream stream;
Davide Pesavento1a4a7bf2020-12-04 22:30:46 -0500398 stream.write(sample.template get<char>(), sample.size());
Davide Pesavento6b330402019-04-24 00:14:01 -0400399 stream.seekg(0);
400 BOOST_CHECK_THROW(Block::fromStream(stream), tlv::Error);
401
402 // fromBuffer(), ConstBufferPtr overload
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500403 auto buf = std::make_shared<Buffer>(sample.begin(), sample.end());
Davide Pesavento6b330402019-04-24 00:14:01 -0400404 bool isOk;
405 Block b;
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500406 std::tie(isOk, b) = Block::fromBuffer(buf);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000407 BOOST_CHECK(!isOk);
Davide Pesavento6b330402019-04-24 00:14:01 -0400408 BOOST_CHECK(!b.isValid());
409
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500410 // fromBuffer(), span overload
411 std::tie(isOk, b) = Block::fromBuffer(sample);
Davide Pesavento6b330402019-04-24 00:14:01 -0400412 BOOST_CHECK(!isOk);
413 BOOST_CHECK(!b.isValid());
Junxiao Shif0da7892015-04-04 22:16:16 -0700414}
415
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100416BOOST_AUTO_TEST_SUITE_END() // Construction
417
Davide Pesaventoa76ea9a2021-04-24 00:06:02 -0400418BOOST_AUTO_TEST_CASE(BlockFromValue)
419{
420 Block b1(301);
421 BOOST_CHECK_EXCEPTION(b1.blockFromValue(), Block::Error, [] (const auto& e) {
422 return e.what() == "Cannot construct block from empty TLV-VALUE"s;
423 });
424
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500425 Block b2(302, std::make_shared<Buffer>());
Davide Pesaventoa76ea9a2021-04-24 00:06:02 -0400426 BOOST_CHECK_EXCEPTION(b2.blockFromValue(), Block::Error, [] (const auto& e) {
427 return e.what() == "Cannot construct block from empty TLV-VALUE"s;
428 });
429
430 b1.encode();
431 Block b3(303, b1);
432 b3.encode();
433 Block nested = b3.blockFromValue();
434 BOOST_CHECK_EQUAL(nested.type(), 301);
435 BOOST_CHECK_EQUAL(nested.size(), 4);
436 BOOST_CHECK_EQUAL(nested.value_size(), 0);
437 BOOST_CHECK(nested == b1);
438}
439
Junxiao Shidc4277a2017-07-17 11:34:02 +0000440BOOST_AUTO_TEST_SUITE(SubElements)
441
442BOOST_AUTO_TEST_CASE(Parse)
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700443{
Junxiao Shidc4277a2017-07-17 11:34:02 +0000444 const uint8_t PACKET[] = {
445 0x06, 0x20, // Data
446 0x07, 0x11, // Name
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000447 0x08, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, // GenericNameComponent 'hello'
448 0x08, 0x01, 0x31, // GenericNameComponent '1'
449 0x08, 0x05, 0x77, 0x6f, 0x72, 0x6c, 0x64, // GenericNameComponent 'world'
Junxiao Shidc4277a2017-07-17 11:34:02 +0000450 0x14, 0x00, // MetaInfo empty
451 0x15, 0x00, // Content empty
452 0x16, 0x05, // SignatureInfo
453 0x1b, 0x01, 0x01, // SignatureType RSA
454 0x1c, 0x00, // KeyLocator empty
455 0x17, 0x00 // SignatureValue empty
456 };
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500457 Block data(PACKET);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000458 data.parse();
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700459
Junxiao Shidc4277a2017-07-17 11:34:02 +0000460 BOOST_CHECK_EQUAL(data.elements_size(), 5);
461 BOOST_CHECK_EQUAL(data.elements().at(0).type(), 0x07);
462 BOOST_CHECK_EQUAL(data.elements().at(0).elements().size(), 0); // parse is not recursive
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700463
Junxiao Shidc4277a2017-07-17 11:34:02 +0000464 BOOST_CHECK(data.get(0x15) == data.elements().at(2));
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400465 BOOST_CHECK_EXCEPTION(data.get(0x01), Block::Error, [] (const auto& e) {
466 return e.what() == "No sub-element of type 1 found in block of type 6"s;
467 });
Junxiao Shidc4277a2017-07-17 11:34:02 +0000468
469 BOOST_CHECK(data.find(0x15) == data.elements_begin() + 2);
470 BOOST_CHECK(data.find(0x01) == data.elements_end());
Davide Pesavento6b330402019-04-24 00:14:01 -0400471
472 const uint8_t MALFORMED[] = {
473 // TLV-LENGTH of nested element is greater than TLV-LENGTH of enclosing element
474 0x05, 0x05, 0x07, 0x07, 0x08, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f
475 };
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500476 Block bad(MALFORMED);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400477 BOOST_CHECK_EXCEPTION(bad.parse(), Block::Error, [] (const auto& e) {
478 return e.what() == "TLV-LENGTH of sub-element of type 7 exceeds TLV-VALUE boundary of parent block"s;
479 });
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700480}
481
Joao Pereira7476ebf2015-07-07 14:54:39 -0400482BOOST_AUTO_TEST_CASE(InsertBeginning)
483{
484 Block masterBlock(tlv::Name);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000485 Block firstBlock = makeStringBlock(tlv::GenericNameComponent, "firstName");
486 Block secondBlock = makeStringBlock(tlv::GenericNameComponent, "secondName");
487 Block thirdBlock = makeStringBlock(tlv::GenericNameComponent, "thirdName");
Joao Pereira7476ebf2015-07-07 14:54:39 -0400488
489 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 0);
490 masterBlock.push_back(secondBlock);
491 masterBlock.push_back(thirdBlock);
492 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 2);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000493 Block::element_const_iterator it = masterBlock.find(tlv::GenericNameComponent);
Joao Pereira7476ebf2015-07-07 14:54:39 -0400494 BOOST_CHECK_EQUAL(*it == secondBlock, true);
495
496 it = masterBlock.insert(it, firstBlock);
497
498 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 3);
499 BOOST_CHECK_EQUAL(*(it + 1) == secondBlock, true);
500 BOOST_CHECK_EQUAL(*(masterBlock.elements_begin()) == firstBlock, true);
501}
502
503BOOST_AUTO_TEST_CASE(InsertEnd)
504{
505 Block masterBlock(tlv::Name);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000506 Block firstBlock = makeStringBlock(tlv::GenericNameComponent, "firstName");
507 Block secondBlock = makeStringBlock(tlv::GenericNameComponent, "secondName");
508 Block thirdBlock = makeStringBlock(tlv::GenericNameComponent, "thirdName");
Joao Pereira7476ebf2015-07-07 14:54:39 -0400509
510 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 0);
511 masterBlock.push_back(firstBlock);
512 masterBlock.push_back(secondBlock);
513 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 2);
514 Block::element_const_iterator it = masterBlock.elements_end();
515 BOOST_CHECK_EQUAL(*(it - 1) == secondBlock, true);
516
517 it = masterBlock.insert(it, thirdBlock);
518
519 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 3);
520 BOOST_CHECK_EQUAL(*(it - 1) == secondBlock, true);
521 BOOST_CHECK_EQUAL(*(masterBlock.elements_end() - 1) == thirdBlock, true);
522}
523
524BOOST_AUTO_TEST_CASE(InsertMiddle)
525{
526 Block masterBlock(tlv::Name);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000527 Block firstBlock = makeStringBlock(tlv::GenericNameComponent, "firstName");
528 Block secondBlock = makeStringBlock(tlv::GenericNameComponent, "secondName");
529 Block thirdBlock = makeStringBlock(tlv::GenericNameComponent, "thirdName");
Joao Pereira7476ebf2015-07-07 14:54:39 -0400530
531 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 0);
532 masterBlock.push_back(firstBlock);
533 masterBlock.push_back(thirdBlock);
534 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 2);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000535 Block::element_const_iterator it = masterBlock.find(tlv::GenericNameComponent);
Joao Pereira7476ebf2015-07-07 14:54:39 -0400536 BOOST_CHECK_EQUAL(*it == firstBlock, true);
537
Junxiao Shidc4277a2017-07-17 11:34:02 +0000538 it = masterBlock.insert(it + 1, secondBlock);
Joao Pereira7476ebf2015-07-07 14:54:39 -0400539
540 BOOST_CHECK_EQUAL(*it == secondBlock, true);
541 BOOST_CHECK_EQUAL(*(it + 1) == thirdBlock, true);
542 BOOST_CHECK_EQUAL(*(it - 1) == firstBlock, true);
543}
544
545BOOST_AUTO_TEST_CASE(EraseSingleElement)
546{
547 Block masterBlock(tlv::Name);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000548 Block firstBlock = makeStringBlock(tlv::GenericNameComponent, "firstName");
549 Block secondBlock = makeStringBlock(tlv::GenericNameComponent, "secondName");
550 Block thirdBlock = makeStringBlock(tlv::GenericNameComponent, "thirdName");
Joao Pereira7476ebf2015-07-07 14:54:39 -0400551
552 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 0);
553 masterBlock.push_back(firstBlock);
554 masterBlock.push_back(secondBlock);
555 masterBlock.push_back(thirdBlock);
556 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 3);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000557 Block::element_const_iterator it = masterBlock.find(tlv::GenericNameComponent);
Joao Pereira7476ebf2015-07-07 14:54:39 -0400558 it++;
559 BOOST_CHECK_EQUAL(*it == secondBlock, true);
560
561 it = masterBlock.erase(it);
562
563 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 2);
564 BOOST_CHECK_EQUAL(*(it) == thirdBlock, true);
565 BOOST_CHECK_EQUAL(*(it - 1) == firstBlock, true);
566}
567
568BOOST_AUTO_TEST_CASE(EraseRange)
569{
570 Block masterBlock(tlv::Name);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000571 Block firstBlock = makeStringBlock(tlv::GenericNameComponent, "firstName");
572 Block secondBlock = makeStringBlock(tlv::GenericNameComponent, "secondName");
573 Block thirdBlock = makeStringBlock(tlv::GenericNameComponent, "thirdName");
574 Block fourthBlock = makeStringBlock(tlv::GenericNameComponent, "fourthName");
575 Block fifthBlock = makeStringBlock(tlv::GenericNameComponent, "fifthName");
576 Block sixthBlock = makeStringBlock(tlv::GenericNameComponent, "sixthName");
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 masterBlock.push_back(fourthBlock);
583 masterBlock.push_back(fifthBlock);
584 masterBlock.push_back(sixthBlock);
585 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 6);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000586 Block::element_const_iterator itStart = masterBlock.find(tlv::GenericNameComponent);
Joao Pereira7476ebf2015-07-07 14:54:39 -0400587 itStart++;
588 Block::element_const_iterator itEnd = itStart + 3;
589 BOOST_CHECK_EQUAL(*itStart == secondBlock, true);
590 BOOST_CHECK_EQUAL(*itEnd == fifthBlock, true);
591
592 Block::element_const_iterator newIt = masterBlock.erase(itStart, itEnd);
593
594 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 3);
595 BOOST_CHECK_EQUAL(*(newIt) == fifthBlock, true);
596 BOOST_CHECK_EQUAL(*(newIt - 1) == firstBlock, true);
597}
598
Eric Newberrya3d9fc02015-07-26 10:55:44 -0700599BOOST_AUTO_TEST_CASE(Remove)
600{
601 Block block(tlv::Data);
602 block.push_back(makeNonNegativeIntegerBlock(tlv::ContentType, 0));
603 block.push_back(makeNonNegativeIntegerBlock(tlv::FreshnessPeriod, 123));
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400604 block.push_back(makeStringBlock(tlv::Name, "/test-prefix"));
Eric Newberrya3d9fc02015-07-26 10:55:44 -0700605 block.push_back(makeNonNegativeIntegerBlock(tlv::ContentType, 2));
606 block.push_back(makeNonNegativeIntegerBlock(tlv::ContentType, 1));
607
608 BOOST_CHECK_EQUAL(5, block.elements_size());
Davide Pesavento6b330402019-04-24 00:14:01 -0400609 BOOST_CHECK_NO_THROW(block.remove(tlv::ContentType));
610 BOOST_REQUIRE_EQUAL(2, block.elements_size());
Eric Newberrya3d9fc02015-07-26 10:55:44 -0700611
Davide Pesavento6b330402019-04-24 00:14:01 -0400612 auto elements = block.elements();
Eric Newberrya3d9fc02015-07-26 10:55:44 -0700613 BOOST_CHECK_EQUAL(tlv::FreshnessPeriod, elements[0].type());
614 BOOST_CHECK_EQUAL(123, readNonNegativeInteger(elements[0]));
615 BOOST_CHECK_EQUAL(tlv::Name, elements[1].type());
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400616 BOOST_CHECK_EQUAL(readString(elements[1]).compare("/test-prefix"), 0);
Eric Newberrya3d9fc02015-07-26 10:55:44 -0700617}
618
Junxiao Shidc4277a2017-07-17 11:34:02 +0000619BOOST_AUTO_TEST_SUITE_END() // SubElements
620
Davide Pesaventoa76ea9a2021-04-24 00:06:02 -0400621BOOST_AUTO_TEST_CASE(ToAsioConstBuffer)
622{
623 Block block = "0101A0"_block;
624 boost::asio::const_buffer buffer(block);
625 BOOST_CHECK_EQUAL(boost::asio::buffer_cast<const uint8_t*>(buffer), block.wire());
626 BOOST_CHECK_EQUAL(boost::asio::buffer_size(buffer), block.size());
627}
628
Junxiao Shidc4277a2017-07-17 11:34:02 +0000629BOOST_AUTO_TEST_CASE(Equality)
630{
Davide Pesaventob10024c2017-09-22 01:36:44 -0400631 const uint8_t one[] = {0x08, 0x00};
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500632 Block a(one);
633 Block b(one);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000634 BOOST_CHECK_EQUAL(a == b, true);
635 BOOST_CHECK_EQUAL(a != b, false);
636
Davide Pesaventob10024c2017-09-22 01:36:44 -0400637 const uint8_t two[] = {0x06, 0x00};
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500638 Block c(two);
639 Block d(one);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000640 BOOST_CHECK_EQUAL(c == d, false);
641 BOOST_CHECK_EQUAL(c != d, true);
642
Davide Pesaventob10024c2017-09-22 01:36:44 -0400643 const uint8_t three[] = {0x06, 0x01, 0xcc};
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500644 Block e(two);
645 Block f(three);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000646 BOOST_CHECK_EQUAL(e == f, false);
647 BOOST_CHECK_EQUAL(e != f, true);
648}
649
Junxiao Shi72c0c642018-04-20 15:41:09 +0000650BOOST_AUTO_TEST_CASE(Print)
651{
652 // default constructed
653 Block b;
654 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(b), "[invalid]");
655
656 // zero length
657 b = "0700"_block;
658 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(b), "7[empty]");
659
660 // unparsed
661 b = "0E10FF7E4E6B3B21C902660F16ED589FCCCC"_block;
662 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(b),
663 "14[16]=FF7E4E6B3B21C902660F16ED589FCCCC");
664 // set and restore format flags
665 {
666 std::ostringstream oss;
667 oss << std::showbase << std::hex << 0xd23c4 << b << 0x4981e;
668 BOOST_CHECK_EQUAL(oss.str(), "0xd23c414[16]=FF7E4E6B3B21C902660F16ED589FCCCC0x4981e");
669 }
670
671 // parsed
672 b = "FD010808 0502CADD 59024E42"_block;
673 b.parse();
674 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(b),
675 "264[8]={5[2]=CADD,89[2]=4E42}");
676
677 // parsed then modified: print modified sub-elements
678 b = "FD010808 0502CADD 59024E42"_block;
679 b.parse();
680 b.erase(b.elements_begin());
681 b.push_back("10022386"_block);
682 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(b),
683 "264[8]={89[2]=4E42,16[2]=2386}");
684}
685
Junxiao Shi2b322eb2018-08-24 10:43:27 -0600686BOOST_AUTO_TEST_SUITE(BlockLiteral)
687
688BOOST_AUTO_TEST_CASE(Simple)
689{
Davide Pesavento6b330402019-04-24 00:14:01 -0400690 Block b0 = "4200"_block;
691 BOOST_CHECK_EQUAL(b0.type(), 0x42);
Junxiao Shi2b322eb2018-08-24 10:43:27 -0600692 BOOST_CHECK_EQUAL(b0.value_size(), 0);
693
694 Block b1 = "0101A0"_block;
695 BOOST_CHECK_EQUAL(b1.type(), 0x01);
696 BOOST_REQUIRE_EQUAL(b1.value_size(), 1);
697 BOOST_CHECK_EQUAL(b1.value()[0], 0xA0);
698}
699
700BOOST_AUTO_TEST_CASE(Comment)
701{
702 Block b0 = "a2b0c0d2eBf0G.B 1+"_block;
703 BOOST_CHECK_EQUAL(b0.type(), 0x20);
704 BOOST_REQUIRE_EQUAL(b0.value_size(), 2);
705 BOOST_CHECK_EQUAL(b0.value()[0], 0xB0);
706 BOOST_CHECK_EQUAL(b0.value()[1], 0xB1);
707}
708
709BOOST_AUTO_TEST_CASE(BadInput)
710{
711 BOOST_CHECK_THROW(""_block, std::invalid_argument);
712 BOOST_CHECK_THROW("1"_block, std::invalid_argument);
713 BOOST_CHECK_THROW("333"_block, std::invalid_argument);
Davide Pesavento6b330402019-04-24 00:14:01 -0400714 BOOST_CHECK_THROW("xx yy zz"_block, std::invalid_argument); // only comments
Junxiao Shi2b322eb2018-08-24 10:43:27 -0600715
Davide Pesavento6b330402019-04-24 00:14:01 -0400716 BOOST_CHECK_THROW("0000"_block, tlv::Error); // invalid type
717 BOOST_CHECK_THROW("0202C0"_block, tlv::Error); // truncated value
718 BOOST_CHECK_THROW("0201C0C1"_block, tlv::Error); // trailing garbage
Junxiao Shi2b322eb2018-08-24 10:43:27 -0600719}
720
721BOOST_AUTO_TEST_SUITE_END() // BlockLiteral
722
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100723BOOST_AUTO_TEST_SUITE_END() // TestBlock
724BOOST_AUTO_TEST_SUITE_END() // Encoding
Alexander Afanasyev233750e2014-02-16 00:50:07 -0800725
Alexander Afanasyev74633892015-02-08 18:08:46 -0800726} // namespace tests
Alexander Afanasyev233750e2014-02-16 00:50:07 -0800727} // namespace ndn