diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a610c21..69ce12a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ Version XXX: * Fix assert when basic_stream used as underlying of ssl::stream with zero-length write. * Add Sec-* HTTP headers. +* Fix nullptr implicit cast on `fields::set()`. -------------------------------------------------------------------------------- diff --git a/include/boost/beast/http/fields.hpp b/include/boost/beast/http/fields.hpp index cf502282..2d83db5b 100644 --- a/include/boost/beast/http/fields.hpp +++ b/include/boost/beast/http/fields.hpp @@ -425,6 +425,11 @@ public: void insert(field name, string_view const& value); + /* Set a field from a null pointer (deleted). + */ + void + insert(field, std::nullptr_t) = delete; + /** Insert a field. If one or more fields with the same name already exist, @@ -438,6 +443,11 @@ public: void insert(string_view name, string_view const& value); + /* Insert a field from a null pointer (deleted). + */ + void + insert(string_view, std::nullptr_t) = delete; + /** Insert a field. If one or more fields with the same name already exist, @@ -457,6 +467,9 @@ public: insert(field name, string_view name_string, string_view const& value); + void + insert(field, string_view, std::nullptr_t) = delete; + /** Set a field value, removing any other instances of that field. First removes any values with matching field names, then @@ -471,6 +484,9 @@ public: void set(field name, string_view const& value); + void + set(field, std::nullptr_t) = delete; + /** Set a field value, removing any other instances of that field. First removes any values with matching field names, then @@ -483,7 +499,10 @@ public: void set(string_view name, string_view const& value); - /** Remove a field. + void + set(string_view, std::nullptr_t) = delete; + + /** Remove a field. References and iterators to the erased elements are invalidated. Other references and iterators are not diff --git a/test/beast/http/fields.cpp b/test/beast/http/fields.cpp index 962db4fc..63ff7cd8 100644 --- a/test/beast/http/fields.cpp +++ b/test/beast/http/fields.cpp @@ -1004,6 +1004,72 @@ public: BEAST_EXPECT(req.count("abc") == 3); } + template + struct set_test + { + static auto test(...) -> + std::false_type; + + template + static auto test(U arg) -> + decltype(std::declval(). + set(std::declval(), + std::declval()), + std::true_type()); + + static constexpr bool value = + decltype(test(std::declval()))::value; + }; + + template + struct insert_test + { + static auto test(...) -> + std::false_type; + + template + static auto test(U arg) -> + decltype(std::declval(). + insert(std::declval(), + std::declval()), + std::true_type()); + + static constexpr bool value = + decltype(test(std::declval()))::value; + }; + + void + testIssue2085() + { + BOOST_STATIC_ASSERT((! set_test::value)); + BOOST_STATIC_ASSERT((! set_test::value)); + BOOST_STATIC_ASSERT((! set_test::value)); + BOOST_STATIC_ASSERT((! set_test::value)); + BOOST_STATIC_ASSERT((! set_test::value)); + BOOST_STATIC_ASSERT((! set_test::value)); + + BOOST_STATIC_ASSERT(( set_test::value)); + BOOST_STATIC_ASSERT(( set_test::value)); + BOOST_STATIC_ASSERT(( set_test::value)); + BOOST_STATIC_ASSERT(( set_test::value)); + BOOST_STATIC_ASSERT(( set_test::value)); + BOOST_STATIC_ASSERT(( set_test::value)); + + BOOST_STATIC_ASSERT((! insert_test::value)); + BOOST_STATIC_ASSERT((! insert_test::value)); + BOOST_STATIC_ASSERT((! insert_test::value)); + BOOST_STATIC_ASSERT((! insert_test::value)); + BOOST_STATIC_ASSERT((! insert_test::value)); + BOOST_STATIC_ASSERT((! insert_test::value)); + + BOOST_STATIC_ASSERT(( insert_test::value)); + BOOST_STATIC_ASSERT(( insert_test::value)); + BOOST_STATIC_ASSERT(( insert_test::value)); + BOOST_STATIC_ASSERT(( insert_test::value)); + BOOST_STATIC_ASSERT(( insert_test::value)); + BOOST_STATIC_ASSERT(( insert_test::value)); + } + void run() override { @@ -1020,6 +1086,7 @@ public: testChunked(); testIssue1828(); + boost::ignore_unused(&fields_test::testIssue2085); } };