Parcourir la source

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()`.
yhirose il y a 1 semaine
Parent
commit
15a23abd7e
2 fichiers modifiés avec 6 ajouts et 7 suppressions
  1. 2 3
      httplib.h
  2. 4 4
      test/test.cc

+ 2 - 3
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;

+ 4 - 4
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<const void *>(m.data()),
             static_cast<const void *>(MAP_FAILED));
 }