name: check TLV type when constructing Name from Block
Change-Id: I5006d188c738597e684638fad89865c6776e2c94
diff --git a/.jenkins.d/20-tests.sh b/.jenkins.d/20-tests.sh
index ab14284..ea5f998 100755
--- a/.jenkins.d/20-tests.sh
+++ b/.jenkins.d/20-tests.sh
@@ -1,14 +1,15 @@
#!/usr/bin/env bash
set -eo pipefail
+# https://github.com/google/sanitizers/wiki/SanitizerCommonFlags
# https://github.com/google/sanitizers/wiki/AddressSanitizerFlags
ASAN_OPTIONS="color=always"
+ASAN_OPTIONS+=":strip_path_prefix=${PWD}/"
ASAN_OPTIONS+=":check_initialization_order=1"
ASAN_OPTIONS+=":detect_stack_use_after_return=1"
ASAN_OPTIONS+=":strict_init_order=1"
ASAN_OPTIONS+=":strict_string_checks=1"
ASAN_OPTIONS+=":detect_invalid_pointer_pairs=2"
-ASAN_OPTIONS+=":strip_path_prefix=${PWD}/"
export ASAN_OPTIONS
# https://www.boost.org/doc/libs/release/libs/test/doc/html/boost_test/runtime_config/summary.html
diff --git a/ndn-cxx/data.hpp b/ndn-cxx/data.hpp
index ac8ef0a..b4f8179 100644
--- a/ndn-cxx/data.hpp
+++ b/ndn-cxx/data.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2023 Regents of the University of California.
+ * Copyright (c) 2013-2024 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -53,7 +53,7 @@
Data(const Name& name = Name());
/** @brief Construct a Data packet by decoding from @p wire.
- * @param wire TLV block of type tlv::Data; may be signed or unsigned.
+ * @param wire TLV element of type tlv::Data; may be signed or unsigned.
* @warning In certain contexts that use `Data::shared_from_this()`, Data must be created using
* `std::make_shared`. Otherwise, `shared_from_this()` may trigger undefined behavior.
* One example where this is necessary is storing Data into a subclass of InMemoryStorage.
@@ -188,7 +188,7 @@
/**
* @brief Set `Content` from a Block.
- * @param block TLV block to be used as Content; must be valid
+ * @param block TLV element to be used as Content; must be valid
* @return A reference to this Data, to allow chaining.
*
* If the block's TLV-TYPE is tlv::Content, it will be used directly as this Data's
diff --git a/ndn-cxx/interest.hpp b/ndn-cxx/interest.hpp
index 7b817ab..965da32 100644
--- a/ndn-cxx/interest.hpp
+++ b/ndn-cxx/interest.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2023 Regents of the University of California.
+ * Copyright (c) 2013-2024 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -323,7 +323,7 @@
/**
* @brief Set `ApplicationParameters` from a Block.
- * @param block TLV block to be used as ApplicationParameters; must be valid
+ * @param block TLV element to be used as ApplicationParameters; must be valid
* @return A reference to this Interest.
*
* If the block's TLV-TYPE is tlv::ApplicationParameters, it will be used directly as
diff --git a/ndn-cxx/name.cpp b/ndn-cxx/name.cpp
index 9f38e4a..240edc5 100644
--- a/ndn-cxx/name.cpp
+++ b/ndn-cxx/name.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2023 Regents of the University of California.
+ * Copyright (c) 2013-2024 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -39,9 +39,8 @@
Name::Name() = default;
Name::Name(const Block& wire)
- : m_wire(wire)
{
- m_wire.parse();
+ wireDecode(wire);
}
Name::Name(std::string_view uri)
diff --git a/ndn-cxx/name.hpp b/ndn-cxx/name.hpp
index ad68c33..5f72ef8 100644
--- a/ndn-cxx/name.hpp
+++ b/ndn-cxx/name.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2023 Regents of the University of California.
+ * Copyright (c) 2013-2024 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -71,14 +71,16 @@
Name();
/**
- * @brief Decode Name from wire encoding.
- * @throw tlv::Error wire encoding is invalid
+ * @brief Create Name from wire encoding.
+ * @param wire TLV element of type tlv::Name
*
- * This is a more efficient equivalent for:
+ * This is equivalent to:
* @code
* Name name;
* name.wireDecode(wire);
* @endcode
+ *
+ * @throw tlv::Error The wire encoding is invalid.
*/
explicit
Name(const Block& wire);
@@ -93,7 +95,7 @@
/**
* @brief Create name from NDN URI.
* @sa https://docs.named-data.net/NDN-packet-spec/0.3/name.html#ndn-uri-scheme
- * @note This constructor enables implicit conversion from a string literal
+ * @note This constructor enables implicit conversion from a string literal.
*/
Name(const char* uri)
: Name(std::string_view(uri))
@@ -103,28 +105,31 @@
/**
* @brief Create name from NDN URI.
* @sa https://docs.named-data.net/NDN-packet-spec/0.3/name.html#ndn-uri-scheme
- * @note This constructor enables implicit conversion from `std::string`
+ * @note This constructor enables implicit conversion from `std::string`.
*/
Name(const std::string& uri)
: Name(std::string_view(uri))
{
}
- /** @brief Write URI representation of the name to the output stream.
- * @sa https://docs.named-data.net/NDN-packet-spec/0.3/name.html#ndn-uri-scheme
+ /**
+ * @brief Write URI representation of the name to the output stream.
+ * @sa https://docs.named-data.net/NDN-packet-spec/0.3/name.html#ndn-uri-scheme
*/
void
toUri(std::ostream& os, name::UriFormat format = name::UriFormat::DEFAULT) const;
- /** @brief Get URI representation of the name.
- * @return URI representation; the "ndn:" scheme identifier is not included
- * @note To print URI representation into a stream, it is more efficient to use `os << name`.
- * @sa https://docs.named-data.net/NDN-packet-spec/0.3/name.html#ndn-uri-scheme
+ /**
+ * @brief Get URI representation of the name.
+ * @return URI representation; the "ndn:" scheme identifier is not included.
+ * @note To print the URI representation to a stream, it is more efficient to use `os << name`.
+ * @sa https://docs.named-data.net/NDN-packet-spec/0.3/name.html#ndn-uri-scheme
*/
std::string
toUri(name::UriFormat format = name::UriFormat::DEFAULT) const;
- /** @brief Check if this instance already has wire encoding.
+ /**
+ * @brief Check if this instance already has wire encoding.
*/
bool
hasWire() const noexcept
@@ -132,26 +137,30 @@
return m_wire.hasWire();
}
- /** @brief Fast encoding or block size estimation.
+ /**
+ * @brief Prepend wire encoding to @p encoder.
*/
template<encoding::Tag TAG>
size_t
wireEncode(EncodingImpl<TAG>& encoder) const;
- /** @brief Perform wire encoding, or return existing wire encoding.
- * @post hasWire() == true
+ /**
+ * @brief Perform wire encoding, or return existing (cached) wire encoding.
+ * @post hasWire() == true
*/
const Block&
wireEncode() const;
- /** @brief Decode name from wire encoding.
- * @throw tlv::Error wire encoding is invalid
- * @post hasWire() == true
+ /**
+ * @brief Decode name from wire encoding.
+ * @throw tlv::Error The wire encoding is invalid.
+ * @post hasWire() == true
*/
void
wireDecode(const Block& wire);
- /** @brief Make a deep copy of the name, reallocating the underlying memory buffer.
+ /**
+ * @brief Make a deep copy of the name, reallocating the underlying memory buffer.
*/
Name
deepCopy() const;
@@ -335,7 +344,7 @@
return append(Component(tlv::GenericNameComponent, value));
}
- /** @brief Append a `NameComponent` of TLV-TYPE @p type, copying TLV-VALUE from a range.
+ /** @brief Append a `NameComponent` of TLV-TYPE @p type, copying the TLV-VALUE from a range.
* @tparam Iterator an @c InputIterator dereferencing to a one-octet value type. More efficient
* implementation is available when it is a @c RandomAccessIterator.
* @param type the TLV-TYPE.
@@ -350,7 +359,7 @@
return append(Component(type, first, last));
}
- /** @brief Append a `GenericNameComponent`, copying TLV-VALUE from a range.
+ /** @brief Append a `GenericNameComponent`, copying the TLV-VALUE from a range.
* @tparam Iterator an @c InputIterator dereferencing to a one-octet value type. More efficient
* implementation is available when it is a @c RandomAccessIterator.
* @param first beginning of the range.
@@ -382,9 +391,10 @@
Name&
append(const PartialName& name);
- /** @brief Append a component with a NonNegativeInteger.
- * @return A reference to this Name, to allow chaining.
- * @sa https://docs.named-data.net/NDN-packet-spec/0.3/tlv.html#non-negative-integer-encoding
+ /**
+ * @brief Append a component with a NonNegativeInteger.
+ * @return A reference to this Name, to allow chaining.
+ * @sa https://docs.named-data.net/NDN-packet-spec/0.3/tlv.html#non-negative-integer-encoding
*/
Name&
appendNumber(uint64_t number)
diff --git a/tests/unit/name.t.cpp b/tests/unit/name.t.cpp
index 734edb7..b105818 100644
--- a/tests/unit/name.t.cpp
+++ b/tests/unit/name.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2023 Regents of the University of California.
+ * Copyright (c) 2013-2024 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -49,8 +49,10 @@
BOOST_AUTO_TEST_CASE(EncodeDecode)
{
- std::string uri = "/Emid/25042=P3/.../..../%1C%9F/"
- "sha256digest=0415e3624a151850ac686c84f155f29808c0dd73819aa4a4c20be73a4d8a874c";
+ constexpr auto uri = "/Emid/25042=P3/.../..../%1C%9F/"
+ "sha256digest=0415e3624a151850ac686c84f155f29808c0dd73819aa4a4c20be73a4d8a874c"sv;
+
+ // construct from std::string_view
Name name(uri);
BOOST_CHECK_EQUAL(name.size(), 6);
BOOST_CHECK_EQUAL(name[0], Component("Emid"));
@@ -66,11 +68,22 @@
Block wire = name.wireEncode();
BOOST_CHECK_EQUAL(wire,
- "0737 0804456D6964 FD61D2025033 0800 08012E 08021C9F "
- "01200415E3624A151850AC686C84F155F29808C0DD73819AA4A4C20BE73A4D8A874C"_block);
+ "0737 0804456D6964 FD61D2025033 0800 08012E 08021C9F "
+ "01200415E3624A151850AC686C84F155F29808C0DD73819AA4A4C20BE73A4D8A874C"_block);
+ // construct from Block
Name decoded(wire);
- BOOST_CHECK_EQUAL(decoded, name);
+ BOOST_TEST(decoded == name);
+ BOOST_CHECK_EXCEPTION(Name("0802CAFE"_block), tlv::Error,
+ [] (const auto& e) { return e.what() == "Expecting Name element, but TLV has type 8"sv; });
+
+ // implicit conversion from char*
+ name = "/hello";
+ BOOST_TEST(name.toUri(name::UriFormat::CANONICAL) == "/8=hello");
+
+ // implicit conversion from std::string
+ name = "/world"s;
+ BOOST_TEST(name.toUri(name::UriFormat::CANONICAL) == "/8=world");
}
BOOST_AUTO_TEST_CASE(ParseUri)
@@ -332,34 +345,34 @@
Name name;
uint64_t number;
- BOOST_CHECK_NO_THROW(number = name.appendSegment(30923).at(-1).toSegment());
+ number = name.appendSegment(30923).at(-1).toSegment();
BOOST_TEST(number == 30923);
- BOOST_CHECK_NO_THROW(number = name.appendByteOffset(41880).at(-1).toByteOffset());
+ number = name.appendByteOffset(41880).at(-1).toByteOffset();
BOOST_TEST(number == 41880);
auto before = time::toUnixTimestamp(time::system_clock::now());
- BOOST_CHECK_NO_THROW(number = name.appendVersion().at(-1).toVersion());
+ number = name.appendVersion().at(-1).toVersion();
auto after = time::toUnixTimestamp(time::system_clock::now());
BOOST_TEST(number >= before.count());
BOOST_TEST(number <= after.count());
- BOOST_CHECK_NO_THROW(number = name.appendVersion(25912).at(-1).toVersion());
+ number = name.appendVersion(25912).at(-1).toVersion();
BOOST_TEST(number == 25912);
const auto tp = time::system_clock::now();
time::system_clock::time_point tp2;
- BOOST_CHECK_NO_THROW(tp2 = name.appendTimestamp(tp).at(-1).toTimestamp());
+ tp2 = name.appendTimestamp(tp).at(-1).toTimestamp();
BOOST_TEST(time::abs(tp2 - tp) <= 1_us);
- BOOST_CHECK_NO_THROW(number = name.appendSequenceNumber(11676).at(-1).toSequenceNumber());
+ number = name.appendSequenceNumber(11676).at(-1).toSequenceNumber();
BOOST_TEST(number == 11676);
name.appendKeyword({0xab, 0xcd, 0xef});
- BOOST_TEST(name.at(-1) == Component::fromEscapedString("32=%AB%CD%EF"));
+ BOOST_TEST(name.at(-1) == Component::fromEscapedString("32=%AB%CD%EF"sv));
name.appendKeyword("test-keyword");
- BOOST_TEST(name.at(-1) == Component::fromEscapedString("32=test-keyword"));
+ BOOST_TEST(name.at(-1) == Component::fromEscapedString("32=test-keyword"sv));
}
BOOST_AUTO_TEST_CASE(EraseComponent)
@@ -543,7 +556,7 @@
BOOST_CHECK_GT (Name("/Z/A/C/Y").compare(1, 2, Name("/X/A"), 1), 0);
}
-BOOST_AUTO_TEST_CASE(UnorderedMap)
+BOOST_AUTO_TEST_CASE(UnorderedMapKey)
{
std::unordered_map<Name, int> map;
Name name1("/1");