Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/keepassxreboot/keepassxc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/autotype/AutoType.cpp105
-rw-r--r--src/autotype/AutoType.h4
-rw-r--r--src/gui/entry/EditEntryWidget.cpp33
-rw-r--r--tests/TestAutoType.cpp12
4 files changed, 80 insertions, 74 deletions
diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp
index fc098afd3..a3d8b0533 100644
--- a/src/autotype/AutoType.cpp
+++ b/src/autotype/AutoType.cpp
@@ -20,8 +20,7 @@
#include <QApplication>
#include <QPluginLoader>
-#include <QtWidgets/QErrorMessage>
-#include <iostream>
+#include <QRegularExpression>
#include "config-keepassx.h"
@@ -128,7 +127,7 @@ QStringList AutoType::windowTitles()
return m_plugin->windowTitles();
}
-void AutoType::executeAutoType(const Entry* entry, QWidget* hideWindow, const QString& customSequence, WId window)
+void AutoType::executeAutoTypeActions(const Entry* entry, QWidget* hideWindow, const QString& customSequence, WId window)
{
if (m_inAutoType || !m_plugin) {
return;
@@ -457,9 +456,7 @@ QList<AutoTypeAction*> AutoType::createActionFromTemplate(const QString& tmpl, c
list.append(new AutoTypeChar('{'));
} else if (tmplName.compare("rightbrace", Qt::CaseInsensitive) == 0) {
list.append(new AutoTypeChar('}'));
- }
-
- else {
+ } else {
QRegExp fnRegexp("f(\\d+)", Qt::CaseInsensitive, QRegExp::RegExp2);
if (fnRegexp.exactMatch(tmplName)) {
int fnNo = fnRegexp.cap(1).toInt();
@@ -615,67 +612,93 @@ bool AutoType::windowMatchesUrl(const QString& windowTitle, const QString& resol
bool AutoType::checkSyntax(const QString& string)
{
- // checks things like {word 23}{F1 23}{~ 23}{% 23}{^}{F12}{(}{) 23}{[}{[}{]}{Delay=23}{+}{-}~+%@fixedstring
- QString allowRepetition = "(\\s\\d*){0,1}";
- QString normalCommands = "[A-Z:]*" + allowRepetition; // the ":" allows custom commands
+ QString allowRepetition = "(?:\\s\\d+)?";
+ // the ":" allows custom commands with syntax S:Field
+ // exclude BEEP otherwise will be checked as valid
+ QString normalCommands = "(?!BEEP\\s)[A-Z:]*" + allowRepetition;
QString specialLiterals = "[\\^\\%\\(\\)~\\{\\}\\[\\]\\+-]" + allowRepetition;
- QString functionKeys = "(F[1-9]" + allowRepetition + "|F1[0-2])" + allowRepetition;
+ QString functionKeys = "(?:F[1-9]" + allowRepetition + "|F1[0-2])" + allowRepetition;
QString numpad = "NUMPAD\\d" + allowRepetition;
QString delay = "DELAY=\\d+";
- QString beep = "BEEP\\s\\d*\\s\\d*";
- QString vkey = "VKEY(-[EN]X){0,1}" + allowRepetition;
+ QString beep = "BEEP\\s\\d+\\s\\d+";
+ QString vkey = "VKEY(?:-[EN]X)?\\s\\w+";
- // these arent in parenthesis
+ // these chars aren't in parentheses
QString shortcutKeys = "[\\^\\%~\\+@]";
+ // a normal string not in parentheses
QString fixedStrings = "[^\\^\\%~\\+@\\{\\}]*";
- QRegExp autoTypeSyntax("(" + shortcutKeys + "|" + fixedStrings + "|\\{(" + normalCommands + "|" + specialLiterals +
- "|" + functionKeys + "|" + numpad + "|" + delay + "|" + beep + "|" + vkey + ")\\})*");
- autoTypeSyntax.setCaseSensitivity(Qt::CaseInsensitive);
- autoTypeSyntax.setPatternSyntax(QRegExp::RegExp);
- return autoTypeSyntax.exactMatch(string);
+ QRegularExpression autoTypeSyntax("^(?:" + shortcutKeys + "|" + fixedStrings + "|\\{(?:" + normalCommands + "|" + specialLiterals +
+ "|" + functionKeys + "|" + numpad + "|" + delay + "|" + beep + "|" + vkey + ")\\})*$",
+ QRegularExpression::CaseInsensitiveOption);
+ QRegularExpressionMatch match = autoTypeSyntax.match(string);
+ return match.hasMatch();
}
bool AutoType::checkHighDelay(const QString& string)
{
- QRegExp highDelay("\\{DELAY\\s\\d{5,}\\}"); // 5 digit numbers(10 seconds) are too much
- highDelay.setCaseSensitivity(Qt::CaseInsensitive);
- highDelay.setPatternSyntax(QRegExp::RegExp);
- return highDelay.exactMatch(string);
+ // 5 digit numbers(10 seconds) are too much
+ QRegularExpression highDelay("\\{DELAY\\s\\d{5,}\\}", QRegularExpression::CaseInsensitiveOption);
+ QRegularExpressionMatch match = highDelay.match(string);
+ return match.hasMatch();
+}
+
+bool AutoType::checkSlowKeypress(const QString& string)
+{
+ // 3 digit numbers(100 milliseconds) are too much
+ QRegularExpression slowKeypress("\\{DELAY=\\d{3,}\\}", QRegularExpression::CaseInsensitiveOption);
+ QRegularExpressionMatch match = slowKeypress.match(string);
+ return match.hasMatch();
}
bool AutoType::checkHighRepetition(const QString& string)
{
- QRegExp highRepetition("\\{(?!DELAY\\s)\\w*\\s\\d{3,}\\}"); // 3 digit numbers are too much
- highRepetition.setCaseSensitivity(Qt::CaseInsensitive);
- highRepetition.setPatternSyntax(QRegExp::RegExp);
- return highRepetition.exactMatch(string);
+ // 3 digit numbers are too much
+ QRegularExpression highRepetition("\\{(?!DELAY\\s)\\w+\\s\\d{3,}\\}", QRegularExpression::CaseInsensitiveOption);
+ QRegularExpressionMatch match = highRepetition.match(string);
+ return match.hasMatch();
}
-void AutoType::performAutoType(const Entry* entry, QWidget* hideWindow, const QString& customSequence, WId window)
+bool AutoType::verifyAutoTypeSyntax(const QString& sequence)
{
- if (!AutoType::checkSyntax(entry->effectiveAutoTypeSequence())) {
+ if (!AutoType::checkSyntax(sequence)) {
QMessageBox messageBox;
- messageBox.critical(0, tr("AutoType"), tr("The Syntax of your AutoType statement is incorrect!"));
- return;
- } else if (AutoType::checkHighDelay(entry->effectiveAutoTypeSequence())) {
+ messageBox.critical(0, tr("Auto-Type"), tr("The Syntax of your AutoType statement is incorrect!"));
+ return false;
+ } else if (AutoType::checkHighDelay(sequence)) {
QMessageBox::StandardButton reply;
- reply = QMessageBox::question(
- 0,
- tr("AutoType"),
- tr("This AutoType command contains a very long delay. Do you really want to execute it?"));
+ reply = QMessageBox::question(0, tr("Auto-Type"),
+ tr("This AutoType command contains a very long delay. Do you really want to proceed?"));
if (reply == QMessageBox::No) {
- return;
+ return false;
}
- } else if (AutoType::checkHighRepetition(entry->effectiveAutoTypeSequence())) {
+ } else if (AutoType::checkSlowKeypress(sequence)) {
QMessageBox::StandardButton reply;
- reply = QMessageBox::question(0, tr("AutoType"), tr("This AutoType command contains arguments which are "
- "repeated very often. Do you really want to execute it?"));
+ reply = QMessageBox::question(0, tr("Auto-Type"),
+ tr("This AutoType command contains very slow key-press. Do you really want to proceed?"));
if (reply == QMessageBox::No) {
- return;
+ return false;
}
+ } else if (AutoType::checkHighRepetition(sequence)) {
+ QMessageBox::StandardButton reply;
+ reply = QMessageBox::question(0, tr("Auto-Type"),
+ tr("This AutoType command contains arguments which are "
+ "repeated very often. Do you really want to proceed?"));
+
+ if (reply == QMessageBox::No) {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+void AutoType::performAutoType(const Entry* entry, QWidget* hideWindow, const QString& customSequence, WId window)
+{
+ auto sequence = entry->effectiveAutoTypeSequence();
+ if (verifyAutoTypeSyntax(sequence)) {
+ executeAutoTypeActions(entry, hideWindow, customSequence, window);
}
- executeAutoType(entry, hideWindow, customSequence, window);
}
diff --git a/src/autotype/AutoType.h b/src/autotype/AutoType.h
index f800ab1e6..eb366ae9c 100644
--- a/src/autotype/AutoType.h
+++ b/src/autotype/AutoType.h
@@ -36,7 +36,7 @@ class AutoType : public QObject
public:
QStringList windowTitles();
- void executeAutoType(const Entry* entry,
+ void executeAutoTypeActions(const Entry* entry,
QWidget* hideWindow = nullptr,
const QString& customSequence = QString(),
WId window = 0);
@@ -45,7 +45,9 @@ public:
int callEventFilter(void* event);
static bool checkSyntax(const QString& string);
static bool checkHighRepetition(const QString& string);
+ static bool checkSlowKeypress(const QString& string);
static bool checkHighDelay(const QString& string);
+ static bool verifyAutoTypeSyntax(const QString& sequence);
void performAutoType(const Entry* entry,
QWidget* hideWindow = nullptr,
const QString& customSequence = QString(),
diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp
index fdb8aa142..2c65d3ec8 100644
--- a/src/gui/entry/EditEntryWidget.cpp
+++ b/src/gui/entry/EditEntryWidget.cpp
@@ -766,40 +766,9 @@ void EditEntryWidget::updateEntryData(Entry* entry) const
entry->setDefaultAutoTypeSequence(QString());
}
else {
- if (!AutoType::checkSyntax(m_autoTypeUi->sequenceEdit->text())) {
- //handle wrong syntax
- QMessageBox messageBox;
- messageBox.critical(0,
- "AutoType",
- tr("The Syntax of your AutoType statement is incorrect! It won't be saved!"));
-
- }
- else if (AutoType::checkHighDelay(m_autoTypeUi->sequenceEdit->text())) {
- //handle too long delay
- QMessageBox::StandardButton reply;
- reply = QMessageBox::question(0,
- "AutoType",
- tr("This AutoType command contains a very long delay. Do you really want to save it?"));
-
- if (reply == QMessageBox::Yes) {
- entry->setDefaultAutoTypeSequence(m_autoTypeUi->sequenceEdit->text());
- }
- }
- else if (AutoType::checkHighRepetition(m_autoTypeUi->sequenceEdit->text())) {
- //handle too much repetition
- QMessageBox::StandardButton reply;
- reply = QMessageBox::question(0,
- "AutoType",
- tr("This AutoType command contains arguments which are repeated very often. Do you really want to save it?"));
-
- if (reply == QMessageBox::Yes) {
- entry->setDefaultAutoTypeSequence(m_autoTypeUi->sequenceEdit->text());
- }
- }
- else {
+ if (AutoType::verifyAutoTypeSyntax(m_autoTypeUi->sequenceEdit->text())) {
entry->setDefaultAutoTypeSequence(m_autoTypeUi->sequenceEdit->text());
}
-
}
entry->autoTypeAssociations()->copyDataFrom(m_autoTypeAssoc);
diff --git a/tests/TestAutoType.cpp b/tests/TestAutoType.cpp
index d1c09c263..da245d8cb 100644
--- a/tests/TestAutoType.cpp
+++ b/tests/TestAutoType.cpp
@@ -287,11 +287,23 @@ void TestAutoType::testAutoTypeSyntaxChecks()
{
// Huge sequence
QCOMPARE(true, AutoType::checkSyntax("{word 23}{F1 23}{~ 23}{% 23}{^}{F12}{(}{) 23}{[}{[}{]}{Delay=23}{+}{-}~+%@fixedstring"));
+
+ QCOMPARE(true, AutoType::checkSyntax("{NUMPAD1 3}"));
+
+ QCOMPARE(true, AutoType::checkSyntax("{BEEP 3 3}"));
+ QCOMPARE(false, AutoType::checkSyntax("{BEEP 3}"));
+
+ QCOMPARE(true, AutoType::checkSyntax("{VKEY 0x01}"));
+ QCOMPARE(true, AutoType::checkSyntax("{VKEY VK_LBUTTON}"));
+ QCOMPARE(true, AutoType::checkSyntax("{VKEY-EX 0x01}"));
// Bad sequence
QCOMPARE(false, AutoType::checkSyntax("{{{}}{}{}}{{}}"));
// High DelAY / low delay
QCOMPARE(true, AutoType::checkHighDelay("{DelAY 50000}"));
QCOMPARE(false, AutoType::checkHighDelay("{delay 50}"));
+ // Slow typing
+ QCOMPARE(true, AutoType::checkSlowKeypress("{DelAY=50000}"));
+ QCOMPARE(false, AutoType::checkSlowKeypress("{delay=50}"));
// Many repetition / few repetition / delay not repetition
QCOMPARE(true, AutoType::checkHighRepetition("{LEFT 50000000}"));
QCOMPARE(false, AutoType::checkHighRepetition("{SPACE 10}{TAB 3}{RIGHT 50}"));