From 15a23abd7e65aaa11e639fcb681464f1ded5a453 Mon Sep 17 00:00:00 2001 From: yhirose Date: Sat, 1 Aug 2026 22:21:26 -0400 Subject: [PATCH] Clarify the MAP_FAILED guard comment and assert the cleared size Explain why `addr_` is reset before `close()`: `munmap()` must not be called with the sentinel. The test also checks `size()`, since the hazard is a stale size paired with a sentinel `data()`. --- httplib.h | 5 ++--- test/test.cc | 8 ++++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/httplib.h b/httplib.h index e699b12..e4044c5 100644 --- a/httplib.h +++ b/httplib.h @@ -5577,10 +5577,9 @@ inline bool mmap::open(const char *path) { return false; } - // A failed mapping must not be left in `addr_`: `is_open()` only compares it - // against nullptr, so the MAP_FAILED sentinel would pass and `data()` would - // hand the caller (const char *)-1. if (addr_ == MAP_FAILED) { + // Clear the sentinel before `close()`, since `is_open()` only checks + // `addr_` against nullptr and `munmap()` must not be called with it. addr_ = nullptr; close(); return false; diff --git a/test/test.cc b/test/test.cc index adc4ddb..588a1b6 100644 --- a/test/test.cc +++ b/test/test.cc @@ -9347,10 +9347,9 @@ TEST(MmapTest, OpenWhileFileHeldForWriting) { #endif #ifndef _WIN32 -// A failed ::mmap must not be reported as an open mapping. is_open() only -// compares addr_ against nullptr, so the MAP_FAILED sentinel used to pass it -// and data() handed the caller (const char *)-1. A directory opens and stats -// fine but has no mapping, so ::mmap fails for it. +// A failed ::mmap() must not be reported as an open mapping, otherwise data() +// hands the caller the MAP_FAILED sentinel. A directory is the easiest way to +// reach it, since ::open() and fstat() succeed for one but ::mmap() doesn't. TEST(MmapTest, FailedMappingIsNotOpen) { const char *path = "./mmap_failed_mapping_test_dir"; ASSERT_EQ(0, ::mkdir(path, 0755)); @@ -9358,6 +9357,7 @@ TEST(MmapTest, FailedMappingIsNotOpen) { detail::mmap m(path); EXPECT_FALSE(m.is_open()); + EXPECT_EQ(0U, m.size()); EXPECT_NE(static_cast(m.data()), static_cast(MAP_FAILED)); }