secure_pwd_reader: Add proper Unicode handling [Ryo contribution]

This commit is contained in:
fireice-uk 2018-09-19 13:39:17 +01:00
parent 579383c26b
commit a061353254

View File

@ -56,8 +56,6 @@ namespace
bool read_from_tty(epee::wipeable_string& pass, bool hide_input) bool read_from_tty(epee::wipeable_string& pass, bool hide_input)
{ {
static constexpr const char BACKSPACE = 8;
HANDLE h_cin = ::GetStdHandle(STD_INPUT_HANDLE); HANDLE h_cin = ::GetStdHandle(STD_INPUT_HANDLE);
DWORD mode_old; DWORD mode_old;
@ -67,32 +65,46 @@ namespace
bool r = true; bool r = true;
pass.reserve(tools::password_container::max_password_size); pass.reserve(tools::password_container::max_password_size);
std::vector<int> chlen;
chlen.reserve(tools::password_container::max_password_size);
while (pass.size() < tools::password_container::max_password_size) while (pass.size() < tools::password_container::max_password_size)
{ {
DWORD read; DWORD read;
char ch; wchar_t ucs2_ch;
r = (TRUE == ::ReadConsoleA(h_cin, &ch, 1, &read, NULL)); r = (TRUE == ::ReadConsoleW(h_cin, &ucs2_ch, 1, &read, NULL));
r &= (1 == read); r &= (1 == read);
if (!r) if (!r)
{ {
break; break;
} }
else if (ch == '\n' || ch == '\r') else if (ucs2_ch == L'\n' || ucs2_ch == L'\r')
{ {
std::cout << std::endl; std::cout << std::endl;
break; break;
} }
else if (ch == BACKSPACE) else if (ucs2_ch == L'\b')
{ {
if (!pass.empty()) if (!pass.empty())
{ {
int len = chlen.back();
chlen.pop_back();
while(len-- > 0)
pass.pop_back(); pass.pop_back();
} }
continue;
} }
else
{ char utf8_ch[8] = {0};
pass.push_back(ch); int len;
} if((len = WideCharToMultiByte(CP_UTF8, 0, &ucs2_ch, 1, utf8_ch, sizeof(utf8_ch), NULL, NULL)) <= 0)
break;
if(pass.size() + len >= tools::password_container::max_password_size)
break;
chlen.push_back(len);
pass += utf8_ch;
} }
::SetConsoleMode(h_cin, mode_old); ::SetConsoleMode(h_cin, mode_old);