Skip to content

Commit 5edb845

Browse files
sribee8Sriya Pratipati
andauthored
[libc] Fixed mbtowc functions (llvm#150118)
mbrtowc was not handling null destination correctly --------- Co-authored-by: Sriya Pratipati <[email protected]>
1 parent 681c2ee commit 5edb845

File tree

3 files changed

+15
-5
lines changed

3 files changed

+15
-5
lines changed

libc/src/__support/wchar/mbrtowc.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ ErrorOr<size_t> mbrtowc(wchar_t *__restrict pwc, const char *__restrict s,
3737
}
3838
auto wc = char_conv.pop_utf32();
3939
if (wc.has_value()) {
40-
*pwc = wc.value();
40+
if (pwc != nullptr)
41+
*pwc = wc.value();
4142
// null terminator -> return 0
4243
if (wc.value() == L'\0')
4344
return 0;

libc/src/wchar/mbtowc.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,7 @@ LLVM_LIBC_FUNCTION(int, mbtowc,
2525
if (s == nullptr)
2626
return 0;
2727
internal::mbstate internal_mbstate;
28-
// temp ptr to use if pwc is nullptr
29-
wchar_t buf[1];
30-
auto ret =
31-
internal::mbrtowc(pwc == nullptr ? buf : pwc, s, n, &internal_mbstate);
28+
auto ret = internal::mbrtowc(pwc, s, n, &internal_mbstate);
3229
if (!ret.has_value() || static_cast<int>(ret.value()) == -2) {
3330
// Encoding failure
3431
libc_errno = EILSEQ;

libc/test/src/wchar/mbrtowc_test.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,18 @@ TEST_F(LlvmLibcMBRToWCTest, NullString) {
190190
ASSERT_ERRNO_SUCCESS();
191191
}
192192

193+
TEST_F(LlvmLibcMBRToWCTest, NullDest) {
194+
const char ch[4] = {static_cast<char>(0xF0), static_cast<char>(0x9F),
195+
static_cast<char>(0xA4),
196+
static_cast<char>(0xA1)}; // 🤡 clown emoji
197+
mbstate_t *mb;
198+
LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t));
199+
// reading nullptr should return correct size
200+
size_t n = LIBC_NAMESPACE::mbrtowc(nullptr, ch, 10, mb);
201+
ASSERT_EQ(static_cast<int>(n), 4);
202+
ASSERT_ERRNO_SUCCESS();
203+
}
204+
193205
TEST_F(LlvmLibcMBRToWCTest, InvalidMBState) {
194206
const char ch[4] = {static_cast<char>(0xC2), static_cast<char>(0x8E),
195207
static_cast<char>(0xC7), static_cast<char>(0x8C)};

0 commit comments

Comments
 (0)