blob: a39df871d5552d94335a0c13018d03f450e6b110 [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);
Eric Newberry6235aac2015-08-13 16:03:47 -0700114
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();
Eric Newberry6235aac2015-08-13 16:03:47 -0700123
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500124 BOOST_CHECK_EQUAL_COLLECTIONS(b2.begin(), b2.end(), buf, buf + sizeof(buf));
Junxiao Shidc4277a2017-07-17 11:34:02 +0000125 BOOST_CHECK_EQUAL(buf2, b2.getBuffer());
Eric Newberry6235aac2015-08-13 16:03:47 -0700126}
127
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100128BOOST_AUTO_TEST_CASE(FromBlockCopyOnWriteModifyCopy)
Eric Newberry6235aac2015-08-13 16:03:47 -0700129{
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500130 const uint8_t buf[] = {
Eric Newberry6235aac2015-08-13 16:03:47 -0700131 0x05, 0x0b, 0x07, 0x03, 0x01, 0x02, 0x03, 0x0a, 0x04, 0x04, 0x05, 0x06, 0x07,
132 };
133
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500134 Block b1(buf);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000135 auto buf1 = b1.getBuffer();
Eric Newberry6235aac2015-08-13 16:03:47 -0700136
Junxiao Shidc4277a2017-07-17 11:34:02 +0000137 Block b2(b1, b1.begin(), b1.end());
Eric Newberry6235aac2015-08-13 16:03:47 -0700138
Junxiao Shidc4277a2017-07-17 11:34:02 +0000139 b2.parse();
140 b2.remove(tlv::Name);
141 b2.encode();
Eric Newberry6235aac2015-08-13 16:03:47 -0700142
Junxiao Shidc4277a2017-07-17 11:34:02 +0000143 b1.parse();
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500144 BOOST_CHECK_EQUAL_COLLECTIONS(b1.begin(), b1.end(), buf, buf + sizeof(buf));
Junxiao Shidc4277a2017-07-17 11:34:02 +0000145 BOOST_CHECK_EQUAL(buf1, b1.getBuffer());
Eric Newberry6235aac2015-08-13 16:03:47 -0700146}
147
Junxiao Shidc4277a2017-07-17 11:34:02 +0000148BOOST_AUTO_TEST_CASE(FromType)
Alexander Afanasyev233750e2014-02-16 00:50:07 -0800149{
Junxiao Shidc4277a2017-07-17 11:34:02 +0000150 Block b1(4);
Davide Pesavento6b330402019-04-24 00:14:01 -0400151 BOOST_CHECK_EQUAL(b1.isValid(), true);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000152 BOOST_CHECK_EQUAL(b1.type(), 4);
153 BOOST_CHECK_EQUAL(b1.size(), 2); // 1-octet TLV-TYPE and 1-octet TLV-LENGTH
Davide Pesavento5c803b92019-02-02 19:23:48 -0500154 BOOST_CHECK_EQUAL(b1.hasValue(), false);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000155 BOOST_CHECK_EQUAL(b1.value_size(), 0);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400156 BOOST_CHECK(b1.value() == nullptr);
Alexander Afanasyev233750e2014-02-16 00:50:07 -0800157
Junxiao Shidc4277a2017-07-17 11:34:02 +0000158 Block b2(258);
Davide Pesavento6b330402019-04-24 00:14:01 -0400159 BOOST_CHECK_EQUAL(b2.isValid(), true);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000160 BOOST_CHECK_EQUAL(b2.type(), 258);
161 BOOST_CHECK_EQUAL(b2.size(), 4); // 3-octet TLV-TYPE and 1-octet TLV-LENGTH
Davide Pesavento5c803b92019-02-02 19:23:48 -0500162 BOOST_CHECK_EQUAL(b2.hasValue(), false);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000163 BOOST_CHECK_EQUAL(b2.value_size(), 0);
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);
174 BOOST_CHECK(b3.value() == nullptr);
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700175}
176
Davide Pesavento5c803b92019-02-02 19:23:48 -0500177BOOST_AUTO_TEST_CASE(FromTypeAndBuffer)
178{
179 const uint8_t VALUE[] = {0x11, 0x12, 0x13, 0x14};
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500180 auto bufferPtr = std::make_shared<Buffer>(VALUE, sizeof(VALUE));
Davide Pesavento5c803b92019-02-02 19:23:48 -0500181
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400182 Block b1(42, std::move(bufferPtr));
183 BOOST_CHECK_EQUAL(b1.isValid(), true);
184 BOOST_CHECK_EQUAL(b1.type(), 42);
185 BOOST_CHECK_EQUAL(b1.size(), 6);
186 BOOST_CHECK_EQUAL(b1.hasValue(), true);
187 BOOST_CHECK_EQUAL(b1.value_size(), sizeof(VALUE));
188 BOOST_CHECK(b1.value() != nullptr);
189
190 // empty buffer as TLV-VALUE
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500191 Block b2(63, std::make_shared<Buffer>());
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400192 BOOST_CHECK_EQUAL(b2.isValid(), true);
193 BOOST_CHECK_EQUAL(b2.type(), 63);
194 BOOST_CHECK_EQUAL(b2.size(), 2);
195 BOOST_CHECK_EQUAL(b2.hasValue(), true);
196 BOOST_CHECK_EQUAL(b2.value_size(), 0);
197 BOOST_CHECK(b2.value() == nullptr);
Davide Pesavento5c803b92019-02-02 19:23:48 -0500198}
199
200BOOST_AUTO_TEST_CASE(FromTypeAndBlock)
201{
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500202 const uint8_t buf[] = {0x80, 0x06, 0x81, 0x01, 0x01, 0x82, 0x01, 0x01};
203 Block nested(buf);
Davide Pesavento5c803b92019-02-02 19:23:48 -0500204
205 Block b(84, nested);
Davide Pesavento6b330402019-04-24 00:14:01 -0400206 BOOST_CHECK_EQUAL(b.isValid(), true);
Davide Pesavento5c803b92019-02-02 19:23:48 -0500207 BOOST_CHECK_EQUAL(b.type(), 84);
208 BOOST_CHECK_EQUAL(b.size(), 10);
209 BOOST_CHECK_EQUAL(b.hasValue(), true);
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500210 BOOST_CHECK_EQUAL(b.value_size(), sizeof(buf));
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400211 BOOST_CHECK(b.value() != nullptr);
Davide Pesavento5c803b92019-02-02 19:23:48 -0500212}
213
Junxiao Shif0da7892015-04-04 22:16:16 -0700214BOOST_AUTO_TEST_CASE(FromStream)
Alexander Afanasyev21ef2392014-03-25 12:40:22 -0700215{
Junxiao Shidc4277a2017-07-17 11:34:02 +0000216 std::stringstream stream;
217 stream.write(reinterpret_cast<const char*>(TEST_BUFFER), sizeof(TEST_BUFFER));
218 stream.seekg(0);
Alexander Afanasyev21ef2392014-03-25 12:40:22 -0700219
Junxiao Shidc4277a2017-07-17 11:34:02 +0000220 Block b = Block::fromStream(stream);
Davide Pesavento6b330402019-04-24 00:14:01 -0400221 BOOST_CHECK_EQUAL(b.type(), 66);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000222 BOOST_CHECK_EQUAL(b.size(), 3);
223 BOOST_CHECK_EQUAL(b.value_size(), 1);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400224 BOOST_CHECK_EQUAL(*b.wire(), 0x42);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000225 BOOST_CHECK_EQUAL(*b.value(), 0xfa);
Alexander Afanasyev21ef2392014-03-25 12:40:22 -0700226
Junxiao Shidc4277a2017-07-17 11:34:02 +0000227 b = Block::fromStream(stream);
228 BOOST_CHECK_EQUAL(b.type(), 1);
229 BOOST_CHECK_EQUAL(b.size(), 3);
230 BOOST_CHECK_EQUAL(b.value_size(), 1);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400231 BOOST_CHECK_EQUAL(*b.wire(), 0x01);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000232 BOOST_CHECK_EQUAL(*b.value(), 0xfb);
Alexander Afanasyev21ef2392014-03-25 12:40:22 -0700233
Davide Pesavento6b330402019-04-24 00:14:01 -0400234 b = Block::fromStream(stream);
235 BOOST_CHECK_EQUAL(b.type(), 0xffffffff);
236 BOOST_CHECK_EQUAL(b.size(), 6);
237 BOOST_CHECK_EQUAL(b.value_size(), 0);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400238 BOOST_CHECK_EQUAL(*b.wire(), 0xfe);
239 BOOST_CHECK(b.value() == nullptr);
Davide Pesavento6b330402019-04-24 00:14:01 -0400240
241 BOOST_CHECK(stream.eof());
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400242 BOOST_CHECK_EXCEPTION(Block::fromStream(stream), tlv::Error, [] (const auto& e) {
243 return e.what() == "Empty buffer during TLV parsing"s;
244 });
Alexander Afanasyev21ef2392014-03-25 12:40:22 -0700245}
246
Junxiao Shif0da7892015-04-04 22:16:16 -0700247BOOST_AUTO_TEST_CASE(FromStreamWhitespace) // Bug 2728
248{
Junxiao Shidc4277a2017-07-17 11:34:02 +0000249 const uint8_t PACKET[] = {
Junxiao Shif0da7892015-04-04 22:16:16 -0700250 0x06, 0x20, // Data
251 0x07, 0x11, // Name
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000252 0x08, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, // GenericNameComponent 'hello'
253 0x08, 0x01, 0x31, // GenericNameComponent '1'
254 0x08, 0x05, 0x77, 0x6f, 0x72, 0x6c, 0x64, // GenericNameComponent 'world'
Junxiao Shif0da7892015-04-04 22:16:16 -0700255 0x14, 0x00, // MetaInfo empty
256 0x15, 0x00, // Content empty
257 0x16, 0x05, // SignatureInfo
Junxiao Shidc4277a2017-07-17 11:34:02 +0000258 0x1b, 0x01, 0x01, // SignatureType RSA
259 0x1c, 0x00, // KeyLocator empty
Junxiao Shif0da7892015-04-04 22:16:16 -0700260 0x17, 0x00 // SignatureValue empty
261 };
262 // TLV-LENGTH of <Data> is 0x20 which happens to be ASCII whitespace
263
264 std::stringstream stream;
265 stream.write(reinterpret_cast<const char*>(PACKET), sizeof(PACKET));
266 stream.seekg(0);
267
Junxiao Shidc4277a2017-07-17 11:34:02 +0000268 Block b = Block::fromStream(stream);
269 BOOST_CHECK_EQUAL(b.type(), 6);
270 BOOST_CHECK_EQUAL(b.value_size(), 32);
271 b.parse();
Davide Pesavento6b330402019-04-24 00:14:01 -0400272 BOOST_CHECK_EQUAL(b.elements_size(), 5);
Junxiao Shif0da7892015-04-04 22:16:16 -0700273}
274
Junxiao Shi760cc7b2017-07-22 19:17:49 +0000275BOOST_AUTO_TEST_CASE(FromStreamZeroLength)
Junxiao Shif0da7892015-04-04 22:16:16 -0700276{
Junxiao Shi760cc7b2017-07-22 19:17:49 +0000277 const uint8_t BUFFER[] = {0x70, 0x00,
278 0x71, 0x03, 0x86, 0x11, 0x24,
279 0x72, 0x00};
Junxiao Shif0da7892015-04-04 22:16:16 -0700280
281 std::stringstream stream;
282 stream.write(reinterpret_cast<const char*>(BUFFER), sizeof(BUFFER));
283 stream.seekg(0);
284
Junxiao Shi760cc7b2017-07-22 19:17:49 +0000285 Block b1 = Block::fromStream(stream);
286 BOOST_CHECK_EQUAL(b1.type(), 0x70);
287 BOOST_CHECK_EQUAL(b1.value_size(), 0);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400288 BOOST_CHECK(b1.value() == nullptr);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000289
Junxiao Shi760cc7b2017-07-22 19:17:49 +0000290 Block b2 = Block::fromStream(stream);
291 BOOST_CHECK_EQUAL(b2.type(), 0x71);
292 BOOST_CHECK_EQUAL(b2.value_size(), 3);
293 const uint8_t EXPECTED_VALUE2[] = {0x86, 0x11, 0x24};
294 BOOST_CHECK_EQUAL_COLLECTIONS(b2.value_begin(), b2.value_end(),
295 EXPECTED_VALUE2, EXPECTED_VALUE2 + sizeof(EXPECTED_VALUE2));
296
297 Block b3 = Block::fromStream(stream);
298 BOOST_CHECK_EQUAL(b3.type(), 0x72);
299 BOOST_CHECK_EQUAL(b3.value_size(), 0);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400300 BOOST_CHECK(b3.value() == nullptr);
Junxiao Shi760cc7b2017-07-22 19:17:49 +0000301
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400302 BOOST_CHECK_EXCEPTION(Block::fromStream(stream), tlv::Error, [] (const auto& e) {
303 return e.what() == "Empty buffer during TLV parsing"s;
304 });
Junxiao Shi760cc7b2017-07-22 19:17:49 +0000305}
306
307BOOST_AUTO_TEST_CASE(FromStreamPacketTooLarge)
308{
309 const uint8_t BUFFER[] = {0x07, 0xfe, 0x00, 0x01, 0x00, 0x00};
310
311 std::stringstream stream;
312 stream.write(reinterpret_cast<const char*>(BUFFER), sizeof(BUFFER));
313 for (int i = 0; i < 0x10000; ++i) {
314 stream.put('\0');
315 }
316 stream.seekg(0);
317
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400318 BOOST_CHECK_EXCEPTION(Block::fromStream(stream), tlv::Error, [] (const auto& e) {
319 return e.what() == "TLV-LENGTH from stream exceeds limit"s;
320 });
Junxiao Shidc4277a2017-07-17 11:34:02 +0000321}
322
323BOOST_AUTO_TEST_CASE(FromWireBuffer)
324{
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500325 auto buffer = std::make_shared<Buffer>(TEST_BUFFER, sizeof(TEST_BUFFER));
Junxiao Shidc4277a2017-07-17 11:34:02 +0000326
Junxiao Shidc4277a2017-07-17 11:34:02 +0000327 bool isOk = false;
328 Block b;
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500329 std::tie(isOk, b) = Block::fromBuffer(buffer);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000330 BOOST_CHECK(isOk);
Davide Pesavento6b330402019-04-24 00:14:01 -0400331 BOOST_CHECK_EQUAL(b.type(), 66);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000332 BOOST_CHECK_EQUAL(b.size(), 3);
333 BOOST_CHECK_EQUAL(b.value_size(), 1);
Davide Pesavento6b330402019-04-24 00:14:01 -0400334 BOOST_CHECK_EQUAL(*b.wire(), 0x42);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000335 BOOST_CHECK_EQUAL(*b.value(), 0xfa);
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500336 size_t offset = b.size();
Junxiao Shidc4277a2017-07-17 11:34:02 +0000337
338 std::tie(isOk, b) = Block::fromBuffer(buffer, offset);
339 BOOST_CHECK(isOk);
340 BOOST_CHECK_EQUAL(b.type(), 1);
341 BOOST_CHECK_EQUAL(b.size(), 3);
342 BOOST_CHECK_EQUAL(b.value_size(), 1);
343 BOOST_CHECK_EQUAL(*b.wire(), 0x01);
344 BOOST_CHECK_EQUAL(*b.value(), 0xfb);
345 offset += b.size();
346
347 std::tie(isOk, b) = Block::fromBuffer(buffer, offset);
Davide Pesavento6b330402019-04-24 00:14:01 -0400348 BOOST_CHECK(isOk);
349 BOOST_CHECK_EQUAL(b.type(), 0xffffffff);
350 BOOST_CHECK_EQUAL(b.size(), 6);
351 BOOST_CHECK_EQUAL(b.value_size(), 0);
352 BOOST_CHECK_EQUAL(*b.wire(), 0xfe);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400353 BOOST_CHECK(b.value() == nullptr);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000354}
355
356BOOST_AUTO_TEST_CASE(FromRawBuffer)
357{
Junxiao Shidc4277a2017-07-17 11:34:02 +0000358 bool isOk = false;
359 Block b;
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500360 std::tie(isOk, b) = Block::fromBuffer(TEST_BUFFER);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000361 BOOST_CHECK(isOk);
Davide Pesavento6b330402019-04-24 00:14:01 -0400362 BOOST_CHECK_EQUAL(b.type(), 66);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000363 BOOST_CHECK_EQUAL(b.size(), 3);
364 BOOST_CHECK_EQUAL(b.value_size(), 1);
Davide Pesavento6b330402019-04-24 00:14:01 -0400365 BOOST_CHECK_EQUAL(*b.wire(), 0x42);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000366 BOOST_CHECK_EQUAL(*b.value(), 0xfa);
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500367 auto offset = b.size();
Junxiao Shidc4277a2017-07-17 11:34:02 +0000368
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500369 std::tie(isOk, b) = Block::fromBuffer(make_span(TEST_BUFFER).subspan(offset));
Junxiao Shidc4277a2017-07-17 11:34:02 +0000370 BOOST_CHECK(isOk);
371 BOOST_CHECK_EQUAL(b.type(), 1);
372 BOOST_CHECK_EQUAL(b.size(), 3);
373 BOOST_CHECK_EQUAL(b.value_size(), 1);
374 BOOST_CHECK_EQUAL(*b.wire(), 0x01);
375 BOOST_CHECK_EQUAL(*b.value(), 0xfb);
376 offset += b.size();
377
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500378 std::tie(isOk, b) = Block::fromBuffer(make_span(TEST_BUFFER).subspan(offset));
Davide Pesavento6b330402019-04-24 00:14:01 -0400379 BOOST_CHECK(isOk);
380 BOOST_CHECK_EQUAL(b.type(), 0xffffffff);
381 BOOST_CHECK_EQUAL(b.size(), 6);
382 BOOST_CHECK_EQUAL(b.value_size(), 0);
383 BOOST_CHECK_EQUAL(*b.wire(), 0xfe);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400384 BOOST_CHECK(b.value() == nullptr);
Davide Pesavento6b330402019-04-24 00:14:01 -0400385}
386
Davide Pesavento1a4a7bf2020-12-04 22:30:46 -0500387static const Buffer MalformedInputs[] = {
388 {0x00, 0x00}, // invalid TLV type (zero)
389 {0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}, // TLV type too large
390 {0x01, 0xff, 0x42, 0x42}, // bad TLV length
391 {0x01, 0x02, 0x03}, // truncated TLV value
Davide Pesavento6b330402019-04-24 00:14:01 -0400392};
393
Davide Pesavento1a4a7bf2020-12-04 22:30:46 -0500394BOOST_DATA_TEST_CASE(Malformed, MalformedInputs)
Davide Pesavento6b330402019-04-24 00:14:01 -0400395{
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500396 // constructor from span
397 BOOST_CHECK_THROW(Block{sample}, tlv::Error);
Davide Pesavento6b330402019-04-24 00:14:01 -0400398
399 // fromStream()
400 std::stringstream stream;
Davide Pesavento1a4a7bf2020-12-04 22:30:46 -0500401 stream.write(sample.template get<char>(), sample.size());
Davide Pesavento6b330402019-04-24 00:14:01 -0400402 stream.seekg(0);
403 BOOST_CHECK_THROW(Block::fromStream(stream), tlv::Error);
404
405 // fromBuffer(), ConstBufferPtr overload
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500406 auto buf = std::make_shared<Buffer>(sample.begin(), sample.end());
Davide Pesavento6b330402019-04-24 00:14:01 -0400407 bool isOk;
408 Block b;
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500409 std::tie(isOk, b) = Block::fromBuffer(buf);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000410 BOOST_CHECK(!isOk);
Davide Pesavento6b330402019-04-24 00:14:01 -0400411 BOOST_CHECK(!b.isValid());
412
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500413 // fromBuffer(), span overload
414 std::tie(isOk, b) = Block::fromBuffer(sample);
Davide Pesavento6b330402019-04-24 00:14:01 -0400415 BOOST_CHECK(!isOk);
416 BOOST_CHECK(!b.isValid());
Junxiao Shif0da7892015-04-04 22:16:16 -0700417}
418
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100419BOOST_AUTO_TEST_SUITE_END() // Construction
420
Davide Pesaventoa76ea9a2021-04-24 00:06:02 -0400421BOOST_AUTO_TEST_CASE(BlockFromValue)
422{
423 Block b1(301);
424 BOOST_CHECK_EXCEPTION(b1.blockFromValue(), Block::Error, [] (const auto& e) {
425 return e.what() == "Cannot construct block from empty TLV-VALUE"s;
426 });
427
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500428 Block b2(302, std::make_shared<Buffer>());
Davide Pesaventoa76ea9a2021-04-24 00:06:02 -0400429 BOOST_CHECK_EXCEPTION(b2.blockFromValue(), Block::Error, [] (const auto& e) {
430 return e.what() == "Cannot construct block from empty TLV-VALUE"s;
431 });
432
433 b1.encode();
434 Block b3(303, b1);
435 b3.encode();
436 Block nested = b3.blockFromValue();
437 BOOST_CHECK_EQUAL(nested.type(), 301);
438 BOOST_CHECK_EQUAL(nested.size(), 4);
439 BOOST_CHECK_EQUAL(nested.value_size(), 0);
440 BOOST_CHECK(nested == b1);
441}
442
Junxiao Shidc4277a2017-07-17 11:34:02 +0000443BOOST_AUTO_TEST_SUITE(SubElements)
444
445BOOST_AUTO_TEST_CASE(Parse)
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700446{
Junxiao Shidc4277a2017-07-17 11:34:02 +0000447 const uint8_t PACKET[] = {
448 0x06, 0x20, // Data
449 0x07, 0x11, // Name
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000450 0x08, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, // GenericNameComponent 'hello'
451 0x08, 0x01, 0x31, // GenericNameComponent '1'
452 0x08, 0x05, 0x77, 0x6f, 0x72, 0x6c, 0x64, // GenericNameComponent 'world'
Junxiao Shidc4277a2017-07-17 11:34:02 +0000453 0x14, 0x00, // MetaInfo empty
454 0x15, 0x00, // Content empty
455 0x16, 0x05, // SignatureInfo
456 0x1b, 0x01, 0x01, // SignatureType RSA
457 0x1c, 0x00, // KeyLocator empty
458 0x17, 0x00 // SignatureValue empty
459 };
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500460 Block data(PACKET);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000461 data.parse();
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700462
Junxiao Shidc4277a2017-07-17 11:34:02 +0000463 BOOST_CHECK_EQUAL(data.elements_size(), 5);
464 BOOST_CHECK_EQUAL(data.elements().at(0).type(), 0x07);
465 BOOST_CHECK_EQUAL(data.elements().at(0).elements().size(), 0); // parse is not recursive
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700466
Junxiao Shidc4277a2017-07-17 11:34:02 +0000467 BOOST_CHECK(data.get(0x15) == data.elements().at(2));
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400468 BOOST_CHECK_EXCEPTION(data.get(0x01), Block::Error, [] (const auto& e) {
469 return e.what() == "No sub-element of type 1 found in block of type 6"s;
470 });
Junxiao Shidc4277a2017-07-17 11:34:02 +0000471
472 BOOST_CHECK(data.find(0x15) == data.elements_begin() + 2);
473 BOOST_CHECK(data.find(0x01) == data.elements_end());
Davide Pesavento6b330402019-04-24 00:14:01 -0400474
475 const uint8_t MALFORMED[] = {
476 // TLV-LENGTH of nested element is greater than TLV-LENGTH of enclosing element
477 0x05, 0x05, 0x07, 0x07, 0x08, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f
478 };
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500479 Block bad(MALFORMED);
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400480 BOOST_CHECK_EXCEPTION(bad.parse(), Block::Error, [] (const auto& e) {
481 return e.what() == "TLV-LENGTH of sub-element of type 7 exceeds TLV-VALUE boundary of parent block"s;
482 });
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700483}
484
Joao Pereira7476ebf2015-07-07 14:54:39 -0400485BOOST_AUTO_TEST_CASE(InsertBeginning)
486{
487 Block masterBlock(tlv::Name);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000488 Block firstBlock = makeStringBlock(tlv::GenericNameComponent, "firstName");
489 Block secondBlock = makeStringBlock(tlv::GenericNameComponent, "secondName");
490 Block thirdBlock = makeStringBlock(tlv::GenericNameComponent, "thirdName");
Joao Pereira7476ebf2015-07-07 14:54:39 -0400491
492 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 0);
493 masterBlock.push_back(secondBlock);
494 masterBlock.push_back(thirdBlock);
495 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 2);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000496 Block::element_const_iterator it = masterBlock.find(tlv::GenericNameComponent);
Joao Pereira7476ebf2015-07-07 14:54:39 -0400497 BOOST_CHECK_EQUAL(*it == secondBlock, true);
498
499 it = masterBlock.insert(it, firstBlock);
500
501 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 3);
502 BOOST_CHECK_EQUAL(*(it + 1) == secondBlock, true);
503 BOOST_CHECK_EQUAL(*(masterBlock.elements_begin()) == firstBlock, true);
504}
505
506BOOST_AUTO_TEST_CASE(InsertEnd)
507{
508 Block masterBlock(tlv::Name);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000509 Block firstBlock = makeStringBlock(tlv::GenericNameComponent, "firstName");
510 Block secondBlock = makeStringBlock(tlv::GenericNameComponent, "secondName");
511 Block thirdBlock = makeStringBlock(tlv::GenericNameComponent, "thirdName");
Joao Pereira7476ebf2015-07-07 14:54:39 -0400512
513 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 0);
514 masterBlock.push_back(firstBlock);
515 masterBlock.push_back(secondBlock);
516 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 2);
517 Block::element_const_iterator it = masterBlock.elements_end();
518 BOOST_CHECK_EQUAL(*(it - 1) == secondBlock, true);
519
520 it = masterBlock.insert(it, thirdBlock);
521
522 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 3);
523 BOOST_CHECK_EQUAL(*(it - 1) == secondBlock, true);
524 BOOST_CHECK_EQUAL(*(masterBlock.elements_end() - 1) == thirdBlock, true);
525}
526
527BOOST_AUTO_TEST_CASE(InsertMiddle)
528{
529 Block masterBlock(tlv::Name);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000530 Block firstBlock = makeStringBlock(tlv::GenericNameComponent, "firstName");
531 Block secondBlock = makeStringBlock(tlv::GenericNameComponent, "secondName");
532 Block thirdBlock = makeStringBlock(tlv::GenericNameComponent, "thirdName");
Joao Pereira7476ebf2015-07-07 14:54:39 -0400533
534 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 0);
535 masterBlock.push_back(firstBlock);
536 masterBlock.push_back(thirdBlock);
537 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 2);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000538 Block::element_const_iterator it = masterBlock.find(tlv::GenericNameComponent);
Joao Pereira7476ebf2015-07-07 14:54:39 -0400539 BOOST_CHECK_EQUAL(*it == firstBlock, true);
540
Junxiao Shidc4277a2017-07-17 11:34:02 +0000541 it = masterBlock.insert(it + 1, secondBlock);
Joao Pereira7476ebf2015-07-07 14:54:39 -0400542
543 BOOST_CHECK_EQUAL(*it == secondBlock, true);
544 BOOST_CHECK_EQUAL(*(it + 1) == thirdBlock, true);
545 BOOST_CHECK_EQUAL(*(it - 1) == firstBlock, true);
546}
547
548BOOST_AUTO_TEST_CASE(EraseSingleElement)
549{
550 Block masterBlock(tlv::Name);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000551 Block firstBlock = makeStringBlock(tlv::GenericNameComponent, "firstName");
552 Block secondBlock = makeStringBlock(tlv::GenericNameComponent, "secondName");
553 Block thirdBlock = makeStringBlock(tlv::GenericNameComponent, "thirdName");
Joao Pereira7476ebf2015-07-07 14:54:39 -0400554
555 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 0);
556 masterBlock.push_back(firstBlock);
557 masterBlock.push_back(secondBlock);
558 masterBlock.push_back(thirdBlock);
559 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 3);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000560 Block::element_const_iterator it = masterBlock.find(tlv::GenericNameComponent);
Joao Pereira7476ebf2015-07-07 14:54:39 -0400561 it++;
562 BOOST_CHECK_EQUAL(*it == secondBlock, true);
563
564 it = masterBlock.erase(it);
565
566 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 2);
567 BOOST_CHECK_EQUAL(*(it) == thirdBlock, true);
568 BOOST_CHECK_EQUAL(*(it - 1) == firstBlock, true);
569}
570
571BOOST_AUTO_TEST_CASE(EraseRange)
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");
577 Block fourthBlock = makeStringBlock(tlv::GenericNameComponent, "fourthName");
578 Block fifthBlock = makeStringBlock(tlv::GenericNameComponent, "fifthName");
579 Block sixthBlock = makeStringBlock(tlv::GenericNameComponent, "sixthName");
Joao Pereira7476ebf2015-07-07 14:54:39 -0400580
581 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 0);
582 masterBlock.push_back(firstBlock);
583 masterBlock.push_back(secondBlock);
584 masterBlock.push_back(thirdBlock);
585 masterBlock.push_back(fourthBlock);
586 masterBlock.push_back(fifthBlock);
587 masterBlock.push_back(sixthBlock);
588 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 6);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000589 Block::element_const_iterator itStart = masterBlock.find(tlv::GenericNameComponent);
Joao Pereira7476ebf2015-07-07 14:54:39 -0400590 itStart++;
591 Block::element_const_iterator itEnd = itStart + 3;
592 BOOST_CHECK_EQUAL(*itStart == secondBlock, true);
593 BOOST_CHECK_EQUAL(*itEnd == fifthBlock, true);
594
595 Block::element_const_iterator newIt = masterBlock.erase(itStart, itEnd);
596
597 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 3);
598 BOOST_CHECK_EQUAL(*(newIt) == fifthBlock, true);
599 BOOST_CHECK_EQUAL(*(newIt - 1) == firstBlock, true);
600}
601
Eric Newberrya3d9fc02015-07-26 10:55:44 -0700602BOOST_AUTO_TEST_CASE(Remove)
603{
604 Block block(tlv::Data);
605 block.push_back(makeNonNegativeIntegerBlock(tlv::ContentType, 0));
606 block.push_back(makeNonNegativeIntegerBlock(tlv::FreshnessPeriod, 123));
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400607 block.push_back(makeStringBlock(tlv::Name, "/test-prefix"));
Eric Newberrya3d9fc02015-07-26 10:55:44 -0700608 block.push_back(makeNonNegativeIntegerBlock(tlv::ContentType, 2));
609 block.push_back(makeNonNegativeIntegerBlock(tlv::ContentType, 1));
610
611 BOOST_CHECK_EQUAL(5, block.elements_size());
Davide Pesavento6b330402019-04-24 00:14:01 -0400612 BOOST_CHECK_NO_THROW(block.remove(tlv::ContentType));
613 BOOST_REQUIRE_EQUAL(2, block.elements_size());
Eric Newberrya3d9fc02015-07-26 10:55:44 -0700614
Davide Pesavento6b330402019-04-24 00:14:01 -0400615 auto elements = block.elements();
Eric Newberrya3d9fc02015-07-26 10:55:44 -0700616 BOOST_CHECK_EQUAL(tlv::FreshnessPeriod, elements[0].type());
617 BOOST_CHECK_EQUAL(123, readNonNegativeInteger(elements[0]));
618 BOOST_CHECK_EQUAL(tlv::Name, elements[1].type());
Davide Pesavento5f6865c2021-04-23 23:24:11 -0400619 BOOST_CHECK_EQUAL(readString(elements[1]).compare("/test-prefix"), 0);
Eric Newberrya3d9fc02015-07-26 10:55:44 -0700620}
621
Junxiao Shidc4277a2017-07-17 11:34:02 +0000622BOOST_AUTO_TEST_SUITE_END() // SubElements
623
Davide Pesaventoa76ea9a2021-04-24 00:06:02 -0400624BOOST_AUTO_TEST_CASE(ToAsioConstBuffer)
625{
626 Block block = "0101A0"_block;
627 boost::asio::const_buffer buffer(block);
628 BOOST_CHECK_EQUAL(boost::asio::buffer_cast<const uint8_t*>(buffer), block.wire());
629 BOOST_CHECK_EQUAL(boost::asio::buffer_size(buffer), block.size());
630}
631
Junxiao Shidc4277a2017-07-17 11:34:02 +0000632BOOST_AUTO_TEST_CASE(Equality)
633{
Davide Pesaventob10024c2017-09-22 01:36:44 -0400634 const uint8_t one[] = {0x08, 0x00};
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500635 Block a(one);
636 Block b(one);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000637 BOOST_CHECK_EQUAL(a == b, true);
638 BOOST_CHECK_EQUAL(a != b, false);
639
Davide Pesaventob10024c2017-09-22 01:36:44 -0400640 const uint8_t two[] = {0x06, 0x00};
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500641 Block c(two);
642 Block d(one);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000643 BOOST_CHECK_EQUAL(c == d, false);
644 BOOST_CHECK_EQUAL(c != d, true);
645
Davide Pesaventob10024c2017-09-22 01:36:44 -0400646 const uint8_t three[] = {0x06, 0x01, 0xcc};
Davide Pesaventofbea4fc2022-02-08 07:26:04 -0500647 Block e(two);
648 Block f(three);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000649 BOOST_CHECK_EQUAL(e == f, false);
650 BOOST_CHECK_EQUAL(e != f, true);
651}
652
Junxiao Shi72c0c642018-04-20 15:41:09 +0000653BOOST_AUTO_TEST_CASE(Print)
654{
655 // default constructed
656 Block b;
657 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(b), "[invalid]");
658
659 // zero length
660 b = "0700"_block;
661 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(b), "7[empty]");
662
663 // unparsed
664 b = "0E10FF7E4E6B3B21C902660F16ED589FCCCC"_block;
665 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(b),
666 "14[16]=FF7E4E6B3B21C902660F16ED589FCCCC");
667 // set and restore format flags
668 {
669 std::ostringstream oss;
670 oss << std::showbase << std::hex << 0xd23c4 << b << 0x4981e;
671 BOOST_CHECK_EQUAL(oss.str(), "0xd23c414[16]=FF7E4E6B3B21C902660F16ED589FCCCC0x4981e");
672 }
673
674 // parsed
675 b = "FD010808 0502CADD 59024E42"_block;
676 b.parse();
677 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(b),
678 "264[8]={5[2]=CADD,89[2]=4E42}");
679
680 // parsed then modified: print modified sub-elements
681 b = "FD010808 0502CADD 59024E42"_block;
682 b.parse();
683 b.erase(b.elements_begin());
684 b.push_back("10022386"_block);
685 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(b),
686 "264[8]={89[2]=4E42,16[2]=2386}");
687}
688
Junxiao Shi2b322eb2018-08-24 10:43:27 -0600689BOOST_AUTO_TEST_SUITE(BlockLiteral)
690
691BOOST_AUTO_TEST_CASE(Simple)
692{
Davide Pesavento6b330402019-04-24 00:14:01 -0400693 Block b0 = "4200"_block;
694 BOOST_CHECK_EQUAL(b0.type(), 0x42);
Junxiao Shi2b322eb2018-08-24 10:43:27 -0600695 BOOST_CHECK_EQUAL(b0.value_size(), 0);
696
697 Block b1 = "0101A0"_block;
698 BOOST_CHECK_EQUAL(b1.type(), 0x01);
699 BOOST_REQUIRE_EQUAL(b1.value_size(), 1);
700 BOOST_CHECK_EQUAL(b1.value()[0], 0xA0);
701}
702
703BOOST_AUTO_TEST_CASE(Comment)
704{
705 Block b0 = "a2b0c0d2eBf0G.B 1+"_block;
706 BOOST_CHECK_EQUAL(b0.type(), 0x20);
707 BOOST_REQUIRE_EQUAL(b0.value_size(), 2);
708 BOOST_CHECK_EQUAL(b0.value()[0], 0xB0);
709 BOOST_CHECK_EQUAL(b0.value()[1], 0xB1);
710}
711
712BOOST_AUTO_TEST_CASE(BadInput)
713{
714 BOOST_CHECK_THROW(""_block, std::invalid_argument);
715 BOOST_CHECK_THROW("1"_block, std::invalid_argument);
716 BOOST_CHECK_THROW("333"_block, std::invalid_argument);
Davide Pesavento6b330402019-04-24 00:14:01 -0400717 BOOST_CHECK_THROW("xx yy zz"_block, std::invalid_argument); // only comments
Junxiao Shi2b322eb2018-08-24 10:43:27 -0600718
Davide Pesavento6b330402019-04-24 00:14:01 -0400719 BOOST_CHECK_THROW("0000"_block, tlv::Error); // invalid type
720 BOOST_CHECK_THROW("0202C0"_block, tlv::Error); // truncated value
721 BOOST_CHECK_THROW("0201C0C1"_block, tlv::Error); // trailing garbage
Junxiao Shi2b322eb2018-08-24 10:43:27 -0600722}
723
724BOOST_AUTO_TEST_SUITE_END() // BlockLiteral
725
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100726BOOST_AUTO_TEST_SUITE_END() // TestBlock
727BOOST_AUTO_TEST_SUITE_END() // Encoding
Alexander Afanasyev233750e2014-02-16 00:50:07 -0800728
Alexander Afanasyev74633892015-02-08 18:08:46 -0800729} // namespace tests
Alexander Afanasyev233750e2014-02-16 00:50:07 -0800730} // namespace ndn