From 2eb1b8d084bc48be382015e2d7ce87fb43c68ae2 Mon Sep 17 00:00:00 2001 From: Mohammad Nejati Date: Thu, 25 Jun 2026 13:23:59 +0000 Subject: [PATCH] clear error_code on successful file operations Fixes #3035 --- .../beast/core/detail/win32_unicode_path.hpp | 1 + include/boost/beast/core/impl/file_posix.ipp | 4 +- include/boost/beast/core/impl/file_stdio.ipp | 2 + include/boost/beast/core/impl/file_win32.ipp | 6 ++ test/beast/core/file_test.hpp | 81 +++++++++++++++++++ 5 files changed, 93 insertions(+), 1 deletion(-) diff --git a/include/boost/beast/core/detail/win32_unicode_path.hpp b/include/boost/beast/core/detail/win32_unicode_path.hpp index 3f77e651be..f0ff9295db 100644 --- a/include/boost/beast/core/detail/win32_unicode_path.hpp +++ b/include/boost/beast/core/detail/win32_unicode_path.hpp @@ -29,6 +29,7 @@ class win32_unicode_path public: win32_unicode_path(const char* utf8_path, error_code& ec) { + ec = {}; int ret = mb2wide(utf8_path, static_buf_.data(), static_buf_.size()); if (ret == 0) diff --git a/include/boost/beast/core/impl/file_posix.ipp b/include/boost/beast/core/impl/file_posix.ipp index e8fa900e0c..bdd5c45f1d 100644 --- a/include/boost/beast/core/impl/file_posix.ipp +++ b/include/boost/beast/core/impl/file_posix.ipp @@ -288,12 +288,13 @@ read(void* buffer, std::size_t n, error_code& ec) const if(result == 0) { // short read - return nread; + break; } n -= result; nread += result; buffer = static_cast(buffer) + result; } + ec = {}; return nread; } @@ -328,6 +329,7 @@ write(void const* buffer, std::size_t n, error_code& ec) nwritten += result; buffer = static_cast(buffer) + result; } + ec = {}; return nwritten; } diff --git a/include/boost/beast/core/impl/file_stdio.ipp b/include/boost/beast/core/impl/file_stdio.ipp index 69dbcfed58..63cf87eef7 100644 --- a/include/boost/beast/core/impl/file_stdio.ipp +++ b/include/boost/beast/core/impl/file_stdio.ipp @@ -300,6 +300,7 @@ read(void* buffer, std::size_t n, error_code& ec) const ec.assign(errno, generic_category()); return 0; } + ec = {}; return nread; } @@ -318,6 +319,7 @@ write(void const* buffer, std::size_t n, error_code& ec) ec.assign(errno, generic_category()); return 0; } + ec = {}; return nwritten; } diff --git a/include/boost/beast/core/impl/file_win32.ipp b/include/boost/beast/core/impl/file_win32.ipp index d7000c5e95..5842feb9cb 100644 --- a/include/boost/beast/core/impl/file_win32.ipp +++ b/include/boost/beast/core/impl/file_win32.ipp @@ -317,7 +317,10 @@ read(void* buffer, std::size_t n, error_code& ec) return nread; } if(bytesRead == 0) + { + ec = {}; return nread; + } n -= bytesRead; nread += bytesRead; buffer = static_cast(buffer) + bytesRead; @@ -357,7 +360,10 @@ write(void const* buffer, std::size_t n, error_code& ec) return nwritten; } if(bytesWritten == 0) + { + ec = {}; return nwritten; + } n -= bytesWritten; nwritten += bytesWritten; buffer = static_cast(buffer) + bytesWritten; diff --git a/test/beast/core/file_test.hpp b/test/beast/core/file_test.hpp index e5a54b9d20..1a9f2bcb08 100644 --- a/test/beast/core/file_test.hpp +++ b/test/beast/core/file_test.hpp @@ -444,6 +444,87 @@ test_file() remove(path); } + // https://github.com/boostorg/beast/issues/3035 + // + // A successful operation must clear `ec`. + { + string_view const s = "Hello, world!"; + + // write + { + File f; + { + error_code ec = error::timeout; + f.open(path, file_mode::write, ec); + BEAST_EXPECTS(! ec, ec.message()); + } + { + error_code ec = error::timeout; + f.write(s.data(), s.size(), ec); + BEAST_EXPECTS(! ec, ec.message()); + } + { + error_code ec = error::timeout; + f.write(s.data(), 0, ec); + BEAST_EXPECTS(! ec, ec.message()); + } + { + error_code ec = error::timeout; + auto n = f.size(ec); + BEAST_EXPECTS(! ec, ec.message()); + BEAST_EXPECT(n == s.size()); + } + { + error_code ec = error::timeout; + f.pos(ec); + BEAST_EXPECTS(! ec, ec.message()); + } + { + error_code ec = error::timeout; + f.seek(0, ec); + BEAST_EXPECTS(! ec, ec.message()); + } + { + error_code ec = error::timeout; + f.close(ec); + BEAST_EXPECTS(! ec, ec.message()); + } + } + + // read + { + File f; + { + error_code ec = error::timeout; + f.open(path, file_mode::read, ec); + BEAST_EXPECTS(! ec, ec.message()); + } + { + std::string buf; + buf.resize(s.size()); + error_code ec = error::timeout; + auto n = f.read(&buf[0], buf.size(), ec); + BEAST_EXPECTS(! ec, ec.message()); + BEAST_EXPECT(n == s.size()); + BEAST_EXPECT(buf == s); + } + { + char c; + error_code ec = error::timeout; + f.read(&c, 0, ec); + BEAST_EXPECTS(! ec, ec.message()); + } + { + char c; + error_code ec = error::timeout; + auto n = f.read(&c, 1, ec); + BEAST_EXPECTS(! ec, ec.message()); + BEAST_EXPECT(n == 0); + } + } + remove(path); + } + BEAST_EXPECT(! fs::exists(path)); }