From 05482567c2f8186367f162f8d6cc0a956f3b3c5f Mon Sep 17 00:00:00 2001 From: Samaresh Kumar Singh Date: Wed, 12 Nov 2025 14:55:43 -0600 Subject: [PATCH 1/3] Clear error_code on entry in win32_unicode_path constructor The win32_unicode_path constructor takes an error_code& parameter but did not clear it on successful path conversion. This left callers with stale error values even when the operation succeeded. This is inconsistent with the std::filesystem convention where error_code parameters are cleared on success (e.g., std::filesystem::create_directory). It also caused unexpected behavior in file_win32::open() where a default error_code value set before try/catch would persist even after successful file operations. This change adds 'ec = {};' at the beginning of the constructor to ensure the error_code is always in a known state, either cleared for success or set for failure. Fixes #3035 --- include/boost/beast/core/detail/win32_unicode_path.hpp | 1 + 1 file changed, 1 insertion(+) 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) From 14bf316bb65de34b156dd7e7cdc5563943f9461b Mon Sep 17 00:00:00 2001 From: Samaresh Kumar Singh Date: Wed, 1 Apr 2026 20:40:07 -0500 Subject: [PATCH 2/3] Fix: Clear ec on success in all file read/write operations Address review feedback and ensured all file-related operations clear error_code on success. --- include/boost/beast/core/impl/file_posix.ipp | 4 +- include/boost/beast/core/impl/file_stdio.ipp | 2 + test/beast/core/file_test.hpp | 74 ++++++++++++++++++++ 3 files changed, 79 insertions(+), 1 deletion(-) 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/test/beast/core/file_test.hpp b/test/beast/core/file_test.hpp index e5a54b9d20..ecf3ffc869 100644 --- a/test/beast/core/file_test.hpp +++ b/test/beast/core/file_test.hpp @@ -445,6 +445,80 @@ test_file() } BEAST_EXPECT(! fs::exists(path)); + { + string_view const s = "Hello, world!"; + + { + File f; + error_code ec = make_error_code(errc::no_such_file_or_directory); + f.open(path, file_mode::write, ec); + BEAST_EXPECT(! ec); + } + + { + File f; + error_code ec; + f.open(path, file_mode::write, ec); + BEAST_EXPECT(! ec); + ec = make_error_code(errc::no_such_file_or_directory); + f.write(s.data(), s.size(), ec); + BEAST_EXPECT(! ec); + } + + { + File f; + error_code ec; + f.open(path, file_mode::read, ec); + BEAST_EXPECT(! ec); + ec = make_error_code(errc::no_such_file_or_directory); + f.size(ec); + BEAST_EXPECT(! ec); + } + + { + File f; + error_code ec; + f.open(path, file_mode::read, ec); + BEAST_EXPECT(! ec); + ec = make_error_code(errc::no_such_file_or_directory); + f.pos(ec); + BEAST_EXPECT(! ec); + } + + { + File f; + error_code ec; + f.open(path, file_mode::read, ec); + BEAST_EXPECT(! ec); + ec = make_error_code(errc::no_such_file_or_directory); + f.seek(0, ec); + BEAST_EXPECT(! ec); + } + + { + File f; + error_code ec; + f.open(path, file_mode::read, ec); + BEAST_EXPECT(! ec); + std::string buf; + buf.resize(s.size()); + ec = make_error_code(errc::no_such_file_or_directory); + f.read(&buf[0], buf.size(), ec); + BEAST_EXPECT(! ec); + } + + { + File f; + error_code ec; + f.open(path, file_mode::read, ec); + BEAST_EXPECT(! ec); + ec = make_error_code(errc::no_such_file_or_directory); + f.close(ec); + BEAST_EXPECT(! ec); + } + + remove(path); + } } } // beast From ed41efe698caa5099028dfe6c4d32c20c2618358 Mon Sep 17 00:00:00 2001 From: Samaresh Kumar Singh Date: Wed, 1 Apr 2026 20:33:18 -0500 Subject: [PATCH 3/3] CI: Add libs/static_assert to Windows get-boost.sh submodule list libs/regex depends on libs/static_assert via Boost.Build, but it was missing from the Windows CI submodule checkout, causing all MSVC builds to fail with 'could not resolve project reference /boost/static_assert'. --- tools/get-boost.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/get-boost.sh b/tools/get-boost.sh index 281b01640f..45d5297e79 100755 --- a/tools/get-boost.sh +++ b/tools/get-boost.sh @@ -82,6 +82,7 @@ git submodule update --init --depth 20 --jobs 4 \ libs/ratio \ libs/rational \ libs/regex \ + libs/static_assert \ libs/thread \ libs/tuple \ libs/type_index \