Skip to content

Commit

Permalink
name: check TLV type when constructing Name from Block
Browse files Browse the repository at this point in the history
Change-Id: I5006d188c738597e684638fad89865c6776e2c94
  • Loading branch information
Pesa committed Feb 9, 2024
1 parent fdc5b51 commit 5d36a52
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 49 deletions.
3 changes: 2 additions & 1 deletion .jenkins.d/20-tests.sh
Original file line number Diff line number Diff line change
@@ -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
Expand Down
6 changes: 3 additions & 3 deletions ndn-cxx/data.hpp
Original file line number Diff line number Diff line change
@@ -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).
*
Expand Down Expand Up @@ -53,7 +53,7 @@ class Data : public PacketBase, public std::enable_shared_from_this<Data>
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.
Expand Down Expand Up @@ -188,7 +188,7 @@ class Data : public PacketBase, public std::enable_shared_from_this<Data>

/**
* @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
Expand Down
4 changes: 2 additions & 2 deletions ndn-cxx/interest.hpp
Original file line number Diff line number Diff line change
@@ -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).
*
Expand Down Expand Up @@ -323,7 +323,7 @@ class Interest : public PacketBase, public std::enable_shared_from_this<Interest

/**
* @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
Expand Down
5 changes: 2 additions & 3 deletions ndn-cxx/name.cpp
Original file line number Diff line number Diff line change
@@ -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).
*
Expand Down Expand Up @@ -39,9 +39,8 @@ namespace ndn {
Name::Name() = default;

Name::Name(const Block& wire)
: m_wire(wire)
{
m_wire.parse();
wireDecode(wire);
}

Name::Name(std::string_view uri)
Expand Down
60 changes: 35 additions & 25 deletions ndn-cxx/name.hpp
Original file line number Diff line number Diff line change
@@ -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).
*
Expand Down Expand Up @@ -71,14 +71,16 @@ class Name : private boost::totally_ordered<Name>
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);
Expand All @@ -93,7 +95,7 @@ class Name : private boost::totally_ordered<Name>
/**
* @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))
Expand All @@ -103,55 +105,62 @@ class Name : private boost::totally_ordered<Name>
/**
* @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
{
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;
Expand Down Expand Up @@ -335,7 +344,7 @@ class Name : private boost::totally_ordered<Name>
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.
Expand All @@ -350,7 +359,7 @@ class Name : private boost::totally_ordered<Name>
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.
Expand Down Expand Up @@ -382,9 +391,10 @@ class Name : private boost::totally_ordered<Name>
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)
Expand Down
43 changes: 28 additions & 15 deletions tests/unit/name.t.cpp
Original file line number Diff line number Diff line change
@@ -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).
*
Expand Down Expand Up @@ -49,8 +49,10 @@ BOOST_AUTO_TEST_SUITE(TestName)

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"));
Expand All @@ -66,11 +68,22 @@ BOOST_AUTO_TEST_CASE(EncodeDecode)

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)
Expand Down Expand Up @@ -332,34 +345,34 @@ BOOST_AUTO_TEST_CASE(AppendTypedComponent)
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)
Expand Down Expand Up @@ -543,7 +556,7 @@ BOOST_AUTO_TEST_CASE(CompareFunc)
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");
Expand Down

0 comments on commit 5d36a52

Please sign in to comment.