Skip to content

Commit

Permalink
Fix stdin/stdout encoding on Windows.
Browse files Browse the repository at this point in the history
QTextStream uses the system default locale, but this breaks in
various situations: (1) It does not work on the native Windows shell
(cmd.exe, Powershell), since the default Windows locale is Windows-1252,
but the shell uses Windows-850. (2) It also breaks on *nix systems where
the locale is Latin1 or C, which is the case for most CI systems or
build servers.

We allow overriding the detected codec by setting the ENCODING_OVERRIDE
environment variable, but otherwise prefer Windows-850 on Windows and
UTF-8 on any other system, even if LANG is set to something else.

This resolves #2413
  • Loading branch information
phoerious committed Oct 28, 2018
1 parent c9cab25 commit 270a392
Show file tree
Hide file tree
Showing 19 changed files with 180 additions and 61 deletions.
3 changes: 1 addition & 2 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,9 @@ set(keepassx_SOURCES
core/Clock.cpp
core/Tools.cpp
core/Translator.cpp
core/Base32.h
core/Base32.cpp
cli/Utils.cpp
cli/Utils.h
cli/TextStream.cpp
crypto/Crypto.cpp
crypto/CryptoHash.cpp
crypto/Random.cpp
Expand Down
8 changes: 4 additions & 4 deletions src/cli/Add.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
#include "Add.h"

#include <QCommandLineParser>
#include <QTextStream>

#include "cli/TextStream.h"
#include "cli/Utils.h"
#include "core/Database.h"
#include "core/Entry.h"
Expand All @@ -41,9 +41,9 @@ Add::~Add()

int Add::execute(const QStringList& arguments)
{
QTextStream inputTextStream(Utils::STDIN, QIODevice::ReadOnly);
QTextStream outputTextStream(Utils::STDOUT, QIODevice::WriteOnly);
QTextStream errorTextStream(Utils::STDERR, QIODevice::WriteOnly);
TextStream inputTextStream(Utils::STDIN, QIODevice::ReadOnly);
TextStream outputTextStream(Utils::STDOUT, QIODevice::WriteOnly);
TextStream errorTextStream(Utils::STDERR, QIODevice::WriteOnly);

QCommandLineParser parser;
parser.setApplicationDescription(description);
Expand Down
8 changes: 4 additions & 4 deletions src/cli/Clip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
#include "Clip.h"

#include <QCommandLineParser>
#include <QTextStream>

#include "cli/TextStream.h"
#include "cli/Utils.h"
#include "core/Database.h"
#include "core/Entry.h"
Expand All @@ -42,7 +42,7 @@ Clip::~Clip()

int Clip::execute(const QStringList& arguments)
{
QTextStream out(Utils::STDOUT);
TextStream out(Utils::STDOUT);

QCommandLineParser parser;
parser.setApplicationDescription(description);
Expand Down Expand Up @@ -73,7 +73,7 @@ int Clip::execute(const QStringList& arguments)

int Clip::clipEntry(Database* database, QString entryPath, QString timeout)
{
QTextStream err(Utils::STDERR);
TextStream err(Utils::STDERR);

int timeoutSeconds = 0;
if (!timeout.isEmpty() && !timeout.toInt()) {
Expand All @@ -83,7 +83,7 @@ int Clip::clipEntry(Database* database, QString entryPath, QString timeout)
timeoutSeconds = timeout.toInt();
}

QTextStream outputTextStream(Utils::STDOUT, QIODevice::WriteOnly);
TextStream outputTextStream(Utils::STDOUT, QIODevice::WriteOnly);
Entry* entry = database->rootGroup()->findEntry(entryPath);
if (!entry) {
err << QObject::tr("Entry %1 not found.").arg(entryPath) << endl;
Expand Down
6 changes: 3 additions & 3 deletions src/cli/Diceware.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
#include "Diceware.h"

#include <QCommandLineParser>
#include <QTextStream>

#include "cli/TextStream.h"
#include "core/PassphraseGenerator.h"
#include "Utils.h"

Expand All @@ -38,8 +38,8 @@ Diceware::~Diceware()

int Diceware::execute(const QStringList& arguments)
{
QTextStream in(Utils::STDIN, QIODevice::ReadOnly);
QTextStream out(Utils::STDOUT, QIODevice::WriteOnly);
TextStream in(Utils::STDIN, QIODevice::ReadOnly);
TextStream out(Utils::STDOUT, QIODevice::WriteOnly);

QCommandLineParser parser;
parser.setApplicationDescription(description);
Expand Down
8 changes: 4 additions & 4 deletions src/cli/Edit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
#include "Edit.h"

#include <QCommandLineParser>
#include <QTextStream>

#include "cli/TextStream.h"
#include "cli/Utils.h"
#include "core/Database.h"
#include "core/Entry.h"
Expand All @@ -41,9 +41,9 @@ Edit::~Edit()

int Edit::execute(const QStringList& arguments)
{
QTextStream in(Utils::STDIN, QIODevice::ReadOnly);
QTextStream out(Utils::STDOUT, QIODevice::WriteOnly);
QTextStream err(Utils::STDERR, QIODevice::WriteOnly);
TextStream in(Utils::STDIN, QIODevice::ReadOnly);
TextStream out(Utils::STDOUT, QIODevice::WriteOnly);
TextStream err(Utils::STDERR, QIODevice::WriteOnly);

QCommandLineParser parser;
parser.setApplicationDescription(description);
Expand Down
8 changes: 4 additions & 4 deletions src/cli/Estimate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
#include "cli/Utils.h"

#include <QCommandLineParser>
#include <QTextStream>

#include "cli/TextStream.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Expand All @@ -45,7 +45,7 @@ Estimate::~Estimate()

static void estimate(const char* pwd, bool advanced)
{
QTextStream out(Utils::STDOUT, QIODevice::WriteOnly);
TextStream out(Utils::STDOUT, QIODevice::WriteOnly);

double e = 0.0;
int len = static_cast<int>(strlen(pwd));
Expand Down Expand Up @@ -150,8 +150,8 @@ static void estimate(const char* pwd, bool advanced)

int Estimate::execute(const QStringList& arguments)
{
QTextStream in(Utils::STDIN, QIODevice::ReadOnly);
QTextStream out(Utils::STDOUT, QIODevice::WriteOnly);
TextStream in(Utils::STDIN, QIODevice::ReadOnly);
TextStream out(Utils::STDOUT, QIODevice::WriteOnly);

QCommandLineParser parser;
parser.setApplicationDescription(description);
Expand Down
6 changes: 3 additions & 3 deletions src/cli/Extract.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@

#include <QCommandLineParser>
#include <QFile>
#include <QTextStream>

#include "cli/TextStream.h"
#include "cli/Utils.h"
#include "core/Database.h"
#include "format/KeePass2Reader.h"
Expand All @@ -43,8 +43,8 @@ Extract::~Extract()

int Extract::execute(const QStringList& arguments)
{
QTextStream out(Utils::STDOUT, QIODevice::WriteOnly);
QTextStream err(Utils::STDERR, QIODevice::WriteOnly);
TextStream out(Utils::STDOUT, QIODevice::WriteOnly);
TextStream err(Utils::STDERR, QIODevice::WriteOnly);

QCommandLineParser parser;
parser.setApplicationDescription(description);
Expand Down
10 changes: 4 additions & 6 deletions src/cli/Generate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
#include "cli/Utils.h"

#include <QCommandLineParser>
#include <QTextStream>

#include "cli/TextStream.h"
#include "core/PasswordGenerator.h"

Generate::Generate()
Expand All @@ -38,9 +38,8 @@ Generate::~Generate()

int Generate::execute(const QStringList& arguments)
{
QTextStream in(Utils::STDIN, QIODevice::ReadOnly);
QTextStream out(Utils::STDOUT, QIODevice::WriteOnly);
out.setCodec("UTF-8"); // force UTF-8 to prevent ??? characters in extended-ASCII passwords
TextStream in(Utils::STDIN, QIODevice::ReadOnly);
TextStream out(Utils::STDOUT, QIODevice::WriteOnly);

QCommandLineParser parser;
parser.setApplicationDescription(description);
Expand Down Expand Up @@ -87,8 +86,7 @@ int Generate::execute(const QStringList& arguments)
if (parser.value(len).isEmpty()) {
passwordGenerator.setLength(PasswordGenerator::DefaultLength);
} else {
int length = parser.value(len).toInt();
passwordGenerator.setLength(static_cast<size_t>(length));
passwordGenerator.setLength(parser.value(len).toInt());
}

PasswordGenerator::CharClasses classes = 0x0;
Expand Down
8 changes: 4 additions & 4 deletions src/cli/List.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
#include "cli/Utils.h"

#include <QCommandLineParser>
#include <QTextStream>

#include "cli/TextStream.h"
#include "core/Database.h"
#include "core/Entry.h"
#include "core/Group.h"
Expand All @@ -40,7 +40,7 @@ List::~List()

int List::execute(const QStringList& arguments)
{
QTextStream out(Utils::STDOUT);
TextStream out(Utils::STDOUT);

QCommandLineParser parser;
parser.setApplicationDescription(description);
Expand Down Expand Up @@ -77,8 +77,8 @@ int List::execute(const QStringList& arguments)

int List::listGroup(Database* database, bool recursive, const QString& groupPath)
{
QTextStream out(Utils::STDOUT, QIODevice::WriteOnly);
QTextStream err(Utils::STDERR, QIODevice::WriteOnly);
TextStream out(Utils::STDOUT, QIODevice::WriteOnly);
TextStream err(Utils::STDERR, QIODevice::WriteOnly);

if (groupPath.isEmpty()) {
out << database->rootGroup()->print(recursive) << flush;
Expand Down
10 changes: 4 additions & 6 deletions src/cli/Locate.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#include <utility>

/*
* Copyright (C) 2017 KeePassXC Team <[email protected]>
*
Expand All @@ -24,8 +22,8 @@

#include <QCommandLineParser>
#include <QStringList>
#include <QTextStream>

#include "cli/TextStream.h"
#include "cli/Utils.h"
#include "core/Global.h"
#include "core/Database.h"
Expand All @@ -44,7 +42,7 @@ Locate::~Locate()

int Locate::execute(const QStringList& arguments)
{
QTextStream out(Utils::STDOUT, QIODevice::WriteOnly);
TextStream out(Utils::STDOUT, QIODevice::WriteOnly);

QCommandLineParser parser;
parser.setApplicationDescription(description);
Expand Down Expand Up @@ -73,8 +71,8 @@ int Locate::execute(const QStringList& arguments)

int Locate::locateEntry(Database* database, const QString& searchTerm)
{
QTextStream out(Utils::STDOUT, QIODevice::WriteOnly);
QTextStream err(Utils::STDERR, QIODevice::WriteOnly);
TextStream out(Utils::STDOUT, QIODevice::WriteOnly);
TextStream err(Utils::STDERR, QIODevice::WriteOnly);

QStringList results = database->rootGroup()->locate(searchTerm);
if (results.isEmpty()) {
Expand Down
6 changes: 3 additions & 3 deletions src/cli/Merge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
#include "Merge.h"

#include <QCommandLineParser>
#include <QTextStream>

#include "cli/TextStream.h"
#include "core/Database.h"
#include "core/Merger.h"
#include "cli/Utils.h"
Expand All @@ -38,8 +38,8 @@ Merge::~Merge()

int Merge::execute(const QStringList& arguments)
{
QTextStream out(Utils::STDOUT, QIODevice::WriteOnly);
QTextStream err(Utils::STDERR, QIODevice::WriteOnly);
TextStream out(Utils::STDOUT, QIODevice::WriteOnly);
TextStream err(Utils::STDERR, QIODevice::WriteOnly);

QCommandLineParser parser;
parser.setApplicationDescription(description);
Expand Down
8 changes: 4 additions & 4 deletions src/cli/Remove.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
#include <QCommandLineParser>
#include <QCoreApplication>
#include <QStringList>
#include <QTextStream>

#include "cli/TextStream.h"
#include "cli/Utils.h"
#include "core/Database.h"
#include "core/Entry.h"
Expand All @@ -44,7 +44,7 @@ Remove::~Remove()

int Remove::execute(const QStringList& arguments)
{
QTextStream out(Utils::STDERR, QIODevice::WriteOnly);
TextStream out(Utils::STDERR, QIODevice::WriteOnly);

QCommandLineParser parser;
parser.setApplicationDescription(QCoreApplication::tr("main", "Remove an entry from the database."));
Expand Down Expand Up @@ -73,8 +73,8 @@ int Remove::execute(const QStringList& arguments)

int Remove::removeEntry(Database* database, const QString& databasePath, const QString& entryPath)
{
QTextStream out(Utils::STDOUT, QIODevice::WriteOnly);
QTextStream err(Utils::STDERR, QIODevice::WriteOnly);
TextStream out(Utils::STDOUT, QIODevice::WriteOnly);
TextStream err(Utils::STDERR, QIODevice::WriteOnly);

QPointer<Entry> entry = database->rootGroup()->findEntryByPath(entryPath);
if (!entry) {
Expand Down
10 changes: 5 additions & 5 deletions src/cli/Show.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
#include <stdio.h>

#include <QCommandLineParser>
#include <QTextStream>

#include "cli/TextStream.h"
#include "core/Database.h"
#include "core/Entry.h"
#include "core/Group.h"
Expand All @@ -41,7 +41,7 @@ Show::~Show()

int Show::execute(const QStringList& arguments)
{
QTextStream out(Utils::STDOUT);
TextStream out(Utils::STDOUT);

QCommandLineParser parser;
parser.setApplicationDescription(description);
Expand Down Expand Up @@ -78,9 +78,9 @@ int Show::execute(const QStringList& arguments)

int Show::showEntry(Database* database, QStringList attributes, const QString& entryPath)
{
QTextStream in(Utils::STDIN, QIODevice::ReadOnly);
QTextStream out(Utils::STDOUT, QIODevice::WriteOnly);
QTextStream err(Utils::STDERR, QIODevice::WriteOnly);
TextStream in(Utils::STDIN, QIODevice::ReadOnly);
TextStream out(Utils::STDOUT, QIODevice::WriteOnly);
TextStream err(Utils::STDERR, QIODevice::WriteOnly);

Entry* entry = database->rootGroup()->findEntry(entryPath);
if (!entry) {
Expand Down
Loading

0 comments on commit 270a392

Please sign in to comment.