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.
This commit is contained in:
parent
e64c8961c9
commit
447896aede
2 changed files with 17 additions and 29 deletions
|
@ -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<char *>(&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;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
#include <unistd.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <unicode/utypes.h>
|
||||
|
@ -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<char *>(&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<char *>(&username[0]),
|
||||
"UTF-8");
|
||||
reinterpret_cast<char *>(&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();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue