[libc-commits] [libc] 4c93275 - [libc][cpp::string] Fix off-by-one bug in resize and a memory leak (#208077)

via libc-commits libc-commits at lists.llvm.org
Tue Jul 7 14:48:51 PDT 2026


Author: Jackson Stogel
Date: 2026-07-07T14:48:15-07:00
New Revision: 4c93275445c698b4290ef48f98f256adf2a90f39

URL: https://github.com/llvm/llvm-project/commit/4c93275445c698b4290ef48f98f256adf2a90f39
DIFF: https://github.com/llvm/llvm-project/commit/4c93275445c698b4290ef48f98f256adf2a90f39.diff

LOG: [libc][cpp::string] Fix off-by-one bug in resize and a memory leak (#208077)

AFAICT, `cpp::string` is only used in tests, so these bugs were mostly
inconsequential.

Added: 
    

Modified: 
    libc/src/__support/CPP/string.h
    libc/test/src/__support/CPP/string_test.cpp

Removed: 
    


################################################################################
diff  --git a/libc/src/__support/CPP/string.h b/libc/src/__support/CPP/string.h
index a3172e9bb53b7..274c6b67cb4d8 100644
--- a/libc/src/__support/CPP/string.h
+++ b/libc/src/__support/CPP/string.h
@@ -93,6 +93,9 @@ class string {
   }
 
   LIBC_INLINE string &operator=(string &&other) {
+    if (buffer_ != get_empty_string())
+      ::free(buffer_);
+
     buffer_ = other.buffer_;
     size_ = other.size_;
     capacity_ = other.capacity_;
@@ -155,7 +158,12 @@ class string {
   }
 
   LIBC_INLINE void resize(size_t size) {
-    if (size > capacity_) {
+    // Avoid growing out of the static empty string during `resize(0)`,
+    // which may happen in string constructors.
+    if (size == size_)
+      return;
+
+    if (size >= capacity_) {
       reserve(size);
       const size_t size_extension = size - size_;
       inline_memset(data() + size_, '\0', size_extension);

diff  --git a/libc/test/src/__support/CPP/string_test.cpp b/libc/test/src/__support/CPP/string_test.cpp
index cc7c47c55e1b6..4a8c043d5d7a8 100644
--- a/libc/test/src/__support/CPP/string_test.cpp
+++ b/libc/test/src/__support/CPP/string_test.cpp
@@ -188,6 +188,15 @@ TEST(LlvmLibcStringTest, ResizeCapacityAndNullTermination) {
     ASSERT_EQ(a[i], '\0');
 }
 
+TEST(LlvmLibcStringTest, ResizeWithCapacityPlus1) {
+  string a;
+  a.resize(32);
+
+  size_t previous_capacity = a.capacity();
+  a.resize(previous_capacity);
+  ASSERT_GT(a.capacity(), previous_capacity);
+}
+
 TEST(LlvmLibcStringTest, ConcatWithCString) {
   ASSERT_STREQ((string("a") + string("b")).c_str(), "ab");
   ASSERT_STREQ((string("a") + "b").c_str(), "ab");


        


More information about the libc-commits mailing list