From ab956900435387f49cb39d3859d128d07699cf5d Mon Sep 17 00:00:00 2001 From: Matthew Donoughe Date: Sat, 29 Oct 2022 08:07:31 -0400 Subject: CLI: Add Unicode support on Windows (#8618) --- src/cli/CMakeLists.txt | 3 +++ src/cli/Utils.cpp | 7 +++++++ src/cli/keepassxc-cli.exe.manifest | 8 ++++++++ tests/CMakeLists.txt | 1 + tests/TestCli.cpp | 26 ++++++++++++++++++++++++++ tests/TestCli.h | 2 ++ tests/data/NonAscii.kdbx | Bin 2862 -> 3886 bytes 7 files changed, 47 insertions(+) create mode 100644 src/cli/keepassxc-cli.exe.manifest diff --git a/src/cli/CMakeLists.txt b/src/cli/CMakeLists.txt index 8f0b2854a..a3852c800 100644 --- a/src/cli/CMakeLists.txt +++ b/src/cli/CMakeLists.txt @@ -65,6 +65,9 @@ install(TARGETS keepassxc-cli RUNTIME DESTINATION ${CLI_INSTALL_DIR} COMPONENT Runtime) if(WIN32) + target_sources(keepassxc-cli + PRIVATE keepassxc-cli.exe.manifest) + # install(CODE "include(BundleUtilities) # fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/keepassxc-cli.exe\" \"\" \"\")" # COMPONENT Runtime) diff --git a/src/cli/Utils.cpp b/src/cli/Utils.cpp index 6c0b73e93..d8134de26 100644 --- a/src/cli/Utils.cpp +++ b/src/cli/Utils.cpp @@ -63,6 +63,13 @@ namespace Utils fd->open(fopen("/dev/null", "w"), QIODevice::WriteOnly); #endif DEVNULL.setDevice(fd); + +#ifdef Q_OS_WIN + // On Windows, we ask via keepassxc-cli.exe.manifest to use UTF-8, + // but the console code-page isn't automatically changed to match. + SetConsoleCP(GetACP()); + SetConsoleOutputCP(GetACP()); +#endif } void setStdinEcho(bool enable = true) diff --git a/src/cli/keepassxc-cli.exe.manifest b/src/cli/keepassxc-cli.exe.manifest new file mode 100644 index 000000000..9ef750e6f --- /dev/null +++ b/src/cli/keepassxc-cli.exe.manifest @@ -0,0 +1,8 @@ + + + + + UTF-8 + + + diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 776c40d98..db82da163 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -235,6 +235,7 @@ endif() add_unit_test(NAME testcli SOURCES TestCli.cpp LIBS testsupport cli ${TEST_LIBRARIES}) +target_compile_definitions(testcli PRIVATE KEEPASSX_CLI_PATH="$") if(WITH_GUI_TESTS) add_subdirectory(gui) diff --git a/tests/TestCli.cpp b/tests/TestCli.cpp index 2ccda2e24..f179e6d25 100644 --- a/tests/TestCli.cpp +++ b/tests/TestCli.cpp @@ -102,6 +102,9 @@ void TestCli::init() m_yubiKeyProtectedDbFile.reset(new TemporaryFile()); m_yubiKeyProtectedDbFile->copyFromFile(file.arg("YubiKeyProtectedPasswords.kdbx")); + m_nonAsciiDbFile.reset(new TemporaryFile()); + m_nonAsciiDbFile->copyFromFile(file.arg("NonAscii.kdbx")); + m_stdout.reset(new QBuffer()); m_stdout->open(QIODevice::ReadWrite); Utils::STDOUT.setDevice(m_stdout.data()); @@ -2316,6 +2319,29 @@ void TestCli::testYubiKeyOption() QCOMPARE(m_stdout->readAll(), QByteArray()); } +void TestCli::testNonAscii() +{ + QProcess process; + process.setProcessChannelMode(QProcess::MergedChannels); + process.start( + KEEPASSX_CLI_PATH, + QStringList( + {"show", "-a", "password", m_nonAsciiDbFile->fileName(), QString::fromUtf8("\xe7\xa7\x98\xe5\xaf\x86")})); + process.waitForStarted(); + QCOMPARE(process.state(), QProcess::ProcessState::Running); + + // Write password. + process.write("\xce\x94\xc3\xb6\xd8\xb6\n"); + process.closeWriteChannel(); + + process.waitForFinished(); + + process.readLine(); // skip password prompt + QByteArray password = process.readLine(); + QCOMPARE(QString::fromUtf8(password).trimmed(), + QString::fromUtf8("\xf0\x9f\x9a\x97\xf0\x9f\x90\x8e\xf0\x9f\x94\x8b\xf0\x9f\x93\x8e")); +} + void TestCli::testCommandParsing_data() { QTest::addColumn("input"); diff --git a/tests/TestCli.h b/tests/TestCli.h index 3beb80724..d33dde26c 100644 --- a/tests/TestCli.h +++ b/tests/TestCli.h @@ -80,6 +80,7 @@ private slots: void testShow(); void testInvalidDbFiles(); void testYubiKeyOption(); + void testNonAscii(); private: QScopedPointer m_devNull; @@ -90,6 +91,7 @@ private: QScopedPointer m_keyFileProtectedDbFile; QScopedPointer m_keyFileProtectedNoPasswordDbFile; QScopedPointer m_yubiKeyProtectedDbFile; + QScopedPointer m_nonAsciiDbFile; QScopedPointer m_stdout; QScopedPointer m_stderr; diff --git a/tests/data/NonAscii.kdbx b/tests/data/NonAscii.kdbx index 06aa5bf2c..8ebaac249 100644 Binary files a/tests/data/NonAscii.kdbx and b/tests/data/NonAscii.kdbx differ -- cgit v1.2.3