[libc-commits] [libc] 5edb845 - [libc] Fixed mbtowc functions (#150118)

via libc-commits libc-commits at lists.llvm.org
Tue Jul 22 15:47:37 PDT 2025


Author: sribee8
Date: 2025-07-22T22:47:34Z
New Revision: 5edb845fcaafd56110670fb2f6eeac22cbb0afff

URL: https://github.com/llvm/llvm-project/commit/5edb845fcaafd56110670fb2f6eeac22cbb0afff
DIFF: https://github.com/llvm/llvm-project/commit/5edb845fcaafd56110670fb2f6eeac22cbb0afff.diff

LOG: [libc] Fixed mbtowc functions (#150118)

mbrtowc was not handling null destination correctly

---------

Co-authored-by: Sriya Pratipati <sriyap at google.com>

Added: 
    

Modified: 
    libc/src/__support/wchar/mbrtowc.cpp
    libc/src/wchar/mbtowc.cpp
    libc/test/src/wchar/mbrtowc_test.cpp

Removed: 
    


################################################################################
diff  --git a/libc/src/__support/wchar/mbrtowc.cpp b/libc/src/__support/wchar/mbrtowc.cpp
index 90ba934c42b69..0f730d6e6dbec 100644
--- a/libc/src/__support/wchar/mbrtowc.cpp
+++ b/libc/src/__support/wchar/mbrtowc.cpp
@@ -37,7 +37,8 @@ ErrorOr<size_t> mbrtowc(wchar_t *__restrict pwc, const char *__restrict s,
   }
   auto wc = char_conv.pop_utf32();
   if (wc.has_value()) {
-    *pwc = wc.value();
+    if (pwc != nullptr)
+      *pwc = wc.value();
     // null terminator -> return 0
     if (wc.value() == L'\0')
       return 0;

diff  --git a/libc/src/wchar/mbtowc.cpp b/libc/src/wchar/mbtowc.cpp
index eae39ba6081f3..6d099d43da5fa 100644
--- a/libc/src/wchar/mbtowc.cpp
+++ b/libc/src/wchar/mbtowc.cpp
@@ -25,10 +25,7 @@ LLVM_LIBC_FUNCTION(int, mbtowc,
   if (s == nullptr)
     return 0;
   internal::mbstate internal_mbstate;
-  // temp ptr to use if pwc is nullptr
-  wchar_t buf[1];
-  auto ret =
-      internal::mbrtowc(pwc == nullptr ? buf : pwc, s, n, &internal_mbstate);
+  auto ret = internal::mbrtowc(pwc, s, n, &internal_mbstate);
   if (!ret.has_value() || static_cast<int>(ret.value()) == -2) {
     // Encoding failure
     libc_errno = EILSEQ;

diff  --git a/libc/test/src/wchar/mbrtowc_test.cpp b/libc/test/src/wchar/mbrtowc_test.cpp
index 5a14d8e25935c..c406300b9ca34 100644
--- a/libc/test/src/wchar/mbrtowc_test.cpp
+++ b/libc/test/src/wchar/mbrtowc_test.cpp
@@ -190,6 +190,18 @@ TEST_F(LlvmLibcMBRToWCTest, NullString) {
   ASSERT_ERRNO_SUCCESS();
 }
 
+TEST_F(LlvmLibcMBRToWCTest, NullDest) {
+  const char ch[4] = {static_cast<char>(0xF0), static_cast<char>(0x9F),
+                      static_cast<char>(0xA4),
+                      static_cast<char>(0xA1)}; // 🤡 clown emoji
+  mbstate_t *mb;
+  LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t));
+  // reading nullptr should return correct size
+  size_t n = LIBC_NAMESPACE::mbrtowc(nullptr, ch, 10, mb);
+  ASSERT_EQ(static_cast<int>(n), 4);
+  ASSERT_ERRNO_SUCCESS();
+}
+
 TEST_F(LlvmLibcMBRToWCTest, InvalidMBState) {
   const char ch[4] = {static_cast<char>(0xC2), static_cast<char>(0x8E),
                       static_cast<char>(0xC7), static_cast<char>(0x8C)};


        


More information about the libc-commits mailing list