diff --git a/Tests/LibC/TestWchar.cpp b/Tests/LibC/TestWchar.cpp index a158f33748..dc173eccb4 100644 --- a/Tests/LibC/TestWchar.cpp +++ b/Tests/LibC/TestWchar.cpp @@ -414,3 +414,28 @@ TEST_CASE(mbsrtowcs) EXPECT_EQ(buf[2], L'\0'); EXPECT_EQ(src, nullptr); } + +TEST_CASE(wcslcpy) +{ + auto buf = static_cast(malloc(8 * sizeof(wchar_t))); + if (!buf) { + FAIL("Could not allocate space for copy target"); + return; + } + + size_t ret; + + // If buffer is long enough, a straight-forward string copy is performed. + ret = wcslcpy(buf, L"abc", 8); + EXPECT_EQ(ret, 3ul); + EXPECT_EQ(wmemcmp(L"abc", buf, 4), 0); + + // If buffer is (supposedly) too small, the string will be truncated. + ret = wcslcpy(buf, L"1234", 4); + EXPECT_EQ(ret, 4ul); + EXPECT_EQ(wmemcmp(L"123", buf, 4), 0); + + // If the buffer is null, the length of the input is returned. + ret = wcslcpy(nullptr, L"abc", 0); + EXPECT_EQ(ret, 3ul); +} diff --git a/Userland/Libraries/LibC/wchar.cpp b/Userland/Libraries/LibC/wchar.cpp index 794fef19fe..9462f87c04 100644 --- a/Userland/Libraries/LibC/wchar.cpp +++ b/Userland/Libraries/LibC/wchar.cpp @@ -69,6 +69,18 @@ wchar_t* wcsncpy(wchar_t* dest, const wchar_t* src, size_t num) return original_dest; } +size_t wcslcpy(wchar_t* dest, const wchar_t* src, size_t n) +{ + size_t i; + for (i = 0; i + 1 < n && src[i] != L'\0'; ++i) + dest[i] = src[i]; + if (n) + dest[i] = L'\0'; + for (; src[i] != L'\0'; ++i) + ; // Determine the length of src, don't copy. + return i; +} + int wcscmp(const wchar_t* s1, const wchar_t* s2) { while (*s1 == *s2++) diff --git a/Userland/Libraries/LibC/wchar.h b/Userland/Libraries/LibC/wchar.h index b47b412cc3..12ef0f530c 100644 --- a/Userland/Libraries/LibC/wchar.h +++ b/Userland/Libraries/LibC/wchar.h @@ -29,6 +29,7 @@ struct tm; size_t wcslen(const wchar_t*); wchar_t* wcscpy(wchar_t*, const wchar_t*); wchar_t* wcsncpy(wchar_t*, const wchar_t*, size_t); +__attribute__((warn_unused_result)) size_t wcslcpy(wchar_t*, const wchar_t*, size_t); int wcscmp(const wchar_t*, const wchar_t*); int wcsncmp(const wchar_t*, const wchar_t*, size_t); wchar_t* wcschr(const wchar_t*, int);