Fix nullptr implicit cast on fields::set()

fixes #2085
This commit is contained in:
Richard Hodges
2020-09-11 18:56:42 +02:00
parent 91d9457ab9
commit bea31bfff6
3 changed files with 88 additions and 1 deletions

View File

@@ -2,6 +2,7 @@ Version XXX:
* Fix assert when basic_stream used as underlying of ssl::stream with zero-length write. * Fix assert when basic_stream used as underlying of ssl::stream with zero-length write.
* Add Sec-* HTTP headers. * Add Sec-* HTTP headers.
* Fix nullptr implicit cast on `fields::set()`.
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View File

@@ -425,6 +425,11 @@ public:
void void
insert(field name, string_view const& value); 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. /** Insert a field.
If one or more fields with the same name already exist, If one or more fields with the same name already exist,
@@ -438,6 +443,11 @@ public:
void void
insert(string_view name, string_view const& value); 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. /** Insert a field.
If one or more fields with the same name already exist, If one or more fields with the same name already exist,
@@ -457,6 +467,9 @@ public:
insert(field name, string_view name_string, insert(field name, string_view name_string,
string_view const& value); string_view const& value);
void
insert(field, string_view, std::nullptr_t) = delete;
/** Set a field value, removing any other instances of that field. /** Set a field value, removing any other instances of that field.
First removes any values with matching field names, then First removes any values with matching field names, then
@@ -471,6 +484,9 @@ public:
void void
set(field name, string_view const& value); 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. /** Set a field value, removing any other instances of that field.
First removes any values with matching field names, then First removes any values with matching field names, then
@@ -483,7 +499,10 @@ public:
void void
set(string_view name, string_view const& value); 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 References and iterators to the erased elements are
invalidated. Other references and iterators are not invalidated. Other references and iterators are not

View File

@@ -1004,6 +1004,72 @@ public:
BEAST_EXPECT(req.count("abc") == 3); BEAST_EXPECT(req.count("abc") == 3);
} }
template<class Arg1, class InArg>
struct set_test
{
static auto test(...) ->
std::false_type;
template<class U = InArg>
static auto test(U arg) ->
decltype(std::declval<fields>().
set(std::declval<Arg1>(),
std::declval<U>()),
std::true_type());
static constexpr bool value =
decltype(test(std::declval<InArg>()))::value;
};
template<class Arg1, class InArg>
struct insert_test
{
static auto test(...) ->
std::false_type;
template<class U = InArg>
static auto test(U arg) ->
decltype(std::declval<fields>().
insert(std::declval<Arg1>(),
std::declval<U>()),
std::true_type());
static constexpr bool value =
decltype(test(std::declval<InArg>()))::value;
};
void
testIssue2085()
{
BOOST_STATIC_ASSERT((! set_test<field, int>::value));
BOOST_STATIC_ASSERT((! set_test<field, std::nullptr_t>::value));
BOOST_STATIC_ASSERT((! set_test<field, double>::value));
BOOST_STATIC_ASSERT((! set_test<string_view, int>::value));
BOOST_STATIC_ASSERT((! set_test<string_view, std::nullptr_t>::value));
BOOST_STATIC_ASSERT((! set_test<string_view, double>::value));
BOOST_STATIC_ASSERT(( set_test<field, const char*>::value));
BOOST_STATIC_ASSERT(( set_test<field, string_view>::value));
BOOST_STATIC_ASSERT(( set_test<field, const char(&)[10]>::value));
BOOST_STATIC_ASSERT(( set_test<string_view, const char*>::value));
BOOST_STATIC_ASSERT(( set_test<string_view, string_view>::value));
BOOST_STATIC_ASSERT(( set_test<string_view, const char(&)[10]>::value));
BOOST_STATIC_ASSERT((! insert_test<field, int>::value));
BOOST_STATIC_ASSERT((! insert_test<field, std::nullptr_t>::value));
BOOST_STATIC_ASSERT((! insert_test<field, double>::value));
BOOST_STATIC_ASSERT((! insert_test<string_view, int>::value));
BOOST_STATIC_ASSERT((! insert_test<string_view, std::nullptr_t>::value));
BOOST_STATIC_ASSERT((! insert_test<string_view, double>::value));
BOOST_STATIC_ASSERT(( insert_test<field, const char*>::value));
BOOST_STATIC_ASSERT(( insert_test<field, string_view>::value));
BOOST_STATIC_ASSERT(( insert_test<field, const char(&)[10]>::value));
BOOST_STATIC_ASSERT(( insert_test<string_view, const char*>::value));
BOOST_STATIC_ASSERT(( insert_test<string_view, string_view>::value));
BOOST_STATIC_ASSERT(( insert_test<string_view, const char(&)[10]>::value));
}
void void
run() override run() override
{ {
@@ -1020,6 +1086,7 @@ public:
testChunked(); testChunked();
testIssue1828(); testIssue1828();
boost::ignore_unused(&fields_test::testIssue2085);
} }
}; };