diff --git a/src/core/Tools.cpp b/src/core/Tools.cpp index 4ac9edfc0..b0d012c82 100644 --- a/src/core/Tools.cpp +++ b/src/core/Tools.cpp @@ -449,6 +449,11 @@ namespace Tools return userName; } + QString escapeAccelerators(QString string) + { + return string.replace("&", "&&"); + } + QVariantMap qo2qvm(const QObject* object, const QStringList& ignoredProperties) { QVariantMap result; diff --git a/src/core/Tools.h b/src/core/Tools.h index a9a645846..a8fe5b2be 100644 --- a/src/core/Tools.h +++ b/src/core/Tools.h @@ -49,6 +49,7 @@ namespace Tools QProcessEnvironment environment = QProcessEnvironment::systemEnvironment()); QString cleanFilename(QString filename); QString cleanUsername(); + QString escapeAccelerators(QString string); template QSet asSet(const QList& a) { diff --git a/src/gui/DatabaseTabWidget.cpp b/src/gui/DatabaseTabWidget.cpp index c8639eb44..2bf18071d 100644 --- a/src/gui/DatabaseTabWidget.cpp +++ b/src/gui/DatabaseTabWidget.cpp @@ -674,7 +674,7 @@ void DatabaseTabWidget::updateTabName(int index) return; } index = indexOf(dbWidget); - setTabText(index, tabName(index)); + setTabText(index, Tools::escapeAccelerators(tabName(index))); setTabToolTip(index, dbWidget->displayFilePath()); auto iconIndex = dbWidget->database()->publicIcon(); if (iconIndex >= 0 && iconIndex < databaseIcons()->count()) { diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 2142dba4a..755b38a1e 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -38,6 +38,7 @@ #include "autotype/AutoType.h" #include "core/InactivityTimer.h" #include "core/Resources.h" +#include "core/Tools.h" #include "gui/AboutDialog.h" #include "gui/ActionCollection.h" #include "gui/Icons.h" @@ -789,7 +790,7 @@ void MainWindow::updateLastDatabasesMenu() const QStringList lastDatabases = config()->get(Config::LastDatabases).toStringList(); for (const QString& database : lastDatabases) { - QAction* action = m_ui->menuRecentDatabases->addAction(database); + QAction* action = m_ui->menuRecentDatabases->addAction(Tools::escapeAccelerators(database)); action->setData(database); m_lastDatabasesActions->addAction(action); } diff --git a/tests/TestTools.cpp b/tests/TestTools.cpp index 5e8217842..2e0d094fe 100644 --- a/tests/TestTools.cpp +++ b/tests/TestTools.cpp @@ -451,3 +451,14 @@ void TestTools::testCleanUsername_data() QTest::newRow("Trailing dots and spaces") << "username... " << "username"; QTest::newRow("Combination of issues") << R"( user<>:"/\|?*name... )" << "user_________name"; } + +void TestTools::testEscapeAccelerators() +{ + QCOMPARE(Tools::escapeAccelerators(""), ""); + QCOMPARE(Tools::escapeAccelerators("NoAccelerator"), "NoAccelerator"); + QCOMPARE(Tools::escapeAccelerators("&Accelerator"), "&&Accelerator"); + QCOMPARE(Tools::escapeAccelerators("Accelerator&"), "Accelerator&&"); + QCOMPARE(Tools::escapeAccelerators("Accel&erator&"), "Accel&&erator&&"); + QCOMPARE(Tools::escapeAccelerators("Accel&&erator"), "Accel&&&&erator"); + QCOMPARE(Tools::escapeAccelerators("Some & text"), "Some && text"); +} diff --git a/tests/TestTools.h b/tests/TestTools.h index dbf74ef41..dc17f5b13 100644 --- a/tests/TestTools.h +++ b/tests/TestTools.h @@ -43,6 +43,7 @@ private slots: void testIsTextMimeType(); void testCleanUsername(); void testCleanUsername_data(); + void testEscapeAccelerators(); }; #endif // KEEPASSX_TESTTOOLS_H