Boost logo

Boost Users :

Subject: Re: [Boost-users] boost::asio::buffer bug with string literal
From: Martijn Otto (boost_at_[hidden])
Date: 2017-11-28 14:06:55


Fair point, which is why I asked. The overloads for std::string_view
are already there in the 1.66 beta, but they are not used for string
literals. I think this is because it would be a conversion, where using
the template with an array of PodType is not - so this is the better
match.

Of course, with the std::string_view overload and using std::literals
one can simply add sv after their string literals to make it work,
since the overload is then an exact match.

Perhaps we could do something with std::char_traits, which has a
constexpr length function (since c++17). A quick test seems to indicate
it handles both null-terminated and non-null-terminated arrays
properly, though how it does so I have no idea. I have tested it across
different compilation units to prevent the compiler from inlining the
whole thing.

What about something like this?

/// Create a new non-modifiable buffer that represents the given
character array.
/**
  * @returns A const_buffer value equivalent to:
  * @code const_buffer(
  *     static_cast<const void*>(data),
  *     std::char_traits<char>::length(data)); @endcode
  */
inline BOOST_ASIO_CONST_BUFFER buffer(
    const char *data) BOOST_ASIO_NOEXCEPT
{
  return BOOST_ASIO_CONST_BUFFER(data,
std::char_traits<char>::length(data));
}

 Richard Hodges via Boost-users wrote:
> > Would this be the best approach?
>
> It gives me the shivers. Binary data could easily have a zero in the
> last byte.
>
> Wouldn't it be more explicit to simply provide an overload for
> boost::utility::string_view and std::string_view?
>
>
> On 28 November 2017 at 08:43, Martijn Otto via Boost-users <boost-use
> rs_at_[hidden]> wrote:
> > When using boost::asio::buffer with a string literal the
> > terminating
> > null character is included in the buffer size, leading to bugs like
> > accidentally sending out a null character. We could fix this by
> > adding
> > something like this to buffer.hpp:
> >
> > /// Create a new non-modifiable buffer that represents the given
> > character array.
> > /**
> >   * @returns A const_buffer value equivalent to:
> >   * @code const_buffer(
> >   *     static_cast<const void*>(data),
> >   *     (N - 1) * sizeof(char)); @endcode
> >   */
> > template <std::size_t N>
> > inline BOOST_ASIO_CONST_BUFFER buffer(
> >     const char (&data)[N]) BOOST_ASIO_NOEXCEPT
> > {
> >   return BOOST_ASIO_CONST_BUFFER(data, (N - 1) * sizeof(char));
> > }
> >
> > But this might cause trouble when using a const char array that is
> > not
> > null-terminated, since we then basically drop the last character.
> > Would
> > this be the best approach?
> > _______________________________________________
> > Boost-users mailing list
> > Boost-users_at_[hidden]
> > https://lists.boost.org/mailman/listinfo.cgi/boost-users
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> https://lists.boost.org/mailman/listinfo.cgi/boost-users


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net