From 2ec0c2996f8048d5feb84e660af674bd5528ec2b Mon Sep 17 00:00:00 2001 From: Andrew Schwartzmeyer Date: Tue, 4 Aug 2015 18:27:29 -0700 Subject: [PATCH] Use WCHAR sizes instead of CHAR sizes Such that lpnSize is the length (number of UTF-16 characters, including null) of the username. Must be multiplied by sizeof(char16_t) for bytes. --- src/impl/getusername.cpp | 10 +++++----- src/tests/test-getusername.cpp | 36 ++++++++++++---------------------- 2 files changed, 17 insertions(+), 29 deletions(-) diff --git a/src/impl/getusername.cpp b/src/impl/getusername.cpp index 0314b0abe..e2bd4e837 100644 --- a/src/impl/getusername.cpp +++ b/src/impl/getusername.cpp @@ -32,7 +32,7 @@ in TCHARs. On output, the variable receives the number of TCHARs copied to the buffer, including the terminating null character. - Note that TCHAR is CHAR here because UNICODE is defined, and so a + Note that TCHAR is WCHAR here because UNICODE is defined, and so a TCHAR is a byte. https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx#CHAR @@ -121,11 +121,11 @@ BOOL GetUserName(WCHAR_T *lpBuffer, LPDWORD lpnSize) reinterpret_cast(&username16[0]), (username16.size()-1)*sizeof(char16_t), "UTF-16LE"); - // number of characters including null + // Number of characters including null username16.resize(targetSize/sizeof(char16_t)+1); - // Size in bytes including null - const DWORD size = username16.length()*sizeof(char16_t); + // Size in WCHARs including null + const DWORD size = username16.length(); if (size > *lpnSize) { errno = ERROR_INSUFFICIENT_BUFFER; // Set lpnSize if buffer is too small to inform user @@ -135,7 +135,7 @@ BOOL GetUserName(WCHAR_T *lpBuffer, LPDWORD lpnSize) } // Copy bytes from string to buffer - memcpy(lpBuffer, &username16[0], size); + memcpy(lpBuffer, &username16[0], size*sizeof(char16_t)); *lpnSize = size; return 1; diff --git a/src/tests/test-getusername.cpp b/src/tests/test-getusername.cpp index 575aa8545..1aab90721 100644 --- a/src/tests/test-getusername.cpp +++ b/src/tests/test-getusername.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -16,7 +17,7 @@ protected: DWORD expectedSize; GetUserNameTest(): expectedUsername(std::string(getlogin())), - expectedSize((expectedUsername.length()+1)*sizeof(char16_t)) + expectedSize(expectedUsername.length()+1) {} void TestWithSize(DWORD size) { @@ -32,22 +33,21 @@ protected: // returns 1 on success EXPECT_EQ(1, result); - // sets lpnSize to number of bytes including null, - // note that this is (length+1)*sizeof(char16_t) + // sets lpnSize to number of WCHARs including null ASSERT_EQ(expectedSize, lpnSize); // setup for conversion from UTF-16LE const char *begin = reinterpret_cast(&lpBuffer[0]); - icu::UnicodeString username16(begin, lpnSize, "UTF-16LE"); + // multiply to get number of bytes + icu::UnicodeString username16(begin, lpnSize*sizeof(char16_t), "UTF-16LE"); // username16 length includes null and is number of characters - ASSERT_EQ(expectedUsername.length()+1, username16.length()); + ASSERT_EQ(expectedSize, username16.length()); // convert (minus null) to UTF-8 for comparison - std::string username(lpnSize/sizeof(char16_t)-1, 0); + std::string username(lpnSize-1, 0); ASSERT_EQ(expectedUsername.length(), username.length()); int32_t targetSize = username16.extract(0, username.length(), - reinterpret_cast(&username[0]), - "UTF-8"); + reinterpret_cast(&username[0]), "UTF-8"); EXPECT_EQ(expectedUsername, username); } @@ -109,30 +109,18 @@ TEST_F(GetUserNameTest, BufferSizeAsOne) { TEST_F(GetUserNameTest, BufferSizeAsUsername) { // the buffer is too small because this is a UTF-8 size - TestWithSize(expectedUsername.size()); + TestWithSize(expectedUsername.length()); TestInsufficientBuffer(); } TEST_F(GetUserNameTest, BufferSizeAsUsernamePlusOne) { - // the buffer is still too small even with null - TestWithSize(expectedUsername.size()+1); - TestInsufficientBuffer(); -} - -TEST_F(GetUserNameTest, BufferSizeAsUsernameInUTF16) { - // the buffer is still too small because it is missing null - TestWithSize(expectedUsername.size()*sizeof(char16_t)); - TestInsufficientBuffer(); -} - -TEST_F(GetUserNameTest, BufferSizeAsUsernamePlusOneInUTF16) { - // the buffer is exactly big enough - TestWithSize((expectedUsername.size()+1)*sizeof(char16_t)); + // includes null and so should be sufficient + TestWithSize(expectedUsername.length()+1); TestSuccess(); } TEST_F(GetUserNameTest, BufferSizeAsExpectedSize) { - // expectedSize is the same as username.size()+1 in UTF16 + // expectedSize is the same as username.size()+1 TestWithSize(expectedSize); TestSuccess(); }