From 296c3a185d72efbcae23c1e2232b8932e24d21b7 Mon Sep 17 00:00:00 2001 From: Davide Pesavento Date: Thu, 4 May 2023 21:40:40 -0400 Subject: [PATCH] interest+data: add string_view overloads for convenience Also, explicitly declare the nullptr_t overloads as deleted, so that users get a clear compilation error instead of a potentially confusing "ambiguous overload" if they try to pass nullptr to these functions. Change-Id: I399efcbd698a0d3f7e29219d21eb1a53a1d71070 --- docs/examples.rst | 2 +- examples/producer.cpp | 4 +- ndn-cxx/data.cpp | 22 ++++-- ndn-cxx/data.hpp | 67 +++++++++++------ ndn-cxx/interest.cpp | 36 +++++++-- ndn-cxx/interest.hpp | 102 ++++++++++++++++---------- ndn-cxx/link.cpp | 8 +- tests/unit/data.t.cpp | 53 ++++++++----- tests/unit/interest.t.cpp | 92 +++++++++++++---------- tests/unit/link.t.cpp | 21 ++++-- tests/unit/security/certificate.t.cpp | 7 +- tests/unit/security/key-chain.t.cpp | 2 +- 12 files changed, 265 insertions(+), 151 deletions(-) diff --git a/docs/examples.rst b/docs/examples.rst index a778b250..a2a0a0cb 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -41,7 +41,7 @@ using :ndn-cxx:`Face::put` method. .. literalinclude:: ../examples/producer.cpp :language: c++ :linenos: - :emphasize-lines: 39-42,55,62-64,79,87,91 + :emphasize-lines: 39-42,55,60-63,78,86,90 Consumer that uses Scheduler ---------------------------- diff --git a/examples/producer.cpp b/examples/producer.cpp index 24562800..8ba70880 100644 --- a/examples/producer.cpp +++ b/examples/producer.cpp @@ -60,9 +60,7 @@ private: auto data = std::make_shared(); data->setName(interest.getName()); data->setFreshnessPeriod(10_s); - - constexpr std::string_view content{"Hello, world!"}; - data->setContent({reinterpret_cast(content.data()), content.size()}); + data->setContent("Hello, world!"); // In order for the consumer application to be able to validate the packet, you need to setup // the following keys: diff --git a/ndn-cxx/data.cpp b/ndn-cxx/data.cpp index 4391d357..2e45a837 100644 --- a/ndn-cxx/data.cpp +++ b/ndn-cxx/data.cpp @@ -261,11 +261,19 @@ Data::setContent(span value) return *this; } +Data& +Data::setContent(std::string_view value) +{ + m_content = makeStringBlock(tlv::Content, value); + resetWire(); + return *this; +} + Data& Data::setContent(ConstBufferPtr value) { - if (value == nullptr) { - NDN_THROW(std::invalid_argument("Content buffer cannot be nullptr")); + if (!value) { + NDN_THROW(std::invalid_argument("Content buffer cannot be null")); } m_content = Block(tlv::Content, std::move(value)); @@ -276,8 +284,10 @@ Data::setContent(ConstBufferPtr value) Data& Data::unsetContent() { - m_content = {}; - resetWire(); + if (m_content.isValid()) { + m_content = {}; + resetWire(); + } return *this; } @@ -300,8 +310,8 @@ Data::setSignatureValue(span value) Data& Data::setSignatureValue(ConstBufferPtr value) { - if (value == nullptr) { - NDN_THROW(std::invalid_argument("SignatureValue buffer cannot be nullptr")); + if (!value) { + NDN_THROW(std::invalid_argument("SignatureValue buffer cannot be null")); } m_signatureValue = Block(tlv::SignatureValue, std::move(value)); diff --git a/ndn-cxx/data.hpp b/ndn-cxx/data.hpp index 5467e49e..ac8ef0ac 100644 --- a/ndn-cxx/data.hpp +++ b/ndn-cxx/data.hpp @@ -95,18 +95,21 @@ public: const Block& wireEncode(EncodingBuffer& encoder, span signature) const; - /** @brief Encode into a Block. - * @pre Data must be signed. + /** + * @brief Encode into a Block. + * @pre Data must be signed. */ const Block& wireEncode() const; - /** @brief Decode from @p wire. + /** + * @brief Decode from @p wire. */ void wireDecode(const Block& wire); - /** @brief Check if this instance has cached wire encoding. + /** + * @brief Check if this instance has cached wire encoding. */ bool hasWire() const noexcept @@ -114,16 +117,17 @@ public: return m_wire.hasWire(); } - /** @brief Get full name including implicit digest - * @pre hasWire() == true; i.e. wireEncode() must have been called - * @throw Error Data has no wire encoding + /** + * @brief Get the full name (including implicit digest). + * @pre hasWire() == true, i.e., wireEncode() must have been called. + * @throw Error Data has no wire encoding */ const Name& getFullName() const; public: // Data fields /** - * @brief Get the data name. + * @brief Get the %Data name. */ const Name& getName() const noexcept @@ -132,7 +136,7 @@ public: // Data fields } /** - * @brief Set the data name. + * @brief Set the %Data name. * @return A reference to this Data, to allow chaining. */ Data& @@ -201,14 +205,25 @@ public: // Data fields Data& setContent(span value); + /** + * @brief Set `Content` by copying from a string. + * @param value string with the TLV-VALUE of the content + * @return A reference to this Data, to allow chaining. + */ + Data& + setContent(std::string_view value); + /** * @brief Set `Content` from a shared buffer. - * @param value buffer with the TLV-VALUE of the content; must not be nullptr + * @param value buffer with the TLV-VALUE of the content; must not be null * @return A reference to this Data, to allow chaining. */ Data& setContent(ConstBufferPtr value); + Data& + setContent(std::nullptr_t) = delete; + /** * @brief Remove the `Content` element. * @return A reference to this Data, to allow chaining. @@ -226,14 +241,15 @@ public: // Data fields return m_signatureInfo; } - /** @brief Set the `SignatureInfo` element. + /** + * @brief Set the `SignatureInfo` element. * - * This is a low-level function that should not normally be called directly by applications. - * Instead, provide a SignatureInfo to the SigningInfo object passed to KeyChain::sign(). + * This is a low-level function that should not normally be called directly by applications. + * Instead, provide a SignatureInfo to the SigningInfo object passed to KeyChain::sign(). * - * @return A reference to this Data, to allow chaining. - * @warning SignatureInfo is overwritten when the packet is signed via KeyChain::sign(). - * @sa SigningInfo + * @return A reference to this Data, to allow chaining. + * @warning SignatureInfo is overwritten when the packet is signed via KeyChain::sign(). + * @sa SigningInfo */ Data& setSignatureInfo(const SignatureInfo& info); @@ -262,7 +278,7 @@ public: // Data fields /** * @brief Set `SignatureValue` from a shared buffer. - * @param value buffer containing the TLV-VALUE of the SignatureValue; must not be nullptr + * @param value buffer containing the TLV-VALUE of the SignatureValue; must not be null * @return A reference to this Data, to allow chaining. * * This is a low-level function that should not normally be called directly by applications. @@ -273,11 +289,15 @@ public: // Data fields Data& setSignatureValue(ConstBufferPtr value); - /** @brief Extract ranges of Data covered by the signature. - * @throw Error Data cannot be encoded or is missing ranges necessary for signing - * @warning The returned pointers will be invalidated if wireDecode() or wireEncode() are called. + Data& + setSignatureValue(std::nullptr_t) = delete; + + /** + * @brief Extract ranges of Data covered by the signature. + * @throw Error Data cannot be encoded or is missing ranges necessary for signing + * @warning The returned pointers will be invalidated if wireDecode() or wireEncode() are called. */ - InputBuffers + [[nodiscard]] InputBuffers extractSignedRanges() const; public: // MetaInfo fields @@ -332,8 +352,9 @@ public: // SignatureInfo fields } protected: - /** @brief Clear wire encoding and cached FullName - * @note This does not clear the SignatureValue. + /** + * @brief Clear wire encoding and cached FullName. + * @note This does not clear the SignatureValue. */ void resetWire(); diff --git a/ndn-cxx/interest.cpp b/ndn-cxx/interest.cpp index f5b1ea3b..3c235622 100644 --- a/ndn-cxx/interest.cpp +++ b/ndn-cxx/interest.cpp @@ -376,6 +376,26 @@ Interest::setName(const Name& name) return *this; } +Interest& +Interest::setCanBePrefix(bool canBePrefix) +{ + if (canBePrefix != m_canBePrefix) { + m_canBePrefix = canBePrefix; + m_wire.reset(); + } + return *this; +} + +Interest& +Interest::setMustBeFresh(bool mustBeFresh) +{ + if (mustBeFresh != m_mustBeFresh) { + m_mustBeFresh = mustBeFresh; + m_wire.reset(); + } + return *this; +} + Interest& Interest::setForwardingHint(std::vector value) { @@ -384,7 +404,7 @@ Interest::setForwardingHint(std::vector value) return *this; } -static auto +[[nodiscard]] static auto generateNonce() { uint32_t r = random::generateWord32(); @@ -488,11 +508,17 @@ Interest::setApplicationParameters(span value) return setApplicationParametersInternal(makeBinaryBlock(tlv::ApplicationParameters, value)); } +Interest& +Interest::setApplicationParameters(std::string_view value) +{ + return setApplicationParametersInternal(makeStringBlock(tlv::ApplicationParameters, value)); +} + Interest& Interest::setApplicationParameters(ConstBufferPtr value) { - if (value == nullptr) { - NDN_THROW(std::invalid_argument("ApplicationParameters buffer cannot be nullptr")); + if (!value) { + NDN_THROW(std::invalid_argument("ApplicationParameters buffer cannot be null")); } return setApplicationParametersInternal({tlv::ApplicationParameters, std::move(value)}); @@ -618,8 +644,8 @@ Interest::setSignatureValue(span value) Interest& Interest::setSignatureValue(ConstBufferPtr value) { - if (value == nullptr) { - NDN_THROW(std::invalid_argument("InterestSignatureValue buffer cannot be nullptr")); + if (!value) { + NDN_THROW(std::invalid_argument("InterestSignatureValue buffer cannot be null")); } return setSignatureValueInternal({tlv::InterestSignatureValue, std::move(value)}); diff --git a/ndn-cxx/interest.hpp b/ndn-cxx/interest.hpp index dff5f399..5ca79248 100644 --- a/ndn-cxx/interest.hpp +++ b/ndn-cxx/interest.hpp @@ -71,10 +71,10 @@ public: Nonce(uint8_t n1, uint8_t n2, uint8_t n3, uint8_t n4) noexcept { - data()[0] = n1; - data()[1] = n2; - data()[2] = n3; - data()[3] = n4; + (*this)[0] = n1; + (*this)[1] = n2; + (*this)[2] = n3; + (*this)[3] = n4; } private: // non-member operators @@ -153,22 +153,27 @@ public: toUri() const; public: // matching - /** @brief Check if Interest can be satisfied by @p data. + /** + * @brief Check if this Interest can be satisfied by @p data. * - * This method considers Name, CanBePrefix, and MustBeFresh. However, MustBeFresh processing - * is limited to rejecting Data with zero/omitted FreshnessPeriod. + * This method considers `Name`, `CanBePrefix`, and `MustBeFresh`. However, `MustBeFresh` + * evaluation is limited to rejecting Data with zero/omitted `FreshnessPeriod`. */ - bool + [[nodiscard]] bool matchesData(const Data& data) const; - /** @brief Check if this Interest matches @p other + /** + * @brief Check if this Interest matches @p other. * - * Two Interests match if both have the same Name, CanBePrefix, and MustBeFresh. + * Two Interests match if they have the same `Name`, `CanBePrefix`, and `MustBeFresh`. */ - bool + [[nodiscard]] bool matchesInterest(const Interest& other) const; -public: // element access +public: // Interest fields + /** + * @brief Get the %Interest name. + */ const Name& getName() const noexcept { @@ -176,8 +181,8 @@ public: // element access } /** - * @brief Set the %Interest's name. - * @throw std::invalid_argument @p name is invalid + * @brief Set the %Interest name. + * @throw std::invalid_argument @p name is not a valid %Interest name */ Interest& setName(const Name& name); @@ -196,12 +201,7 @@ public: // element access * @param canBePrefix Whether the element should be present. */ Interest& - setCanBePrefix(bool canBePrefix) - { - m_canBePrefix = canBePrefix; - m_wire.reset(); - return *this; - } + setCanBePrefix(bool canBePrefix); /** * @brief Check whether the `MustBeFresh` element is present. @@ -217,19 +217,22 @@ public: // element access * @param mustBeFresh Whether the element should be present. */ Interest& - setMustBeFresh(bool mustBeFresh) - { - m_mustBeFresh = mustBeFresh; - m_wire.reset(); - return *this; - } + setMustBeFresh(bool mustBeFresh); + /** + * @brief Get the delegations (names) in the `ForwardingHint`. + */ span getForwardingHint() const noexcept { return m_forwardingHint; } + /** + * @brief Set the `ForwardingHint` delegations (names). + * + * To completely remove the `ForwardingHint` element from the Interest, pass an empty vector. + */ Interest& setForwardingHint(std::vector value); @@ -253,7 +256,7 @@ public: // element access /** * @brief Set the %Interest's nonce. * - * Use `setNonce(nullopt)` to remove any nonce from the Interest. + * Use `setNonce(std::nullopt)` to remove any nonce from the Interest. */ Interest& setNonce(std::optional nonce); @@ -295,7 +298,7 @@ public: // element access /** * @brief Set the %Interest's hop limit. * - * Use `setHopLimit(nullopt)` to remove any hop limit from the Interest. + * Use `setHopLimit(std::nullopt)` to remove any hop limit from the Interest. */ Interest& setHopLimit(std::optional hopLimit); @@ -353,9 +356,21 @@ public: // element access Interest& setApplicationParameters(span value); + /** + * @brief Set `ApplicationParameters` by copying from a string. + * @param value string from which the TLV-VALUE of the parameters will be copied + * @return A reference to this Interest. + * + * This function will also recompute the value of the ParametersSha256DigestComponent in the + * Interest's name. If the name does not contain a ParametersSha256DigestComponent, one will + * be appended to it. + */ + Interest& + setApplicationParameters(std::string_view value); + /** * @brief Set `ApplicationParameters` from a shared buffer. - * @param value buffer containing the TLV-VALUE of the parameters; must not be nullptr + * @param value buffer containing the TLV-VALUE of the parameters; must not be null * @return A reference to this Interest. * * This function will also recompute the value of the ParametersSha256DigestComponent in the @@ -365,6 +380,9 @@ public: // element access Interest& setApplicationParameters(ConstBufferPtr value); + Interest& + setApplicationParameters(std::nullptr_t) = delete; + /** * @brief Remove the `ApplicationParameters` element from this Interest. * @return A reference to this Interest. @@ -386,7 +404,6 @@ public: // element access /** * @brief Get the `InterestSignatureInfo` element. - * @retval nullopt The element is not present. */ std::optional getSignatureInfo() const; @@ -418,7 +435,7 @@ public: // element access /** * @brief Set `InterestSignatureValue` from a shared buffer. - * @param value buffer containing the TLV-VALUE of the InterestSignatureValue; must not be nullptr + * @param value buffer containing the TLV-VALUE of the InterestSignatureValue; must not be null * @return A reference to this Interest. * @throw Error InterestSignatureInfo is unset * @@ -427,11 +444,15 @@ public: // element access Interest& setSignatureValue(ConstBufferPtr value); - /** @brief Extract ranges of Interest covered by the signature in Packet Specification v0.3 - * @throw Error Interest cannot be encoded or is missing ranges necessary for signing - * @warning The returned pointers will be invalidated if wireDecode() or wireEncode() are called. + Interest& + setSignatureValue(std::nullptr_t) = delete; + + /** + * @brief Extract ranges of Interest covered by the signature. + * @throw Error Interest cannot be encoded or is missing ranges necessary for signing + * @warning The returned pointers will be invalidated if wireDecode() or wireEncode() are called. */ - InputBuffers + [[nodiscard]] InputBuffers extractSignedRanges() const; public: // ParametersSha256DigestComponent support @@ -447,12 +468,13 @@ public: // ParametersSha256DigestComponent support s_autoCheckParametersDigest = b; } - /** @brief Check if the ParametersSha256DigestComponent in the name is valid. + /** + * @brief Check if the ParametersSha256DigestComponent in the name is valid. * - * Returns true if there is a single ParametersSha256DigestComponent in the name and the digest - * value is correct, or if there is no ParametersSha256DigestComponent in the name and the - * Interest does not contain any parameters. - * Returns false otherwise. + * Returns true if there is a single ParametersSha256DigestComponent in the name and the digest + * value is correct, or if there is no ParametersSha256DigestComponent in the name and the + * Interest does not contain any parameters. + * Returns false otherwise. */ bool isParametersDigestValid() const; diff --git a/ndn-cxx/link.cpp b/ndn-cxx/link.cpp index 976a7223..d3e28b5a 100644 --- a/ndn-cxx/link.cpp +++ b/ndn-cxx/link.cpp @@ -43,13 +43,7 @@ void Link::encodeContent() { setContentType(tlv::ContentType_Link); - - if (m_delegations.empty()) { - setContent(span{}); - } - else { - setContent(makeNestedBlock(tlv::Content, m_delegations.begin(), m_delegations.end())); - } + setContent(makeNestedBlock(tlv::Content, m_delegations.begin(), m_delegations.end())); } void diff --git a/tests/unit/data.t.cpp b/tests/unit/data.t.cpp index 4672a83a..cb7de5b1 100644 --- a/tests/unit/data.t.cpp +++ b/tests/unit/data.t.cpp @@ -168,7 +168,7 @@ BOOST_AUTO_TEST_CASE(NotSigned) { Data d; BOOST_CHECK_EXCEPTION(d.wireEncode(), tlv::Error, [] (const auto& e) { - return e.what() == "Requested wire format, but Data has not been signed"s; + return e.what() == "Requested wire format, but Data has not been signed"sv; }); } @@ -239,7 +239,7 @@ BOOST_FIXTURE_TEST_SUITE(Decode, DecodeFixture) BOOST_AUTO_TEST_CASE(NotData) { BOOST_CHECK_EXCEPTION(d.wireDecode("4202CAFE"_block), tlv::Error, [] (const auto& e) { - return e.what() == "Expecting Data element, but TLV has type 66"s; + return e.what() == "Expecting Data element, but TLV has type 66"sv; }); } @@ -330,46 +330,46 @@ BOOST_AUTO_TEST_CASE(CriticalElementOutOfOrder) "0630 1400 0703080145 1500 16031B0100 " "1720612A79399E60304A9F701C1ECAC7956BF2F1B046E6C6F0D6C29B3FE3A29BAD76"_block), tlv::Error, - [] (const auto& e) { return e.what() == "Name element is missing or out of order"s; }); + [] (const auto& e) { return e.what() == "Name element is missing or out of order"sv; }); BOOST_CHECK_EXCEPTION(d.wireDecode( "0630 0703080145 1500 1400 16031B0100 " "1720612A79399E60304A9F701C1ECAC7956BF2F1B046E6C6F0D6C29B3FE3A29BAD76"_block), tlv::Error, - [] (const auto& e) { return e.what() == "MetaInfo element is out of order"s; }); + [] (const auto& e) { return e.what() == "MetaInfo element is out of order"sv; }); BOOST_CHECK_EXCEPTION(d.wireDecode( "0630 0703080145 1400 16031B0100 1500 " "1720612A79399E60304A9F701C1ECAC7956BF2F1B046E6C6F0D6C29B3FE3A29BAD76"_block), tlv::Error, - [] (const auto& e) { return e.what() == "Content element is out of order"s; }); + [] (const auto& e) { return e.what() == "Content element is out of order"sv; }); BOOST_CHECK_EXCEPTION(d.wireDecode( "0630 0703080145 1400 1500 " "1720612A79399E60304A9F701C1ECAC7956BF2F1B046E6C6F0D6C29B3FE3A29BAD76 16031B0100"_block), tlv::Error, - [] (const auto& e) { return e.what() == "SignatureInfo element is out of order"s; }); + [] (const auto& e) { return e.what() == "SignatureInfo element is out of order"sv; }); BOOST_CHECK_EXCEPTION(d.wireDecode( "0652 0703080145 1400 1500 16031B0100 " "1720612A79399E60304A9F701C1ECAC7956BF2F1B046E6C6F0D6C29B3FE3A29BAD76" "1720612A79399E60304A9F701C1ECAC7956BF2F1B046E6C6F0D6C29B3FE3A29BAD76"_block), tlv::Error, - [] (const auto& e) { return e.what() == "SignatureValue element is out of order"s; }); + [] (const auto& e) { return e.what() == "SignatureValue element is out of order"sv; }); } BOOST_AUTO_TEST_CASE(MissingName) { BOOST_CHECK_EXCEPTION(d.wireDecode("0607 16031B0100 1700"_block), tlv::Error, - [] (const auto& e) { return e.what() == "Name element is missing or out of order"s; }); + [] (const auto& e) { return e.what() == "Name element is missing or out of order"sv; }); } BOOST_AUTO_TEST_CASE(MissingSignatureInfo) { BOOST_CHECK_EXCEPTION(d.wireDecode("0607 0703080144 1700"_block), tlv::Error, - [] (const auto& e) { return e.what() == "SignatureInfo element is missing"s; }); + [] (const auto& e) { return e.what() == "SignatureInfo element is missing"sv; }); } BOOST_AUTO_TEST_CASE(MissingSignatureValue) { BOOST_CHECK_EXCEPTION(d.wireDecode("0607 0700 16031B0100"_block), tlv::Error, - [] (const auto& e) { return e.what() == "SignatureValue element is missing"s; }); + [] (const auto& e) { return e.what() == "SignatureValue element is missing"sv; }); } BOOST_AUTO_TEST_CASE(UnrecognizedNonCriticalElementBeforeName) @@ -378,7 +378,7 @@ BOOST_AUTO_TEST_CASE(UnrecognizedNonCriticalElementBeforeName) "062E FC00 0703080144 16031B0100 " "1720612A79399E60304A9F701C1ECAC7956BF2F1B046E6C6F0D6C29B3FE3A29BAD76"_block), tlv::Error, - [] (const auto& e) { return e.what() == "Name element is missing or out of order"s; }); + [] (const auto& e) { return e.what() == "Name element is missing or out of order"sv; }); } BOOST_AUTO_TEST_CASE(UnrecognizedCriticalElement) @@ -387,7 +387,7 @@ BOOST_AUTO_TEST_CASE(UnrecognizedCriticalElement) "0632 0703080145 FB00 1400 1500 16031B0100 " "1720612A79399E60304A9F701C1ECAC7956BF2F1B046E6C6F0D6C29B3FE3A29BAD76"_block), tlv::Error, - [] (const auto& e) { return e.what() == "Unrecognized element of critical type 251"s; }); + [] (const auto& e) { return e.what() == "Unrecognized element of critical type 251"sv; }); } BOOST_AUTO_TEST_SUITE_END() // Decode @@ -523,7 +523,9 @@ BOOST_AUTO_TEST_CASE(SetContent) BOOST_TEST(d.getContent().value_bytes() == nested, boost::test_tools::per_element()); // Block overload, default constructed (invalid) - BOOST_CHECK_THROW(d.setContent(Block{}), std::invalid_argument); + BOOST_CHECK_EXCEPTION(d.setContent(Block{}), std::invalid_argument, [] (const auto& e) { + return e.what() == "Content block must be valid"sv; + }); // span overload d.setContent(nested); @@ -532,8 +534,15 @@ BOOST_AUTO_TEST_CASE(SetContent) BOOST_TEST(d.getContent().value_bytes() == nested, boost::test_tools::per_element()); d.setContent(span{}); BOOST_CHECK_EQUAL(d.hasContent(), true); - BOOST_CHECK_EQUAL(d.getContent().type(), tlv::Content); - BOOST_CHECK_EQUAL(d.getContent().value_size(), 0); + BOOST_CHECK_EQUAL(d.getContent(), "1500"_block); + + // string_view overload + d.setContent("hi"sv); + BOOST_CHECK_EQUAL(d.hasContent(), true); + BOOST_CHECK_EQUAL(d.getContent(), "15026869"_block); + d.setContent(""); + BOOST_CHECK_EQUAL(d.hasContent(), true); + BOOST_CHECK_EQUAL(d.getContent(), "1500"_block); // ConstBufferPtr overload d.setContent(std::make_shared(direct, sizeof(direct))); @@ -542,9 +551,12 @@ BOOST_AUTO_TEST_CASE(SetContent) BOOST_TEST(d.getContent().value_bytes() == direct, boost::test_tools::per_element()); d.setContent(std::make_shared()); BOOST_CHECK_EQUAL(d.hasContent(), true); - BOOST_CHECK_EQUAL(d.getContent().type(), tlv::Content); - BOOST_CHECK_EQUAL(d.getContent().value_size(), 0); - BOOST_CHECK_THROW(d.setContent(nullptr), std::invalid_argument); + BOOST_CHECK_EQUAL(d.getContent(), "1500"_block); + + // ConstBufferPtr overload, null/empty pointer (invalid) + BOOST_CHECK_EXCEPTION(d.setContent(ConstBufferPtr{}), std::invalid_argument, [] (const auto& e) { + return e.what() == "Content buffer cannot be null"sv; + }); // unset d.unsetContent(); @@ -573,7 +585,10 @@ BOOST_AUTO_TEST_CASE(SetSignatureValue) BOOST_CHECK_EQUAL(d.getSignatureValue().type(), tlv::SignatureValue); BOOST_CHECK_EQUAL(d.getSignatureValue().value_size(), 0); - BOOST_CHECK_THROW(d.setSignatureValue(nullptr), std::invalid_argument); + // ConstBufferPtr overload, null/empty pointer (invalid) + BOOST_CHECK_EXCEPTION(d.setSignatureValue(ConstBufferPtr{}), std::invalid_argument, [] (const auto& e) { + return e.what() == "SignatureValue buffer cannot be null"sv; + }); } BOOST_FIXTURE_TEST_CASE(ExtractSignedRanges, KeyChainFixture) diff --git a/tests/unit/interest.t.cpp b/tests/unit/interest.t.cpp index 036dc72c..bbf3af6b 100644 --- a/tests/unit/interest.t.cpp +++ b/tests/unit/interest.t.cpp @@ -346,7 +346,7 @@ BOOST_AUTO_TEST_CASE(MissingApplicationParameters) i.setName(Name("/A").appendParametersSha256DigestPlaceholder()); BOOST_CHECK_EQUAL(i.isParametersDigestValid(), false); BOOST_CHECK_EXCEPTION(i.wireEncode(), tlv::Error, [] (const auto& e) { - return e.what() == "Interest without parameters must not have a ParametersSha256DigestComponent"s; + return e.what() == "Interest without parameters must not have a ParametersSha256DigestComponent"sv; }); } @@ -364,7 +364,7 @@ BOOST_AUTO_TEST_CASE(MissingParametersSha256DigestComponent) i.setNonce(42); // now the check fails while attempting to reencode BOOST_CHECK_EXCEPTION(i.wireEncode(), tlv::Error, [] (const auto& e) { - return e.what() == "Interest with parameters must have a ParametersSha256DigestComponent"s; + return e.what() == "Interest with parameters must have a ParametersSha256DigestComponent"sv; }); } @@ -393,7 +393,7 @@ BOOST_FIXTURE_TEST_SUITE(Decode, DecodeFixture) BOOST_AUTO_TEST_CASE(NotAnInterest) { BOOST_CHECK_EXCEPTION(i.wireDecode("4202CAFE"_block), tlv::Error, [] (const auto& e) { - return e.what() == "Expecting Interest element, but TLV has type 66"s; + return e.what() == "Expecting Interest element, but TLV has type 66"sv; }); } @@ -506,32 +506,32 @@ BOOST_AUTO_TEST_CASE(CriticalElementOutOfOrder) "0529 2100 0703080149 1200 1E0B(1F09 1E023E15 0703080148) " "0A044ACB1E4C 0C0276A1 2201D6 2404C0C1C2C3"_block), tlv::Error, - [] (const auto& e) { return e.what() == "Name element is missing or out of order"s; }); + [] (const auto& e) { return e.what() == "Name element is missing or out of order"sv; }); BOOST_CHECK_EXCEPTION(i.wireDecode( "0529 0703080149 1200 2100 1E0B(1F09 1E023E15 0703080148) " "0A044ACB1E4C 0C0276A1 2201D6 2404C0C1C2C3"_block), tlv::Error, - [] (const auto& e) { return e.what() == "CanBePrefix element is out of order"s; }); + [] (const auto& e) { return e.what() == "CanBePrefix element is out of order"sv; }); BOOST_CHECK_EXCEPTION(i.wireDecode( "0529 0703080149 2100 1E0B(1F09 1E023E15 0703080148) 1200 " "0A044ACB1E4C 0C0276A1 2201D6 2404C0C1C2C3"_block), tlv::Error, - [] (const auto& e) { return e.what() == "MustBeFresh element is out of order"s; }); + [] (const auto& e) { return e.what() == "MustBeFresh element is out of order"sv; }); BOOST_CHECK_EXCEPTION(i.wireDecode( "0529 0703080149 2100 1200 0A044ACB1E4C " "1E0B(1F09 1E023E15 0703080148) 0C0276A1 2201D6 2404C0C1C2C3"_block), tlv::Error, - [] (const auto& e) { return e.what() == "ForwardingHint element is out of order"s; }); + [] (const auto& e) { return e.what() == "ForwardingHint element is out of order"sv; }); BOOST_CHECK_EXCEPTION(i.wireDecode( "0529 0703080149 2100 1200 1E0B(1F09 1E023E15 0703080148) " "0C0276A1 0A044ACB1E4C 2201D6 2404C0C1C2C3"_block), tlv::Error, - [] (const auto& e) { return e.what() == "Nonce element is out of order"s; }); + [] (const auto& e) { return e.what() == "Nonce element is out of order"sv; }); BOOST_CHECK_EXCEPTION(i.wireDecode( "0529 0703080149 2100 1200 1E0B(1F09 1E023E15 0703080148) " "0A044ACB1E4C 2201D6 0C0276A1 2404C0C1C2C3"_block), tlv::Error, - [] (const auto& e) { return e.what() == "InterestLifetime element is out of order"s; }); + [] (const auto& e) { return e.what() == "InterestLifetime element is out of order"sv; }); } BOOST_AUTO_TEST_CASE(NonCriticalElementOutOfOrder) @@ -558,51 +558,51 @@ BOOST_AUTO_TEST_CASE(NonCriticalElementOutOfOrder) BOOST_AUTO_TEST_CASE(MissingName) { BOOST_CHECK_EXCEPTION(i.wireDecode("0500"_block), tlv::Error, - [] (const auto& e) { return e.what() == "Name element is missing or out of order"s; }); + [] (const auto& e) { return e.what() == "Name element is missing or out of order"sv; }); BOOST_CHECK_EXCEPTION(i.wireDecode("0502 1200"_block), tlv::Error, - [] (const auto& e) { return e.what() == "Name element is missing or out of order"s; }); + [] (const auto& e) { return e.what() == "Name element is missing or out of order"sv; }); } BOOST_AUTO_TEST_CASE(BadName) { BOOST_CHECK_EXCEPTION(i.wireDecode("0502 0700"_block), tlv::Error, - [] (const auto& e) { return e.what() == "Name has zero name components"s; }); + [] (const auto& e) { return e.what() == "Name has zero name components"sv; }); BOOST_CHECK_EXCEPTION(i.wireDecode("054C 074A(080149" "02200000000000000000000000000000000000000000000000000000000000000000" "080132" "02200000000000000000000000000000000000000000000000000000000000000000)"_block), tlv::Error, - [] (const auto& e) { return e.what() == "Name has more than one ParametersSha256DigestComponent"s; }); + [] (const auto& e) { return e.what() == "Name has more than one ParametersSha256DigestComponent"sv; }); } BOOST_AUTO_TEST_CASE(BadCanBePrefix) { BOOST_CHECK_EXCEPTION(i.wireDecode("0508 0703080149 210102"_block), tlv::Error, - [] (const auto& e) { return e.what() == "CanBePrefix element has non-zero TLV-LENGTH"s; }); + [] (const auto& e) { return e.what() == "CanBePrefix element has non-zero TLV-LENGTH"sv; }); } BOOST_AUTO_TEST_CASE(BadMustBeFresh) { BOOST_CHECK_EXCEPTION(i.wireDecode("0508 0703080149 120102"_block), tlv::Error, - [] (const auto& e) { return e.what() == "MustBeFresh element has non-zero TLV-LENGTH"s; }); + [] (const auto& e) { return e.what() == "MustBeFresh element has non-zero TLV-LENGTH"sv; }); } BOOST_AUTO_TEST_CASE(BadNonce) { BOOST_CHECK_EXCEPTION(i.wireDecode("0507 0703080149 0A00"_block), tlv::Error, - [] (const auto& e) { return e.what() == "Nonce element is malformed"s; }); + [] (const auto& e) { return e.what() == "Nonce element is malformed"sv; }); BOOST_CHECK_EXCEPTION(i.wireDecode("050A 0703080149 0A0304C263"_block), tlv::Error, - [] (const auto& e) { return e.what() == "Nonce element is malformed"s; }); + [] (const auto& e) { return e.what() == "Nonce element is malformed"sv; }); BOOST_CHECK_EXCEPTION(i.wireDecode("050C 0703080149 0A05EFA420B262"_block), tlv::Error, - [] (const auto& e) { return e.what() == "Nonce element is malformed"s; }); + [] (const auto& e) { return e.what() == "Nonce element is malformed"sv; }); } BOOST_AUTO_TEST_CASE(BadHopLimit) { BOOST_CHECK_EXCEPTION(i.wireDecode("0507 0703080149 2200"_block), tlv::Error, - [] (const auto& e) { return e.what() == "HopLimit element is malformed"s; }); + [] (const auto& e) { return e.what() == "HopLimit element is malformed"sv; }); BOOST_CHECK_EXCEPTION(i.wireDecode("0509 0703080149 22021356"_block), tlv::Error, - [] (const auto& e) { return e.what() == "HopLimit element is malformed"s; }); + [] (const auto& e) { return e.what() == "HopLimit element is malformed"sv; }); } BOOST_AUTO_TEST_CASE(BadParametersDigest) @@ -631,16 +631,16 @@ BOOST_AUTO_TEST_CASE(BadParametersDigest) BOOST_AUTO_TEST_CASE(UnrecognizedNonCriticalElementBeforeName) { BOOST_CHECK_EXCEPTION(i.wireDecode("0507 FC00 0703080149"_block), tlv::Error, - [] (const auto& e) { return e.what() == "Name element is missing or out of order"s; }); + [] (const auto& e) { return e.what() == "Name element is missing or out of order"sv; }); } BOOST_AUTO_TEST_CASE(UnrecognizedCriticalElement) { BOOST_CHECK_EXCEPTION(i.wireDecode("0507 0703080149 FB00"_block), tlv::Error, - [] (const auto& e) { return e.what() == "Unrecognized element of critical type 251"s; }); + [] (const auto& e) { return e.what() == "Unrecognized element of critical type 251"sv; }); // v0.2 packet with Selectors BOOST_CHECK_EXCEPTION(i.wireDecode("0510 0703080149 09030D0101 0A0401000000"_block), tlv::Error, - [] (const auto& e) { return e.what() == "Unrecognized element of critical type 9"s; }); + [] (const auto& e) { return e.what() == "Unrecognized element of critical type 9"sv; }); } BOOST_AUTO_TEST_SUITE_END() // Decode @@ -881,7 +881,11 @@ BOOST_AUTO_TEST_CASE(SetApplicationParameters) BOOST_CHECK_EQUAL(i.getApplicationParameters(), "2401C0"_block); i.setApplicationParameters("8001C1"_block); BOOST_CHECK_EQUAL(i.getApplicationParameters(), "24038001C1"_block); - BOOST_CHECK_THROW(i.setApplicationParameters(Block{}), std::invalid_argument); + + // Block overload, default constructed (invalid) + BOOST_CHECK_EXCEPTION(i.setApplicationParameters(Block{}), std::invalid_argument, [] (const auto& e) { + return e.what() == "ApplicationParameters block must be valid"sv; + }); // span overload i.setApplicationParameters(PARAMETERS1); @@ -889,12 +893,22 @@ BOOST_AUTO_TEST_CASE(SetApplicationParameters) i.setApplicationParameters(span{}); BOOST_CHECK_EQUAL(i.getApplicationParameters(), "2400"_block); + // string_view overload + i.setApplicationParameters("hi"sv); + BOOST_CHECK_EQUAL(i.getApplicationParameters(), "24026869"_block); + i.setApplicationParameters(""); + BOOST_CHECK_EQUAL(i.getApplicationParameters(), "2400"_block); + // ConstBufferPtr overload i.setApplicationParameters(make_shared(PARAMETERS2, sizeof(PARAMETERS2))); BOOST_CHECK_EQUAL(i.getApplicationParameters(), "2401C2"_block); i.setApplicationParameters(make_shared()); BOOST_CHECK_EQUAL(i.getApplicationParameters(), "2400"_block); - BOOST_CHECK_THROW(i.setApplicationParameters(nullptr), std::invalid_argument); + + // ConstBufferPtr overload, null/empty pointer (invalid) + BOOST_CHECK_EXCEPTION(i.setApplicationParameters(ConstBufferPtr{}), std::invalid_argument, [] (const auto& e) { + return e.what() == "ApplicationParameters buffer cannot be null"sv; + }); } BOOST_AUTO_TEST_CASE(SetSignature) @@ -903,7 +917,7 @@ BOOST_AUTO_TEST_CASE(SetSignature) Block sv1("2E04 01020304"_block); BOOST_CHECK_EXCEPTION(i.setSignatureValue(sv1.value_bytes()), tlv::Error, [] (const auto& e) { - return e.what() == "InterestSignatureInfo must be present to set InterestSignatureValue"s; + return e.what() == "InterestSignatureInfo must be present to set InterestSignatureValue"sv; }); BOOST_CHECK(i.getSignatureInfo() == std::nullopt); @@ -922,8 +936,10 @@ BOOST_AUTO_TEST_CASE(SetSignature) BOOST_CHECK_EQUAL(i.getSignatureValue(), sv1); BOOST_CHECK_EQUAL(i.isSigned(), true); - // Throws because attempting to set InterestSignatureValue to nullptr - BOOST_CHECK_THROW(i.setSignatureValue(nullptr), std::invalid_argument); + // Throws because attempting to set InterestSignatureValue to a null pointer + BOOST_CHECK_EXCEPTION(i.setSignatureValue(ConstBufferPtr{}), std::invalid_argument, [] (const auto& e) { + return e.what() == "InterestSignatureValue buffer cannot be null"sv; + }); BOOST_CHECK_EQUAL(i.getSignatureValue(), sv1); BOOST_CHECK_EQUAL(i.isSigned(), true); @@ -1046,9 +1062,11 @@ BOOST_AUTO_TEST_CASE(ParametersSha256DigestComponent) BOOST_AUTO_TEST_CASE(ExtractSignedRanges) { + InputBuffers bufs; + Interest i1; - BOOST_CHECK_EXCEPTION(i1.extractSignedRanges(), tlv::Error, [] (const auto& e) { - return e.what() == "Name has zero name components"s; + BOOST_CHECK_EXCEPTION(bufs = i1.extractSignedRanges(), tlv::Error, [] (const auto& e) { + return e.what() == "Name has zero name components"sv; }); i1.setName("/test/prefix"); i1.setNonce(0x01020304); @@ -1124,16 +1142,16 @@ BOOST_AUTO_TEST_CASE(ExtractSignedRanges) // Ensure parameters range captured properly BOOST_CHECK_EQUAL_COLLECTIONS(ranges3.back().begin(), ranges3.back().end(), &WIRE[58], &WIRE[79]); - // Test failure with missing ParametersSha256DigestComponent Interest i3("/a"); - BOOST_CHECK_EXCEPTION(i3.extractSignedRanges(), tlv::Error, [] (const auto& e) { - return e.what() == "Interest Name must end with a ParametersSha256DigestComponent"s; + // Failure due to missing ParametersSha256DigestComponent + BOOST_CHECK_EXCEPTION(bufs = i3.extractSignedRanges(), tlv::Error, [] (const auto& e) { + return e.what() == "Interest Name must end with a ParametersSha256DigestComponent"sv; }); - // Test failure with missing InterestSignatureInfo - i3.setApplicationParameters(span{}); - BOOST_CHECK_EXCEPTION(i3.extractSignedRanges(), tlv::Error, [] (const auto& e) { - return e.what() == "Interest missing InterestSignatureInfo"s; + i3.setApplicationParameters(""); + // Failure due to missing InterestSignatureInfo + BOOST_CHECK_EXCEPTION(bufs = i3.extractSignedRanges(), tlv::Error, [] (const auto& e) { + return e.what() == "Interest missing InterestSignatureInfo"sv; }); } diff --git a/tests/unit/link.t.cpp b/tests/unit/link.t.cpp index f1bbd079..2a17a960 100644 --- a/tests/unit/link.t.cpp +++ b/tests/unit/link.t.cpp @@ -35,7 +35,7 @@ static_assert(std::is_convertible_v, BOOST_AUTO_TEST_SUITE(TestLink) const uint8_t GOOD_LINK[] = { -0x06, 0xd0, // Data + 0x06, 0xd0, // Data 0x07, 0x14, // Name 0x08, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, @@ -84,7 +84,7 @@ BOOST_AUTO_TEST_SUITE(EncodeDecode) BOOST_AUTO_TEST_CASE(Decode) { Link link(Block{GOOD_LINK}); - BOOST_CHECK_EQUAL(link.getName(), Name("/local/ndn/prefix")); + BOOST_TEST(link.getName() == "/local/ndn/prefix"); BOOST_TEST(link.getDelegationList() == std::vector({"/local", "/ndn"}), boost::test_tools::per_element()); } @@ -104,14 +104,25 @@ BOOST_AUTO_TEST_CASE(Encode) { Link link1("/test", {"/test1", "/test2", "/test3"}); signData(link1); - Block wire = link1.wireEncode(); + BOOST_TEST(link1.getName() == "/test"); + BOOST_TEST(link1.getContentType() == tlv::ContentType_Link); - Link link2(wire); - BOOST_CHECK_EQUAL(link2.getName(), "/test"); + Link link2(link1.wireEncode()); + BOOST_TEST(link2.getName() == "/test"); BOOST_TEST(link2.getDelegationList() == std::vector({"/test1", "/test2", "/test3"}), boost::test_tools::per_element()); } +BOOST_AUTO_TEST_CASE(EncodeEmpty) +{ + Link link("/L"); + signData(link); + BOOST_TEST(link.getName() == "/L"); + BOOST_TEST(link.getContentType() == tlv::ContentType_Link); + BOOST_TEST(link.getContent() == "1500"_block); + BOOST_TEST(link.getDelegationList().empty() == true); +} + BOOST_AUTO_TEST_SUITE_END() // EncodeDecode BOOST_AUTO_TEST_SUITE(Modify) diff --git a/tests/unit/security/certificate.t.cpp b/tests/unit/security/certificate.t.cpp index facb261a..a44ddfbd 100644 --- a/tests/unit/security/certificate.t.cpp +++ b/tests/unit/security/certificate.t.cpp @@ -315,8 +315,8 @@ IQCz3DHoRtKl7uZoJOgQsZP1/CGkNjlGZE3EQ+Ylwiprrw==)BASE64"); R"TXT(Certificate Name: /ndn/test/identity/KEY/%C7G%3A%D6%12P%B5%F0/self/v=1650251820652 Public Key: - Key Type: Unknown (23 bytes) - bm90IGEgdmFsaWQgcHVibGljIGtleQA= + Key Type: Unknown (22 bytes) + bm90IGEgdmFsaWQgcHVibGljIGtleQ== Validity: Not Before: 1970-01-01T00:00:00 Not After: 2042-04-13T03:17:00 @@ -326,9 +326,8 @@ Signature Information: Self-Signed: yes )TXT"); - const uint8_t notAKey[] = "not a valid public key"; Certificate cert4(cert3); - cert4.setContent(notAKey); + cert4.setContent("not a valid public key"sv); BOOST_CHECK_EQUAL(boost::lexical_cast(cert4), expected4); const std::string expected5( diff --git a/tests/unit/security/key-chain.t.cpp b/tests/unit/security/key-chain.t.cpp index d0b717fd..c1548518 100644 --- a/tests/unit/security/key-chain.t.cpp +++ b/tests/unit/security/key-chain.t.cpp @@ -711,7 +711,7 @@ BOOST_AUTO_TEST_CASE(ErrContent) BOOST_CHECK_THROW(signerKeyChain.makeCertificate(request, signerParams), std::invalid_argument); // empty content - request.setContent(span{}); + request.setContent(""); BOOST_CHECK_THROW(signerKeyChain.makeCertificate(request, signerParams), std::invalid_argument); }