Skip to content

Commit 924f32f

Browse files
committed
added tests for src == null and mbstate == null
1 parent f60a0ae commit 924f32f

File tree

7 files changed

+101
-2
lines changed

7 files changed

+101
-2
lines changed

libc/src/__support/wchar/wcsnrtombs.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,20 @@
1515
#include "src/__support/common.h"
1616
#include "src/__support/libc_errno.h"
1717
#include "src/__support/macros/config.h"
18+
#include "src/__support/macros/null_check.h"
1819
#include "src/__support/wchar/mbstate.h"
1920
#include "src/__support/wchar/string_converter.h"
2021

2122
namespace LIBC_NAMESPACE_DECL {
2223
namespace internal {
2324

24-
ErrorOr<size_t> wcsnrtombs(char *__restrict s, const wchar_t **__restrict pwcs,
25-
size_t nwc, size_t len, mbstate *ps) {
25+
LIBC_INLINE static ErrorOr<size_t> wcsnrtombs(char *__restrict s,
26+
const wchar_t **__restrict pwcs,
27+
size_t nwc, size_t len,
28+
mbstate *ps) {
29+
LIBC_CRASH_ON_NULLPTR(pwcs);
30+
LIBC_CRASH_ON_NULLPTR(ps);
31+
2632
CharacterConverter cr(ps);
2733
if (!cr.isValidState())
2834
return Error(EINVAL);

libc/src/wchar/wcsnrtombs.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ namespace LIBC_NAMESPACE_DECL {
2323
LLVM_LIBC_FUNCTION(size_t, wcsnrtombs,
2424
(char *__restrict s, const wchar_t **__restrict pwcs,
2525
size_t nwc, size_t len, mbstate_t *ps)) {
26+
LIBC_CRASH_ON_NULLPTR(pwcs);
2627
static internal::mbstate internal_mbstate;
2728
auto result = internal::wcsnrtombs(
2829
s, pwcs, nwc, len,

libc/src/wchar/wcsrtombs.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ namespace LIBC_NAMESPACE_DECL {
2323
LLVM_LIBC_FUNCTION(size_t, wcsrtombs,
2424
(char *__restrict s, const wchar_t **__restrict pwcs,
2525
size_t n, mbstate_t *ps)) {
26+
LIBC_CRASH_ON_NULLPTR(pwcs);
2627
static internal::mbstate internal_mbstate;
2728
auto result = internal::wcsnrtombs(
2829
s, pwcs, SIZE_MAX, n,

libc/src/wchar/wcstombs.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ namespace LIBC_NAMESPACE_DECL {
2222
LLVM_LIBC_FUNCTION(size_t, wcstombs,
2323
(char *__restrict s, const wchar_t *__restrict wcs,
2424
size_t n)) {
25+
LIBC_CRASH_ON_NULLPTR(wcs);
2526
static internal::mbstate internal_mbstate;
2627
const wchar_t *wcs_ptr_copy = wcs;
2728
auto result =

libc/test/src/__support/wchar/wcsnrtombs_test.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,3 +188,13 @@ TEST(LlvmLibcWcsnrtombs, InvalidCharacter) {
188188
ASSERT_FALSE(res.has_value());
189189
ASSERT_EQ(res.error(), EILSEQ);
190190
}
191+
192+
TEST(LlvmLibcWcsnrtombs, NullSrc) {
193+
EXPECT_DEATH(
194+
[] {
195+
LIBC_NAMESPACE::internal::mbstate state;
196+
char mbs[10];
197+
LIBC_NAMESPACE::internal::wcsnrtombs(mbs, nullptr, 1, 1, &state);
198+
},
199+
WITH_SIGNAL(-1));
200+
}

libc/test/src/wchar/wcsnrtombs_test.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,43 @@ TEST_F(LlvmLibcWcsnrtombs, ErrnoTest) {
154154
static_cast<size_t>(-1));
155155
ASSERT_ERRNO_EQ(EILSEQ);
156156
}
157+
158+
TEST_F(LlvmLibcWcsnrtombs, NullState) {
159+
// this test is the same as DestLimit except it uses a nullptr mbstate*
160+
161+
/// clown emoji, sigma symbol, y with diaeresis, letter A
162+
const wchar_t src[] = {static_cast<wchar_t>(0x1f921),
163+
static_cast<wchar_t>(0x2211),
164+
static_cast<wchar_t>(0xff), static_cast<wchar_t>(0x41),
165+
static_cast<wchar_t>(0x0)};
166+
const wchar_t *cur = src;
167+
168+
char mbs[11];
169+
for (int i = 0; i < 11; ++i)
170+
mbs[i] = '\x01'; // dummy initial values
171+
172+
ASSERT_EQ(LIBC_NAMESPACE::wcsnrtombs(mbs, &cur, 5, 4, nullptr),
173+
static_cast<size_t>(4));
174+
ASSERT_ERRNO_SUCCESS();
175+
ASSERT_EQ(cur, src + 1);
176+
ASSERT_EQ(mbs[0], '\xF0');
177+
ASSERT_EQ(mbs[1], '\x9F');
178+
ASSERT_EQ(mbs[2], '\xA4');
179+
ASSERT_EQ(mbs[3], '\xA1');
180+
ASSERT_EQ(mbs[4], '\x01'); // didn't write more than 4 bytes
181+
182+
for (int i = 0; i < 11; ++i)
183+
mbs[i] = '\x01'; // dummy initial values
184+
185+
// not enough bytes to convert the second character, so only converts one
186+
cur = src;
187+
ASSERT_EQ(LIBC_NAMESPACE::wcsnrtombs(mbs, &cur, 5, 6, nullptr),
188+
static_cast<size_t>(4));
189+
ASSERT_ERRNO_SUCCESS();
190+
ASSERT_EQ(cur, src + 1);
191+
ASSERT_EQ(mbs[0], '\xF0');
192+
ASSERT_EQ(mbs[1], '\x9F');
193+
ASSERT_EQ(mbs[2], '\xA4');
194+
ASSERT_EQ(mbs[3], '\xA1');
195+
ASSERT_EQ(mbs[4], '\x01');
196+
}

libc/test/src/wchar/wcsrtombs_test.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,43 @@ TEST_F(LlvmLibcWcsrtombs, ErrnoTest) {
111111
static_cast<size_t>(-1));
112112
ASSERT_ERRNO_EQ(EILSEQ);
113113
}
114+
115+
TEST_F(LlvmLibcWcsrtombs, NullState) {
116+
// this test is the same as DestLimit except it uses a nullptr mbstate*
117+
118+
/// clown emoji, sigma symbol, y with diaeresis, letter A
119+
const wchar_t src[] = {static_cast<wchar_t>(0x1f921),
120+
static_cast<wchar_t>(0x2211),
121+
static_cast<wchar_t>(0xff), static_cast<wchar_t>(0x41),
122+
static_cast<wchar_t>(0x0)};
123+
const wchar_t *cur = src;
124+
125+
char mbs[11];
126+
for (int i = 0; i < 11; ++i)
127+
mbs[i] = '\x01'; // dummy initial values
128+
129+
ASSERT_EQ(LIBC_NAMESPACE::wcsrtombs(mbs, &cur, 4, nullptr),
130+
static_cast<size_t>(4));
131+
ASSERT_ERRNO_SUCCESS();
132+
ASSERT_EQ(cur, src + 1);
133+
ASSERT_EQ(mbs[0], '\xF0');
134+
ASSERT_EQ(mbs[1], '\x9F');
135+
ASSERT_EQ(mbs[2], '\xA4');
136+
ASSERT_EQ(mbs[3], '\xA1');
137+
ASSERT_EQ(mbs[4], '\x01'); // didn't write more than 4 bytes
138+
139+
for (int i = 0; i < 11; ++i)
140+
mbs[i] = '\x01'; // dummy initial values
141+
142+
// not enough bytes to convert the second character, so only converts one
143+
cur = src;
144+
ASSERT_EQ(LIBC_NAMESPACE::wcsrtombs(mbs, &cur, 6, nullptr),
145+
static_cast<size_t>(4));
146+
ASSERT_ERRNO_SUCCESS();
147+
ASSERT_EQ(cur, src + 1);
148+
ASSERT_EQ(mbs[0], '\xF0');
149+
ASSERT_EQ(mbs[1], '\x9F');
150+
ASSERT_EQ(mbs[2], '\xA4');
151+
ASSERT_EQ(mbs[3], '\xA1');
152+
ASSERT_EQ(mbs[4], '\x01');
153+
}

0 commit comments

Comments
 (0)