-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
simplewallet: Add Unicode input_line [Ryo backport] #4390
simplewallet: Add Unicode input_line [Ryo backport] #4390
Conversation
src/common/command_line.cpp
Outdated
@@ -36,6 +36,14 @@ | |||
#include "cryptonote_config.h" | |||
#include "string_tools.h" | |||
|
|||
#ifdef WIN32 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use _WIN32 (apparently WIN32 is only defined if you've got the right include included already, so it's error prone)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What you are thinking is MSVC defines (not that the code compiles there anyway), but sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No idea about windows. I'm repeating what I was told by someone who does know, but maybe I'm assuming things. If you think that is wrong, explain why.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To put it in simple terms:
gcc defines WIN32
and _WIN32
msvc defines _WIN32
You use WIN32
(and I did out of laziness), however you suggestion is better practice.
src/common/command_line.cpp
Outdated
int size_needed = WideCharToMultiByte(CP_UTF8, 0, buffer, -1, NULL, 0, NULL, NULL); | ||
std::string buf(size_needed, '\0'); | ||
WideCharToMultiByte(CP_UTF8, 0, buffer, -1, &buf[0], size_needed, NULL, NULL); | ||
buf.pop_back(); //size_needed includes null that we needed to have space for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you move that inner code to util please, it seems generally useful. It also has nothing to do with command line. Without the trim seems best. Then you can have the input_line kept in simplewallet calling it and trimming. Also gets rid of all the diff spam due to namespaces below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean by inner code -> UCS2 conversion? Or do you want the read_line to act as a wrapper on win?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean the whole code except the trim, which is simplewallet specific, as it's not a canonical way to behave for a line reading function. So simplewallet would keep a function that calls the utils input function, then trims.
src/common/command_line.cpp
Outdated
buffer[read] = 0; | ||
|
||
SetConsoleMode(hConIn, oldMode); | ||
CloseHandle(hConIn); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any of those return error codes that need checking ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I subscribe to school that return codes should be checked if something can be done about it. Here the only thing available would be to throw.
c43d896
to
7852402
Compare
Let me know if that's what you meant. Note I made a reply on the collapsed topic here : #4390 (comment) |
Yes, that is what I meant. Note that seeds are input via input_secure_line, not input_line, so that one will also have to be changed. |
Looks like something you merged after the base of this PR. Hold on, let me rebase then. |
7852402
to
e08ab7d
Compare
Ok, looks like someone already did most of the work on that one for me, apart from failing to call the correct API ( One note the existing code. UTF8 characters can be up to 4 bytes long. This kind of thing makes people scream in agony:
|
@@ -56,8 +56,6 @@ namespace | |||
|
|||
bool read_from_tty(epee::wipeable_string& pass, bool hide_input) | |||
{ | |||
static constexpr const char BACKSPACE = 8; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no idea why someone chose to do this instead of using \b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most likely for symmetry with the Unix routine (which used BACKSPACE = 127, ASCII DEL). I'd suggest preserving this line. Although I would have named them both DELETE, not BACKSPACE.
Ok. Done. The second commit adds proper handling of multibyte characters. Note: Please check whether the code actually builds, I wrote it totally "dry" on Linux. |
Ah, my mistake. I had been assuming you'd actually tried it at least once. If not, then we'll wait some more for a Windows coder to show up and do it. |
That's fine - if you are short on manpower I can do it tomorrow evening. It is purely a matter of me having to power down and switch to Windows. |
OK, that's fine. It's not like we're in a hurry about this now. |
3b2c819
to
56cbf00
Compare
@moneromooo-monero Compiled it on win and fixed two minor build errors. I think that's everything from my end. |
if((len = WideCharToMultiByte(CP_UTF8, 0, &ucs2_ch, 1, utf8_ch, sizeof(utf8_ch), NULL, NULL)) <= 0) | ||
break; | ||
|
||
chlen.push_back(len); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's possible for the UTF8 char to push pass.size() over the max_password_size. Should check the length and break out of the loop here, before appending the new character.
I think it's bad practice to just silently return with whatever was read so far, but the existing code already does this. And I suppose the likelihood of anyone entering such a long password is low to begin with, so maybe not a serious problem.
HANDLE hConIn = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); | ||
DWORD oldMode; | ||
|
||
FlushConsoleInputBuffer(hConIn); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why can't we just use STD_INPUT_HANDLE here?
The Unix version will work with input redirection. I don't see why we should break that for Windows.
@@ -187,9 +146,10 @@ namespace | |||
std::cout << prompt; | |||
|
|||
std::string buf; | |||
#ifdef _WIN32 | |||
buf = tools::input_line_win(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably should have emulated std::getline() semantics instead, e.g.
tools::getline(buf);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This paradigm is actually faster in C++11 onwards (copy elision).
The buffer overflow should be fixed at least. If you want this in 0.13, fix it quick please. |
@moneromooo-monero |
56cbf00
to
8823d78
Compare
Let me know if that's what you meant. Whenever dealing with Unicode you should really delete all |
src/common/password.cpp
Outdated
if((len = WideCharToMultiByte(CP_UTF8, 0, &ucs2_ch, 1, utf8_ch, sizeof(utf8_ch), NULL, NULL)) <= 0) | ||
break; | ||
|
||
if(std::accumulate(chlen.begin(), chlen.end(), 0) + len >= tools::password_container::max_password_size) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if(pass.size() + len >= tools::password_container::max_password_size)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
In this context we have to assume size means bytes. |
Could be, I didn't look at the code hyc pointed out. If there's a bug, then it needs fixing. If it's just a misunderstanding, then it can be merged now. |
8823d78
to
a061353
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed
Issue description : ryo-currency/ryo-currency#102
Monero Issue : #4351