mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2024-12-28 00:39:43 -05:00
improve regex filtering
This commit is contained in:
parent
203960b4b5
commit
e803076063
@ -20,8 +20,7 @@
|
|||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QPluginLoader>
|
#include <QPluginLoader>
|
||||||
#include <QtWidgets/QErrorMessage>
|
#include <QRegularExpression>
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include "config-keepassx.h"
|
#include "config-keepassx.h"
|
||||||
|
|
||||||
@ -128,7 +127,7 @@ QStringList AutoType::windowTitles()
|
|||||||
return m_plugin->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) {
|
if (m_inAutoType || !m_plugin) {
|
||||||
return;
|
return;
|
||||||
@ -457,9 +456,7 @@ QList<AutoTypeAction*> AutoType::createActionFromTemplate(const QString& tmpl, c
|
|||||||
list.append(new AutoTypeChar('{'));
|
list.append(new AutoTypeChar('{'));
|
||||||
} else if (tmplName.compare("rightbrace", Qt::CaseInsensitive) == 0) {
|
} else if (tmplName.compare("rightbrace", Qt::CaseInsensitive) == 0) {
|
||||||
list.append(new AutoTypeChar('}'));
|
list.append(new AutoTypeChar('}'));
|
||||||
}
|
} else {
|
||||||
|
|
||||||
else {
|
|
||||||
QRegExp fnRegexp("f(\\d+)", Qt::CaseInsensitive, QRegExp::RegExp2);
|
QRegExp fnRegexp("f(\\d+)", Qt::CaseInsensitive, QRegExp::RegExp2);
|
||||||
if (fnRegexp.exactMatch(tmplName)) {
|
if (fnRegexp.exactMatch(tmplName)) {
|
||||||
int fnNo = fnRegexp.cap(1).toInt();
|
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)
|
bool AutoType::checkSyntax(const QString& string)
|
||||||
{
|
{
|
||||||
// checks things like {word 23}{F1 23}{~ 23}{% 23}{^}{F12}{(}{) 23}{[}{[}{]}{Delay=23}{+}{-}~+%@fixedstring
|
QString allowRepetition = "(?:\\s\\d+)?";
|
||||||
QString allowRepetition = "(\\s\\d*){0,1}";
|
// the ":" allows custom commands with syntax S:Field
|
||||||
QString normalCommands = "[A-Z:]*" + allowRepetition; // the ":" allows custom commands
|
// exclude BEEP otherwise will be checked as valid
|
||||||
|
QString normalCommands = "(?!BEEP\\s)[A-Z:]*" + allowRepetition;
|
||||||
QString specialLiterals = "[\\^\\%\\(\\)~\\{\\}\\[\\]\\+-]" + 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 numpad = "NUMPAD\\d" + allowRepetition;
|
||||||
QString delay = "DELAY=\\d+";
|
QString delay = "DELAY=\\d+";
|
||||||
QString beep = "BEEP\\s\\d*\\s\\d*";
|
QString beep = "BEEP\\s\\d+\\s\\d+";
|
||||||
QString vkey = "VKEY(-[EN]X){0,1}" + allowRepetition;
|
QString vkey = "VKEY(?:-[EN]X)?\\s\\w+";
|
||||||
|
|
||||||
// these arent in parenthesis
|
// these chars aren't in parentheses
|
||||||
QString shortcutKeys = "[\\^\\%~\\+@]";
|
QString shortcutKeys = "[\\^\\%~\\+@]";
|
||||||
|
// a normal string not in parentheses
|
||||||
QString fixedStrings = "[^\\^\\%~\\+@\\{\\}]*";
|
QString fixedStrings = "[^\\^\\%~\\+@\\{\\}]*";
|
||||||
|
|
||||||
QRegExp autoTypeSyntax("(" + shortcutKeys + "|" + fixedStrings + "|\\{(" + normalCommands + "|" + specialLiterals +
|
QRegularExpression autoTypeSyntax("^(?:" + shortcutKeys + "|" + fixedStrings + "|\\{(?:" + normalCommands + "|" + specialLiterals +
|
||||||
"|" + functionKeys + "|" + numpad + "|" + delay + "|" + beep + "|" + vkey + ")\\})*");
|
"|" + functionKeys + "|" + numpad + "|" + delay + "|" + beep + "|" + vkey + ")\\})*$",
|
||||||
autoTypeSyntax.setCaseSensitivity(Qt::CaseInsensitive);
|
QRegularExpression::CaseInsensitiveOption);
|
||||||
autoTypeSyntax.setPatternSyntax(QRegExp::RegExp);
|
QRegularExpressionMatch match = autoTypeSyntax.match(string);
|
||||||
return autoTypeSyntax.exactMatch(string);
|
return match.hasMatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AutoType::checkHighDelay(const QString& string)
|
bool AutoType::checkHighDelay(const QString& string)
|
||||||
{
|
{
|
||||||
QRegExp highDelay("\\{DELAY\\s\\d{5,}\\}"); // 5 digit numbers(10 seconds) are too much
|
// 5 digit numbers(10 seconds) are too much
|
||||||
highDelay.setCaseSensitivity(Qt::CaseInsensitive);
|
QRegularExpression highDelay("\\{DELAY\\s\\d{5,}\\}", QRegularExpression::CaseInsensitiveOption);
|
||||||
highDelay.setPatternSyntax(QRegExp::RegExp);
|
QRegularExpressionMatch match = highDelay.match(string);
|
||||||
return highDelay.exactMatch(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)
|
bool AutoType::checkHighRepetition(const QString& string)
|
||||||
{
|
{
|
||||||
QRegExp highRepetition("\\{(?!DELAY\\s)\\w*\\s\\d{3,}\\}"); // 3 digit numbers are too much
|
// 3 digit numbers are too much
|
||||||
highRepetition.setCaseSensitivity(Qt::CaseInsensitive);
|
QRegularExpression highRepetition("\\{(?!DELAY\\s)\\w+\\s\\d{3,}\\}", QRegularExpression::CaseInsensitiveOption);
|
||||||
highRepetition.setPatternSyntax(QRegExp::RegExp);
|
QRegularExpressionMatch match = highRepetition.match(string);
|
||||||
return highRepetition.exactMatch(string);
|
return match.hasMatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AutoType::verifyAutoTypeSyntax(const QString& sequence)
|
||||||
|
{
|
||||||
|
if (!AutoType::checkSyntax(sequence)) {
|
||||||
|
QMessageBox messageBox;
|
||||||
|
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("Auto-Type"),
|
||||||
|
tr("This AutoType command contains a very long delay. Do you really want to proceed?"));
|
||||||
|
|
||||||
|
if (reply == QMessageBox::No) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (AutoType::checkSlowKeypress(sequence)) {
|
||||||
|
QMessageBox::StandardButton reply;
|
||||||
|
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 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)
|
void AutoType::performAutoType(const Entry* entry, QWidget* hideWindow, const QString& customSequence, WId window)
|
||||||
{
|
{
|
||||||
if (!AutoType::checkSyntax(entry->effectiveAutoTypeSequence())) {
|
auto sequence = entry->effectiveAutoTypeSequence();
|
||||||
QMessageBox messageBox;
|
if (verifyAutoTypeSyntax(sequence)) {
|
||||||
messageBox.critical(0, tr("AutoType"), tr("The Syntax of your AutoType statement is incorrect!"));
|
executeAutoTypeActions(entry, hideWindow, customSequence, window);
|
||||||
return;
|
|
||||||
} else if (AutoType::checkHighDelay(entry->effectiveAutoTypeSequence())) {
|
|
||||||
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?"));
|
|
||||||
|
|
||||||
if (reply == QMessageBox::No) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
} else if (AutoType::checkHighRepetition(entry->effectiveAutoTypeSequence())) {
|
|
||||||
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?"));
|
|
||||||
|
|
||||||
if (reply == QMessageBox::No) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
executeAutoType(entry, hideWindow, customSequence, window);
|
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ class AutoType : public QObject
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
QStringList windowTitles();
|
QStringList windowTitles();
|
||||||
void executeAutoType(const Entry* entry,
|
void executeAutoTypeActions(const Entry* entry,
|
||||||
QWidget* hideWindow = nullptr,
|
QWidget* hideWindow = nullptr,
|
||||||
const QString& customSequence = QString(),
|
const QString& customSequence = QString(),
|
||||||
WId window = 0);
|
WId window = 0);
|
||||||
@ -45,7 +45,9 @@ public:
|
|||||||
int callEventFilter(void* event);
|
int callEventFilter(void* event);
|
||||||
static bool checkSyntax(const QString& string);
|
static bool checkSyntax(const QString& string);
|
||||||
static bool checkHighRepetition(const QString& string);
|
static bool checkHighRepetition(const QString& string);
|
||||||
|
static bool checkSlowKeypress(const QString& string);
|
||||||
static bool checkHighDelay(const QString& string);
|
static bool checkHighDelay(const QString& string);
|
||||||
|
static bool verifyAutoTypeSyntax(const QString& sequence);
|
||||||
void performAutoType(const Entry* entry,
|
void performAutoType(const Entry* entry,
|
||||||
QWidget* hideWindow = nullptr,
|
QWidget* hideWindow = nullptr,
|
||||||
const QString& customSequence = QString(),
|
const QString& customSequence = QString(),
|
||||||
|
@ -766,41 +766,10 @@ void EditEntryWidget::updateEntryData(Entry* entry) const
|
|||||||
entry->setDefaultAutoTypeSequence(QString());
|
entry->setDefaultAutoTypeSequence(QString());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!AutoType::checkSyntax(m_autoTypeUi->sequenceEdit->text())) {
|
if (AutoType::verifyAutoTypeSyntax(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());
|
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 {
|
|
||||||
entry->setDefaultAutoTypeSequence(m_autoTypeUi->sequenceEdit->text());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
entry->autoTypeAssociations()->copyDataFrom(m_autoTypeAssoc);
|
entry->autoTypeAssociations()->copyDataFrom(m_autoTypeAssoc);
|
||||||
}
|
}
|
||||||
|
@ -287,11 +287,23 @@ void TestAutoType::testAutoTypeSyntaxChecks()
|
|||||||
{
|
{
|
||||||
// Huge sequence
|
// Huge sequence
|
||||||
QCOMPARE(true, AutoType::checkSyntax("{word 23}{F1 23}{~ 23}{% 23}{^}{F12}{(}{) 23}{[}{[}{]}{Delay=23}{+}{-}~+%@fixedstring"));
|
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
|
// Bad sequence
|
||||||
QCOMPARE(false, AutoType::checkSyntax("{{{}}{}{}}{{}}"));
|
QCOMPARE(false, AutoType::checkSyntax("{{{}}{}{}}{{}}"));
|
||||||
// High DelAY / low delay
|
// High DelAY / low delay
|
||||||
QCOMPARE(true, AutoType::checkHighDelay("{DelAY 50000}"));
|
QCOMPARE(true, AutoType::checkHighDelay("{DelAY 50000}"));
|
||||||
QCOMPARE(false, AutoType::checkHighDelay("{delay 50}"));
|
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
|
// Many repetition / few repetition / delay not repetition
|
||||||
QCOMPARE(true, AutoType::checkHighRepetition("{LEFT 50000000}"));
|
QCOMPARE(true, AutoType::checkHighRepetition("{LEFT 50000000}"));
|
||||||
QCOMPARE(false, AutoType::checkHighRepetition("{SPACE 10}{TAB 3}{RIGHT 50}"));
|
QCOMPARE(false, AutoType::checkHighRepetition("{SPACE 10}{TAB 3}{RIGHT 50}"));
|
||||||
|
Loading…
Reference in New Issue
Block a user