Skip to content

Commit

Permalink
CLI: Add Unicode support on Windows (keepassxreboot#8618)
Browse files Browse the repository at this point in the history
  • Loading branch information
mdonoughe authored Oct 29, 2022
1 parent 37baa6f commit ab95690
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/cli/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
7 changes: 7 additions & 0 deletions src/cli/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
8 changes: 8 additions & 0 deletions src/cli/keepassxc-cli.exe.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<application>
<windowsSettings>
<activeCodePage xmlns="http://schemas.microsoft.com/SMI/2019/WindowsSettings">UTF-8</activeCodePage>
</windowsSettings>
</application>
</assembly>
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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="$<TARGET_FILE:keepassxc-cli>")

if(WITH_GUI_TESTS)
add_subdirectory(gui)
Expand Down
26 changes: 26 additions & 0 deletions tests/TestCli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down Expand Up @@ -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<QString>("input");
Expand Down
2 changes: 2 additions & 0 deletions tests/TestCli.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ private slots:
void testShow();
void testInvalidDbFiles();
void testYubiKeyOption();
void testNonAscii();

private:
QScopedPointer<QFile> m_devNull;
Expand All @@ -90,6 +91,7 @@ private slots:
QScopedPointer<TemporaryFile> m_keyFileProtectedDbFile;
QScopedPointer<TemporaryFile> m_keyFileProtectedNoPasswordDbFile;
QScopedPointer<TemporaryFile> m_yubiKeyProtectedDbFile;
QScopedPointer<TemporaryFile> m_nonAsciiDbFile;

QScopedPointer<QBuffer> m_stdout;
QScopedPointer<QBuffer> m_stderr;
Expand Down
Binary file modified tests/data/NonAscii.kdbx
Binary file not shown.

0 comments on commit ab95690

Please sign in to comment.