chriskohlhoff / asio

Asio C++ Library
http://think-async.com/Asio
4.72k stars 1.19k forks source link

Undefined behavior when using `async_write_some` and `write_some` with large buffers #1443

Open ashtum opened 3 months ago

ashtum commented 3 months ago

It seems that the limit of the buffer size allowed to pass to async_write_some and write_some is platform-dependent and undocumented.

For example, on Windows, a narrowing conversion in this line:https://github.com/chriskohlhoff/asio/blob/ed5db1b50136bace796062c1a6eab0df9a74f8fa/asio/include/asio/detail/impl/socket_ops.ipp#L1386 causes incorrect reports of the number of written bytes when the buffer size is >= 2^31:

std::string buf(2'147'483'648, '*'); // a buffer of up to 2'147'483'647 bytes would be just fine
auto bytes_transferred = socket.write_some(asio::buffer(buf));
assert(bytes_transferred == 0); // reports 0 while all 2'147'483'648 bytes are written successfully 

The same issue occurs for async_write_some when the buffer size is >= 2^32:

std::string buf(4'294'967'296, '*'); // a buffer of up to 4'294'967'295 bytes would be just fine
auto bytes_transferred = co_await socket.async_write_some(asio::buffer(buf), asio::deferred);
assert(bytes_transferred == 0); // reports 0 while all 4'294'967'296 bytes are written successfully 

Because these types of limitations are platform-dependent, the expected behavior might be that async_write_some and write_some internally limit the buffer size instead of exhibiting surprising or undefined behavior.