Skip to content

Commit

Permalink
Merge branch 'develop' into 852-warn-on-deleting-with-references
Browse files Browse the repository at this point in the history
  • Loading branch information
wgml committed Mar 24, 2018
2 parents 51c7829 + e92d5e8 commit 8b33c20
Show file tree
Hide file tree
Showing 40 changed files with 266 additions and 147 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,8 @@ if(MINGW)
set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> <FLAGS> -O coff <DEFINES> -i <SOURCE> -o <OBJECT>")
if(NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo"))
# Enable DEP and ASLR
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--nxcompat -Wl,--dynamicbase")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--nxcompat -Wl,--dynamicbase")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--nxcompat -Wl,--dynamicbase -Wl,--high-entropy-va")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--nxcompat -Wl,--dynamicbase -Wl,--high-entropy-va")
endif()
endif()

Expand Down
9 changes: 8 additions & 1 deletion INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,22 @@ To update the project from within the project's folder, you can run the followin
git pull
```

For a stable build, it is recommended to checkout the master branch.

```bash
git checkout master
```

Navigate to the directory where you have downloaded KeePassXC and type these commands:

```
cd directory-where-sources-live
mkdir build
cd build
cmake -DWITH_TESTS=OFF ...and other options - see below...
cmake -DWITH_XC_ALL=ON ..
make
```

These steps place the compiled KeePassXC binary inside the `./build/src/` directory.
(Note the cmake notes/options below.)

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ so please check out your distribution's package list to see if KeePassXC is avai
[Mozilla Firefox](https://addons.mozilla.org/en-US/firefox/addon/keepasshttp-connector/) and
[Google Chrome or Chromium](https://chrome.google.com/webstore/detail/keepasshttp-connector/dafgdjggglmmknipkhngniifhplpcldb), and
[passafari](https://github.com/mmichaa/passafari.safariextension/) in Safari. [[See note about KeePassHTTP]](#Note_about_KeePassHTTP)
- Browser integration with KeePassXC-Browser using [native messaging](https://developer.chrome.com/extensions/nativeMessaging) for [Mozilla Firefox](https://addons.mozilla.org/en-US/firefox/addon/keepassxc-browser/) and [Google Chrome or Chromium](https://chrome.google.com/webstore/detail/keepassxc-browser/iopaggbpplllidnfmcghoonnokmjoicf)
- Browser integration with KeePassXC-Browser using [native messaging](https://developer.chrome.com/extensions/nativeMessaging) for [Mozilla Firefox](https://addons.mozilla.org/en-US/firefox/addon/keepassxc-browser/) and [Google Chrome or Chromium](https://chrome.google.com/webstore/detail/keepassxc-browser/oboonakemofpalcgghocfoadofidjkkk)
- Many bug fixes

For a full list of features and changes, read the [CHANGELOG](CHANGELOG) document.
Expand Down
59 changes: 33 additions & 26 deletions src/autotype/AutoType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,6 @@ QStringList AutoType::windowTitles()
return m_plugin->windowTitles();
}

void AutoType::resetInAutoType()
{
m_inAutoType.unlock();

emit autotypeRejected();
}

void AutoType::raiseWindow()
{
#if defined(Q_OS_MAC)
Expand Down Expand Up @@ -199,9 +192,14 @@ int AutoType::callEventFilter(void* event)
*/
void AutoType::executeAutoTypeActions(const Entry* entry, QWidget* hideWindow, const QString& sequence, WId window)
{
if (!m_inAutoType.tryLock()) {
return;
}

// no edit to the sequence beyond this point
if (!verifyAutoTypeSyntax(sequence)) {
emit autotypeRejected();
m_inAutoType.unlock();
return;
}

Expand All @@ -210,6 +208,7 @@ void AutoType::executeAutoTypeActions(const Entry* entry, QWidget* hideWindow, c

if (!parseActions(sequence, entry, actions)) {
emit autotypeRejected();
m_inAutoType.unlock();
return;
}

Expand All @@ -233,6 +232,7 @@ void AutoType::executeAutoTypeActions(const Entry* entry, QWidget* hideWindow, c
if (m_plugin->activeWindow() != window) {
qWarning("Active window changed, interrupting auto-type.");
emit autotypeRejected();
m_inAutoType.unlock();
return;
}

Expand All @@ -242,6 +242,8 @@ void AutoType::executeAutoTypeActions(const Entry* entry, QWidget* hideWindow, c

// emit signal only if autotype performed correctly
emit autotypePerformed();

m_inAutoType.unlock();
}

/**
Expand All @@ -259,13 +261,7 @@ void AutoType::performAutoType(const Entry* entry, QWidget* hideWindow)
return;
}

if (!m_inAutoType.tryLock()) {
return;
}

executeAutoTypeActions(entry, hideWindow, sequences.first());

m_inAutoType.unlock();
}

/**
Expand All @@ -278,13 +274,14 @@ void AutoType::performGlobalAutoType(const QList<Database*>& dbList)
return;
}

QString windowTitle = m_plugin->activeWindowTitle();

if (windowTitle.isEmpty()) {
if (!m_inGlobalAutoTypeDialog.tryLock()) {
return;
}

if (!m_inAutoType.tryLock()) {
QString windowTitle = m_plugin->activeWindowTitle();

if (windowTitle.isEmpty()) {
m_inGlobalAutoTypeDialog.unlock();
return;
}

Expand All @@ -303,8 +300,6 @@ void AutoType::performGlobalAutoType(const QList<Database*>& dbList)
}

if (matchList.isEmpty()) {
m_inAutoType.unlock();

if (qobject_cast<QApplication*>(QCoreApplication::instance())) {
auto* msgBox = new QMessageBox();
msgBox->setAttribute(Qt::WA_DeleteOnClose);
Expand All @@ -318,16 +313,20 @@ void AutoType::performGlobalAutoType(const QList<Database*>& dbList)
msgBox->activateWindow();
}

m_inGlobalAutoTypeDialog.unlock();
emit autotypeRejected();
} else if ((matchList.size() == 1) && !config()->get("security/autotypeask").toBool()) {
executeAutoTypeActions(matchList.first().entry, nullptr, matchList.first().sequence);
m_inAutoType.unlock();
m_inGlobalAutoTypeDialog.unlock();
} else {
m_windowFromGlobal = m_plugin->activeWindow();
auto* selectDialog = new AutoTypeSelectDialog();

// connect slots, both of which must unlock the m_inGlobalAutoTypeDialog mutex
connect(selectDialog, SIGNAL(matchActivated(AutoTypeMatch)),
SLOT(performAutoTypeFromGlobal(AutoTypeMatch)));
connect(selectDialog, SIGNAL(rejected()), SLOT(resetInAutoType()));
connect(selectDialog, SIGNAL(rejected()), SLOT(autoTypeRejectedFromGlobal()));

selectDialog->setMatchList(matchList);
#if defined(Q_OS_MAC)
m_plugin->raiseOwnWindow();
Expand All @@ -341,14 +340,22 @@ void AutoType::performGlobalAutoType(const QList<Database*>& dbList)

void AutoType::performAutoTypeFromGlobal(AutoTypeMatch match)
{
// We don't care about the result here, the mutex should already be locked. Now it's locked for sure
m_inAutoType.tryLock();

m_plugin->raiseWindow(m_windowFromGlobal);

executeAutoTypeActions(match.entry, nullptr, match.sequence, m_windowFromGlobal);

m_inAutoType.unlock();
// make sure the mutex is definitely locked before we unlock it
Q_UNUSED(m_inGlobalAutoTypeDialog.tryLock());
m_inGlobalAutoTypeDialog.unlock();
}

void AutoType::autoTypeRejectedFromGlobal()
{
// this slot can be called twice when the selection dialog is deleted,
// so make sure the mutex is locked before we try unlocking it
Q_UNUSED(m_inGlobalAutoTypeDialog.tryLock());
m_inGlobalAutoTypeDialog.unlock();

emit autotypeRejected();
}

/**
Expand Down
3 changes: 2 additions & 1 deletion src/autotype/AutoType.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public slots:

private slots:
void performAutoTypeFromGlobal(AutoTypeMatch match);
void resetInAutoType();
void autoTypeRejectedFromGlobal();
void unloadPlugin();

private:
Expand All @@ -88,6 +88,7 @@ private slots:
bool windowMatches(const QString& windowTitle, const QString& windowPattern);

QMutex m_inAutoType;
QMutex m_inGlobalAutoTypeDialog;
int m_autoTypeDelay;
Qt::Key m_currentGlobalKey;
Qt::KeyboardModifiers m_currentGlobalModifiers;
Expand Down
4 changes: 2 additions & 2 deletions src/browser/BrowserOptionDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,9 @@ void BrowserOptionDialog::saveSettings()
void BrowserOptionDialog::showProxyLocationFileDialog()
{
#ifdef Q_OS_WIN
QString fileTypeFilter(tr("Executable Files (*.exe);;All Files (*.*)"));
QString fileTypeFilter(QString("%1 (*.exe);;%2 (*.*)").arg(tr("Executable Files"), tr("All Files")));
#else
QString fileTypeFilter(tr("Executable Files (*)"));
QString fileTypeFilter(QString("%1 (*)").arg(tr("Executable Files")));
#endif
auto proxyLocation = QFileDialog::getOpenFileName(this, tr("Select custom proxy location"),
QFileInfo(QCoreApplication::applicationDirPath()).filePath(),
Expand Down
2 changes: 1 addition & 1 deletion src/browser/BrowserService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ void BrowserService::removeSharedEncryptionKeys()

if (keysToRemove.isEmpty()) {
QMessageBox::information(0, tr("KeePassXC: No keys found"),
tr("No shared encryption keys found in KeePassXC Settings."),
tr("No shared encryption keys found in KeePassXC settings."),
QMessageBox::Ok);
return;
}
Expand Down
3 changes: 2 additions & 1 deletion src/browser/NativeMessagingBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ void NativeMessagingBase::sendReply(const QJsonObject& json)
void NativeMessagingBase::sendReply(const QString& reply)
{
if (!reply.isEmpty()) {
uint len = reply.length();
QByteArray bytes = reply.toUtf8();
uint len = bytes.size();
std::cout << char(((len>>0) & 0xFF)) << char(((len>>8) & 0xFF)) << char(((len>>16) & 0xFF)) << char(((len>>24) & 0xFF));
std::cout << reply.toStdString() << std::flush;
}
Expand Down
8 changes: 3 additions & 5 deletions src/core/CsvParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ bool CsvParser::readFile(QFile *device) {
m_array.replace("\r\n", "\n");
m_array.replace("\r", "\n");
if (0 == m_array.size())
appendStatusMsg(QObject::tr("file empty !\n"));
appendStatusMsg(QObject::tr("file empty").append("\n"));
m_isFileLoaded = true;
}
return m_isFileLoaded;
Expand Down Expand Up @@ -377,10 +377,8 @@ int CsvParser::getCsvRows() const {


void CsvParser::appendStatusMsg(QString s, bool isCritical) {
m_statusMsg += s
.append(": (row,col) " + QString::number(m_currRow))
.append(",")
.append(QString::number(m_currCol))
m_statusMsg += QObject::tr("%1: (row, col) %2,%3")
.arg(s, m_currRow, m_currCol)
.append("\n");
m_isGood = !isCritical;
}
2 changes: 1 addition & 1 deletion src/core/Database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ Database* Database::unlockFromStdin(QString databaseFilename, QString keyFilenam
FileKey fileKey;
QString errorMessage;
if (!fileKey.load(keyFilename, &errorMessage)) {
errorTextStream << QObject::tr("Failed to load key file %1 : %2").arg(keyFilename, errorMessage);
errorTextStream << QObject::tr("Failed to load key file %1: %2").arg(keyFilename, errorMessage);
errorTextStream << endl;
return nullptr;
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/Entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,7 @@ Entry* Entry::clone(CloneFlags flags) const
}

if (flags & CloneRenameTitle)
entry->setTitle(entry->title() + tr(" - Clone", "Suffix added to cloned entries"));
entry->setTitle(tr("%1 - Clone").arg(entry->title()));

return entry;
}
Expand Down
10 changes: 9 additions & 1 deletion src/core/FilePath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,15 @@ QString FilePath::wordlistPath(const QString& name)
}

QIcon FilePath::applicationIcon()
{
#ifdef KEEPASSXC_DIST_SNAP
return icon("apps", "keepassxc", false);
#else
return icon("apps", "keepassxc");
#endif
}

QIcon FilePath::trayIcon()
{
bool darkIcon = useDarkIcon();

Expand All @@ -107,7 +116,6 @@ QIcon FilePath::applicationIcon()
#endif
}


QIcon FilePath::trayIconLocked()
{
#ifdef KEEPASSXC_DIST_SNAP
Expand Down
1 change: 1 addition & 0 deletions src/core/FilePath.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class FilePath
QString pluginPath(const QString& name);
QString wordlistPath(const QString& name);
QIcon applicationIcon();
QIcon trayIcon();
QIcon trayIconLocked();
QIcon trayIconUnlocked();
QIcon icon(const QString& category, const QString& name, bool fromTheme = true);
Expand Down
4 changes: 2 additions & 2 deletions src/core/Group.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ QString Group::print(bool recursive, int depth)
QString indentation = QString(" ").repeated(depth);

if (entries().isEmpty() && children().isEmpty()) {
response += indentation + "[empty]\n";
response += indentation + tr("[empty]", "group has no children") + "\n";
return response;
}

Expand Down Expand Up @@ -911,7 +911,7 @@ void Group::markOlderEntry(Entry* entry)
{
entry->attributes()->set(
"merged",
QString("older entry merged from database \"%1\"").arg(entry->group()->database()->metadata()->name()));
tr("older entry merged from database \"%1\"").arg(entry->group()->database()->metadata()->name()));
}

bool Group::resolveSearchingEnabled() const
Expand Down
10 changes: 5 additions & 5 deletions src/format/Kdbx3Reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Database* Kdbx3Reader::readDatabaseImpl(QIODevice* device, const QByteArray& hea
if (m_masterSeed.isEmpty() || m_encryptionIV.isEmpty()
|| m_streamStartBytes.isEmpty() || m_protectedStreamKey.isEmpty()
|| m_db->cipher().isNull()) {
raiseError("missing database headers");
raiseError(tr("missing database headers"));
return nullptr;
}

Expand Down Expand Up @@ -134,7 +134,7 @@ Database* Kdbx3Reader::readDatabaseImpl(QIODevice* device, const QByteArray& hea
if (!xmlReader.headerHash().isEmpty()) {
QByteArray headerHash = CryptoHash::hash(headerData, CryptoHash::Sha256);
if (headerHash != xmlReader.headerHash()) {
raiseError("Header doesn't match hash");
raiseError(tr("Header doesn't match hash"));
return nullptr;
}
}
Expand All @@ -146,23 +146,23 @@ bool Kdbx3Reader::readHeaderField(StoreDataStream& headerStream)
{
QByteArray fieldIDArray = headerStream.read(1);
if (fieldIDArray.size() != 1) {
raiseError("Invalid header id size");
raiseError(tr("Invalid header id size"));
return false;
}
char fieldID = fieldIDArray.at(0);

bool ok;
auto fieldLen = Endian::readSizedInt<quint16>(&headerStream, KeePass2::BYTEORDER, &ok);
if (!ok) {
raiseError("Invalid header field length");
raiseError(tr("Invalid header field length"));
return false;
}

QByteArray fieldData;
if (fieldLen != 0) {
fieldData = headerStream.read(fieldLen);
if (fieldData.size() != fieldLen) {
raiseError("Invalid header data length");
raiseError(tr("Invalid header data length"));
return false;
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/format/KdbxXmlReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,9 @@ QString KdbxXmlReader::errorString() const
{
if (m_error) {
return m_errorStr;
}if (m_xml.hasError()) {
return QString("XML error:\n%1\nLine %2, column %3")
}
if (m_xml.hasError()) {
return tr("XML error:\n%1\nLine %2, column %3")
.arg(m_xml.errorString())
.arg(m_xml.lineNumber())
.arg(m_xml.columnNumber());
Expand Down
2 changes: 1 addition & 1 deletion src/format/KeePass1Reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ SymmetricCipherStream* KeePass1Reader::testKeys(const QString& password, const Q
cipherStream->reset();
cipherStream->close();
if (!m_device->seek(contentPos)) {
QString msg = "unable to seek to content position";
QString msg = tr("unable to seek to content position");
if (!m_device->errorString().isEmpty()) {
msg.append("\n").append(m_device->errorString());
}
Expand Down
Loading

0 comments on commit 8b33c20

Please sign in to comment.