From 45cb97ec8535f6ab5c47cd3d92da91a89f9381b7 Mon Sep 17 00:00:00 2001 From: Marco Date: Mon, 8 May 2017 12:10:53 +0200 Subject: [PATCH 01/18] :bug: #216 add warning on long autotypes, enable user and pw repetition Auto Type now shows a warning when you try to repeat something too often. Also you can now repeat your password and username --- src/autotype/AutoType.cpp | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index 0d01a831..b0c65ccc 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -334,7 +334,9 @@ bool AutoType::parseActions(const QString& sequence, const Entry* entry, QList autoType = createActionFromTemplate(tmpl, entry); + if (autoType.isEmpty()) return false; + actions.append(autoType); inTmpl = false; tmpl.clear(); } @@ -391,11 +393,24 @@ QList AutoType::createActionFromTemplate(const QString& tmpl, c // some safety checks else if (tmplName.compare("delay",Qt::CaseInsensitive)==0) { if (num > 10000) { - return list; + QMessageBox::StandardButton reply; + reply = QMessageBox::question(0,"AutoType", + "This AutoType command contains a very long delay. Do you really want to execute it?"); + + if (reply==QMessageBox::No) { + return list; + } } } else if (num > 100) { - return list; + QMessageBox::StandardButton reply; + reply = QMessageBox::question(0,"AutoType", + "This AutoType command contains arguments which are repeated very often. Do you really want to execute it?"); + + if (reply==QMessageBox::No) { + return list; + } + } } @@ -501,6 +516,7 @@ QList AutoType::createActionFromTemplate(const QString& tmpl, c else if (tmplName.compare("rightbrace",Qt::CaseInsensitive)==0) { list.append(new AutoTypeChar('}')); } + else { QRegExp fnRegexp("f(\\d+)", Qt::CaseInsensitive, QRegExp::RegExp2); if (fnRegexp.exactMatch(tmplName)) { @@ -515,7 +531,6 @@ QList AutoType::createActionFromTemplate(const QString& tmpl, c for (int i = 1; i < num; i++) { list.append(list.at(0)->clone()); } - return list; } @@ -555,6 +570,14 @@ QList AutoType::createActionFromTemplate(const QString& tmpl, c } } + //allows to insert usernames and passwords multiple times + if (!list.isEmpty()) { + for (int i = 1; i < num; i++) { + for (int i = 0; i< resolved.size();i++) { + list.append(list.at(i)->clone()); + } + } + } return list; } From 4fcedc218702b7ec1044887e80f2b29dad75427b Mon Sep 17 00:00:00 2001 From: Marco Date: Sun, 14 May 2017 18:25:43 +0200 Subject: [PATCH 02/18] check autotype syntax, high repetion, reformat code TODO: specify what should happen when autotypesyntax incorrect --- src/autotype/AutoType.cpp | 101 +++++++++++++++--------------- src/gui/entry/EditEntryWidget.cpp | 14 +++++ 2 files changed, 66 insertions(+), 49 deletions(-) diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index b0c65ccc..fa6a5d85 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -62,9 +62,9 @@ AutoType::AutoType(QObject* parent, bool test) QString pluginPath = filePath()->pluginPath(pluginName); if (!pluginPath.isEmpty()) { - #ifdef WITH_XC_AUTOTYPE +#ifdef WITH_XC_AUTOTYPE loadPlugin(pluginPath); - #endif +#endif } connect(qApp, SIGNAL(aboutToQuit()), SLOT(unloadPlugin())); @@ -394,126 +394,128 @@ QList AutoType::createActionFromTemplate(const QString& tmpl, c else if (tmplName.compare("delay",Qt::CaseInsensitive)==0) { if (num > 10000) { QMessageBox::StandardButton reply; - reply = QMessageBox::question(0,"AutoType", + reply = QMessageBox::question(0, + "AutoType", "This AutoType command contains a very long delay. Do you really want to execute it?"); - if (reply==QMessageBox::No) { + if (reply == QMessageBox::No) { return list; } } } else if (num > 100) { QMessageBox::StandardButton reply; - reply = QMessageBox::question(0,"AutoType", + reply = QMessageBox::question(0, + "AutoType", "This AutoType command contains arguments which are repeated very often. Do you really want to execute it?"); - if (reply==QMessageBox::No) { + if (reply == QMessageBox::No) { return list; } } } - if (tmplName.compare("tab",Qt::CaseInsensitive)==0) { + if (tmplName.compare("tab", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Tab)); } - else if (tmplName.compare("enter",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("enter", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Enter)); } - else if (tmplName.compare("space",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("space", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Space)); } - else if (tmplName.compare("up",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("up", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Up)); } - else if (tmplName.compare("down",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("down", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Down)); } - else if (tmplName.compare("left",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("left", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Left)); } - else if (tmplName.compare("right",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("right", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Right)); } - else if (tmplName.compare("insert",Qt::CaseInsensitive)==0 || - tmplName.compare("ins",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("insert", Qt::CaseInsensitive) == 0 || + tmplName.compare("ins", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Insert)); } - else if (tmplName.compare("delete",Qt::CaseInsensitive)==0 || - tmplName.compare("del",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("delete", Qt::CaseInsensitive) == 0 || + tmplName.compare("del", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Delete)); } - else if (tmplName.compare("home",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("home", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Home)); } - else if (tmplName.compare("end",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("end", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_End)); } - else if (tmplName.compare("pgup",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("pgup", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_PageUp)); } - else if (tmplName.compare("pgdown",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("pgdown", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_PageDown)); } - else if (tmplName.compare("backspace",Qt::CaseInsensitive)==0 || - tmplName.compare("bs",Qt::CaseInsensitive)==0 || - tmplName.compare("bksp",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("backspace", Qt::CaseInsensitive) == 0 || + tmplName.compare("bs", Qt::CaseInsensitive) == 0 || + tmplName.compare("bksp", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Backspace)); } - else if (tmplName.compare("break",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("break", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Pause)); } - else if (tmplName.compare("capslock",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("capslock", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_CapsLock)); } - else if (tmplName.compare("esc",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("esc", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Escape)); } - else if (tmplName.compare("help",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("help", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Help)); } - else if (tmplName.compare("numlock",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("numlock", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_NumLock)); } - else if (tmplName.compare("ptrsc",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("ptrsc", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Print)); } - else if (tmplName.compare("scrolllock",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("scrolllock", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_ScrollLock)); } - // Qt doesn't know about keypad keys so use the normal ones instead - else if (tmplName.compare("add",Qt::CaseInsensitive)==0 || - tmplName.compare("+",Qt::CaseInsensitive)==0) { + // Qt doesn't know about keypad keys so use the normal ones instead + else if (tmplName.compare("add", Qt::CaseInsensitive) == 0 || + tmplName.compare("+", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeChar('+')); } - else if (tmplName.compare("subtract",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("subtract", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeChar('-')); } - else if (tmplName.compare("multiply",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("multiply", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeChar('*')); } - else if (tmplName.compare("divide",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("divide", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeChar('/')); } - else if (tmplName.compare("^",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("^", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeChar('^')); } - else if (tmplName.compare("%",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("%", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeChar('%')); } - else if (tmplName.compare("~",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("~", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeChar('~')); } - else if (tmplName.compare("(",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("(", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeChar('(')); } - else if (tmplName.compare(")",Qt::CaseInsensitive)==0) { + else if (tmplName.compare(")", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeChar(')')); } - else if (tmplName.compare("leftbrace",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("leftbrace", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeChar('{')); } - else if (tmplName.compare("rightbrace",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("rightbrace", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeChar('}')); } @@ -535,10 +537,10 @@ QList AutoType::createActionFromTemplate(const QString& tmpl, c } - if (tmplName.compare("delay",Qt::CaseInsensitive)==0 && num > 0) { + if (tmplName.compare("delay", Qt::CaseInsensitive) == 0 && num > 0) { list.append(new AutoTypeDelay(num)); } - else if (tmplName.compare("clearfield",Qt::CaseInsensitive)==0) { + else if (tmplName.compare("clearfield", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeClearField()); } else if (tmplName.compare("totp", Qt::CaseInsensitive) == 0) { @@ -573,7 +575,7 @@ QList AutoType::createActionFromTemplate(const QString& tmpl, c //allows to insert usernames and passwords multiple times if (!list.isEmpty()) { for (int i = 1; i < num; i++) { - for (int i = 0; i< resolved.size();i++) { + for (int i = 0; i < resolved.size(); i++) { list.append(list.at(i)->clone()); } } @@ -626,7 +628,7 @@ QString AutoType::autoTypeSequence(const Entry* entry, const QString& windowTitl sequence = entry->defaultAutoTypeSequence(); } - const Group* group = entry->group(); + const Group *group = entry->group(); do { if (!enableSet) { if (group->autoTypeEnabled() == Group::Disable) { @@ -644,7 +646,8 @@ QString AutoType::autoTypeSequence(const Entry* entry, const QString& windowTitl group = group->parentGroup(); } while (group && (!enableSet || sequence.isEmpty())); - if (sequence.isEmpty() && (!entry->resolvePlaceholder(entry->username()).isEmpty() || !entry->resolvePlaceholder(entry->password()).isEmpty())) { + if (sequence.isEmpty() && (!entry->resolvePlaceholder(entry->username()).isEmpty() + || !entry->resolvePlaceholder(entry->password()).isEmpty())) { if (entry->resolvePlaceholder(entry->username()).isEmpty()) { sequence = "{PASSWORD}{ENTER}"; } diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp index 3e26e309..f8f3ab49 100644 --- a/src/gui/entry/EditEntryWidget.cpp +++ b/src/gui/entry/EditEntryWidget.cpp @@ -764,6 +764,20 @@ void EditEntryWidget::updateEntryData(Entry* entry) const entry->setDefaultAutoTypeSequence(QString()); } else { + QRegExp autoTypeSyntax("(\\{[A-Z]*(\\s[0-9]*){0,1}\\})*"); + autoTypeSyntax.setCaseSensitivity(Qt::CaseInsensitive); + autoTypeSyntax.setPatternSyntax(QRegExp::RegExp); + + + QRegExp highRepetition(".*[0-9]{3,}.*"); //the 3 means 3 digitnumbers are too much + highRepetition.setPatternSyntax(QRegExp::RegExp); + + if (!autoTypeSyntax.exactMatch(m_autoTypeUi->sequenceEdit->text())) { + //@TODO handle wrong syntax + } + if (!highRepetition.exactMatch(m_autoTypeUi->sequenceEdit->text())) { + //@TODO handle too much repetition + } entry->setDefaultAutoTypeSequence(m_autoTypeUi->sequenceEdit->text()); } From d524aea779e97adcecd8184ab0ad0ca7deeab028 Mon Sep 17 00:00:00 2001 From: Marco Date: Mon, 15 May 2017 11:42:13 +0200 Subject: [PATCH 03/18] Extended autotype syntax to allow all things in keepass2 --- src/autotype/AutoType.cpp | 5 +++-- src/gui/entry/EditEntryWidget.cpp | 33 ++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index fa6a5d85..f69431f9 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -20,6 +20,7 @@ #include #include +#include #include "config-keepassx.h" @@ -396,7 +397,7 @@ QList AutoType::createActionFromTemplate(const QString& tmpl, c QMessageBox::StandardButton reply; reply = QMessageBox::question(0, "AutoType", - "This AutoType command contains a very long delay. Do you really want to execute it?"); + tr("This AutoType command contains a very long delay. Do you really want to execute it?")); if (reply == QMessageBox::No) { return list; @@ -407,7 +408,7 @@ QList AutoType::createActionFromTemplate(const QString& tmpl, c QMessageBox::StandardButton reply; reply = QMessageBox::question(0, "AutoType", - "This AutoType command contains arguments which are repeated very often. Do you really want to execute it?"); + tr("This AutoType command contains arguments which are repeated very often. Do you really want to execute it?")); if (reply == QMessageBox::No) { return list; diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp index f8f3ab49..7c612303 100644 --- a/src/gui/entry/EditEntryWidget.cpp +++ b/src/gui/entry/EditEntryWidget.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include "core/Config.h" #include "core/Database.h" @@ -764,11 +765,41 @@ void EditEntryWidget::updateEntryData(Entry* entry) const entry->setDefaultAutoTypeSequence(QString()); } else { - QRegExp autoTypeSyntax("(\\{[A-Z]*(\\s[0-9]*){0,1}\\})*"); + //checks things like {word 23}{F1 23}{~ 23}{% 23}{^}{F12}{(}{) 23}{[}{[}{]}{Delay=23}{+}{-}~+%@fixedstring + + QString allowRepetition = "(\\s[0-9]*){0,1}"; + QString normalCommands = "[A-Z]*" + allowRepetition; + QString specialLiterals = "[\\^\\%\\(\\)~\\{\\}\\[\\]\\+-]" + allowRepetition; + QString functionKeys = "(F[1-9]" +allowRepetition + "|F1[0-2])" + allowRepetition; + QString numpad = "NUMPAD[0-9]" + allowRepetition; + QString delay = "DELAY=[0-9]+"; + QString beep = "BEEP\\s[0-9]*\\s[0-9]*"; + QString vkey = "VKEY-[EN]X" + allowRepetition; + + //these arent in parenthesis + QString shortcutKeys = "[\\^\\%~\\+@]"; + QString fixedStrings = "[^\\^\\%~\\+@\\{\\}]*"; + + QRegExp autoTypeSyntax + ("("+shortcutKeys + "|" + fixedStrings + "|\\{(" + normalCommands + "|" + specialLiterals + "|" + functionKeys + + "|" + numpad + "|" + delay + "|" + beep + "|" + vkey+")\\})*"); autoTypeSyntax.setCaseSensitivity(Qt::CaseInsensitive); autoTypeSyntax.setPatternSyntax(QRegExp::RegExp); + + //small test @TODO delete + if(autoTypeSyntax.exactMatch(QString("{word 23}{F1 23}{~ 23}{% 23}{^}{F12}{(}{) 23}{[}{[}{]}{Delay=23}{+}{-}~+%@fixeds{Beep 23 32}{Vkey-NX 34}"))) { + std::cout << "yes\n"; + } + if(autoTypeSyntax.exactMatch(QString("word 23}{F1 23}{~ 23}{% 23}{^}{F12}{(}{) 23}{[}{[}{]}{Delay=23}{+}{-}~+%@fixeds"))) { + std::cout << "no1\n"; + } + if(autoTypeSyntax.exactMatch(QString("{@}{F1 23}{~ 23}{% 23}{^}{F12}{(}{) 23}{[}{[}{]}{Delay=23}{+}{-}~+%@fixeds"))) { + std::cout << "no2\n"; + } + + //@TODO restrict repetition only on normal commands and delay QRegExp highRepetition(".*[0-9]{3,}.*"); //the 3 means 3 digitnumbers are too much highRepetition.setPatternSyntax(QRegExp::RegExp); From 2bf68b7970f8cd1e769ad2730a2831a6dea97342 Mon Sep 17 00:00:00 2001 From: Marco Date: Mon, 15 May 2017 17:12:29 +0200 Subject: [PATCH 04/18] fix regular expressions for delays and repetition --- src/gui/entry/EditEntryWidget.cpp | 46 +++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp index 7c612303..45b62e11 100644 --- a/src/gui/entry/EditEntryWidget.cpp +++ b/src/gui/entry/EditEntryWidget.cpp @@ -770,43 +770,67 @@ void EditEntryWidget::updateEntryData(Entry* entry) const QString allowRepetition = "(\\s[0-9]*){0,1}"; QString normalCommands = "[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[0-9]" + allowRepetition; QString delay = "DELAY=[0-9]+"; QString beep = "BEEP\\s[0-9]*\\s[0-9]*"; - QString vkey = "VKEY-[EN]X" + allowRepetition; + QString vkey = "VKEY(-[EN]X){0,1}" + allowRepetition; //these arent in parenthesis QString shortcutKeys = "[\\^\\%~\\+@]"; QString fixedStrings = "[^\\^\\%~\\+@\\{\\}]*"; QRegExp autoTypeSyntax - ("("+shortcutKeys + "|" + fixedStrings + "|\\{(" + normalCommands + "|" + specialLiterals + "|" + functionKeys - + "|" + numpad + "|" + delay + "|" + beep + "|" + vkey+")\\})*"); + ("(" + shortcutKeys + "|" + fixedStrings + "|\\{(" + normalCommands + "|" + specialLiterals + "|" + + functionKeys + + "|" + numpad + "|" + delay + "|" + beep + "|" + vkey + ")\\})*"); autoTypeSyntax.setCaseSensitivity(Qt::CaseInsensitive); autoTypeSyntax.setPatternSyntax(QRegExp::RegExp); + QRegExp highDelay(".*\\{Delay\\s[0-9]{5,}\\}.*"); //the 3 means 3 digitnumbers are too much + highDelay.setCaseSensitivity(Qt::CaseInsensitive); + highDelay.setPatternSyntax(QRegExp::RegExp); + + QRegExp highRepetition(".*\\s[0-9]{3,}.*"); + highRepetition.setPatternSyntax(QRegExp::RegExp); //small test @TODO delete - if(autoTypeSyntax.exactMatch(QString("{word 23}{F1 23}{~ 23}{% 23}{^}{F12}{(}{) 23}{[}{[}{]}{Delay=23}{+}{-}~+%@fixeds{Beep 23 32}{Vkey-NX 34}"))) { + if (autoTypeSyntax.exactMatch(QString( + "{word 23}{F1 23}{~ 23}{% 23}{^}{F12}{(}{) 23}{[}{[}{]}{Delay=23}{+}{-}~+%@fixeds{Beep 23 32}{Vkey-NX 34}"))) { std::cout << "yes\n"; } - if(autoTypeSyntax.exactMatch(QString("word 23}{F1 23}{~ 23}{% 23}{^}{F12}{(}{) 23}{[}{[}{]}{Delay=23}{+}{-}~+%@fixeds"))) { + if (autoTypeSyntax + .exactMatch(QString("word 23}{F1 23}{~ 23}{% 23}{^}{F12}{(}{) 23}{[}{[}{]}{Delay=23}{+}{-}~+%@fixeds"))) { std::cout << "no1\n"; } - if(autoTypeSyntax.exactMatch(QString("{@}{F1 23}{~ 23}{% 23}{^}{F12}{(}{) 23}{[}{[}{]}{Delay=23}{+}{-}~+%@fixeds"))) { + if (autoTypeSyntax + .exactMatch(QString("{@}{F1 23}{~ 23}{% 23}{^}{F12}{(}{) 23}{[}{[}{]}{Delay=23}{+}{-}~+%@fixeds"))) { std::cout << "no2\n"; } + if (highDelay.exactMatch("{asfd}{DELAY 10000}{dasf}")) { + std::cout << "yes1\n"; + } + if (highDelay.exactMatch("{asfd}{DELAY 1000}{dasf}")) { + std::cout << "no3\n"; + } + if (highRepetition.exactMatch("{asfd}{DELAY 100}{dasf}")) { + std::cout << "yes2\n"; + } + if (highRepetition.exactMatch("{asfd}{DELAY 10}{dasf}")) { + std::cout << "no4\n"; + } + + - //@TODO restrict repetition only on normal commands and delay - QRegExp highRepetition(".*[0-9]{3,}.*"); //the 3 means 3 digitnumbers are too much - highRepetition.setPatternSyntax(QRegExp::RegExp); if (!autoTypeSyntax.exactMatch(m_autoTypeUi->sequenceEdit->text())) { //@TODO handle wrong syntax } - if (!highRepetition.exactMatch(m_autoTypeUi->sequenceEdit->text())) { + else if (highDelay.exactMatch(m_autoTypeUi->sequenceEdit->text())) { + //@TODO handle too long delay + } + else if (highRepetition.exactMatch(m_autoTypeUi->sequenceEdit->text())) { //@TODO handle too much repetition } entry->setDefaultAutoTypeSequence(m_autoTypeUi->sequenceEdit->text()); From 70127bad4b5ab4a21d663ffd3929daceda9a7a5a Mon Sep 17 00:00:00 2001 From: Marco Date: Mon, 15 May 2017 17:45:17 +0200 Subject: [PATCH 05/18] extract syntax checking methods as static methods to the Autotype class --- src/autotype/AutoType.cpp | 40 ++++++++++++++++++ src/autotype/AutoType.h | 4 ++ src/gui/entry/EditEntryWidget.cpp | 69 ++++--------------------------- 3 files changed, 51 insertions(+), 62 deletions(-) diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index f69431f9..02160738 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -692,3 +692,43 @@ bool AutoType::windowMatchesUrl(const QString& windowTitle, const QString& resol return false; } + +bool AutoType::checkSynatx(const QString &string) +{ + //checks things like {word 23}{F1 23}{~ 23}{% 23}{^}{F12}{(}{) 23}{[}{[}{]}{Delay=23}{+}{-}~+%@fixedstring + QString allowRepetition = "(\\s[0-9]*){0,1}"; + QString normalCommands = "[A-Z]*" + allowRepetition; + QString specialLiterals = "[\\^\\%\\(\\)~\\{\\}\\[\\]\\+-]" + allowRepetition; + QString functionKeys = "(F[1-9]" + allowRepetition + "|F1[0-2])" + allowRepetition; + QString numpad = "NUMPAD[0-9]" + allowRepetition; + QString delay = "DELAY=[0-9]+"; + QString beep = "BEEP\\s[0-9]*\\s[0-9]*"; + QString vkey = "VKEY(-[EN]X){0,1}" + allowRepetition; + + //these arent in parenthesis + QString shortcutKeys = "[\\^\\%~\\+@]"; + 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); +} + +bool AutoType::checkHighDelay(const QString &string) +{ + QRegExp highDelay(".*\\{Delay\\s[0-9]{5,}\\}.*"); //the 3 means 3 digitnumbers are too much + highDelay.setCaseSensitivity(Qt::CaseInsensitive); + highDelay.setPatternSyntax(QRegExp::RegExp); + return highDelay.exactMatch(string); +} + +bool AutoType::checkHighRepetition(const QString &string) +{ + QRegExp highRepetition(".*\\s[0-9]{3,}.*"); + highRepetition.setPatternSyntax(QRegExp::RegExp); + return highRepetition.exactMatch(string); +} diff --git a/src/autotype/AutoType.h b/src/autotype/AutoType.h index e881975a..f38c19f6 100644 --- a/src/autotype/AutoType.h +++ b/src/autotype/AutoType.h @@ -34,6 +34,7 @@ class AutoType : public QObject { Q_OBJECT + public: QStringList windowTitles(); void performAutoType(const Entry* entry, QWidget* hideWindow = nullptr, @@ -41,6 +42,9 @@ public: bool registerGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers); void unregisterGlobalShortcut(); int callEventFilter(void* event); + static bool checkSynatx(const QString &string); + static bool checkHighRepetition(const QString &string); + static bool checkHighDelay(const QString &string); inline bool isAvailable() { return m_plugin; diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp index 45b62e11..cb04e900 100644 --- a/src/gui/entry/EditEntryWidget.cpp +++ b/src/gui/entry/EditEntryWidget.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include "core/Config.h" #include "core/Database.h" @@ -765,73 +766,17 @@ void EditEntryWidget::updateEntryData(Entry* entry) const entry->setDefaultAutoTypeSequence(QString()); } else { - //checks things like {word 23}{F1 23}{~ 23}{% 23}{^}{F12}{(}{) 23}{[}{[}{]}{Delay=23}{+}{-}~+%@fixedstring - - QString allowRepetition = "(\\s[0-9]*){0,1}"; - QString normalCommands = "[A-Z]*" + allowRepetition; - QString specialLiterals = "[\\^\\%\\(\\)~\\{\\}\\[\\]\\+-]" + allowRepetition; - QString functionKeys = "(F[1-9]" + allowRepetition + "|F1[0-2])" + allowRepetition; - QString numpad = "NUMPAD[0-9]" + allowRepetition; - QString delay = "DELAY=[0-9]+"; - QString beep = "BEEP\\s[0-9]*\\s[0-9]*"; - QString vkey = "VKEY(-[EN]X){0,1}" + allowRepetition; - - //these arent in parenthesis - QString shortcutKeys = "[\\^\\%~\\+@]"; - QString fixedStrings = "[^\\^\\%~\\+@\\{\\}]*"; - - QRegExp autoTypeSyntax - ("(" + shortcutKeys + "|" + fixedStrings + "|\\{(" + normalCommands + "|" + specialLiterals + "|" - + functionKeys - + "|" + numpad + "|" + delay + "|" + beep + "|" + vkey + ")\\})*"); - autoTypeSyntax.setCaseSensitivity(Qt::CaseInsensitive); - autoTypeSyntax.setPatternSyntax(QRegExp::RegExp); - - QRegExp highDelay(".*\\{Delay\\s[0-9]{5,}\\}.*"); //the 3 means 3 digitnumbers are too much - highDelay.setCaseSensitivity(Qt::CaseInsensitive); - highDelay.setPatternSyntax(QRegExp::RegExp); - - QRegExp highRepetition(".*\\s[0-9]{3,}.*"); - highRepetition.setPatternSyntax(QRegExp::RegExp); - - - //small test @TODO delete - if (autoTypeSyntax.exactMatch(QString( - "{word 23}{F1 23}{~ 23}{% 23}{^}{F12}{(}{) 23}{[}{[}{]}{Delay=23}{+}{-}~+%@fixeds{Beep 23 32}{Vkey-NX 34}"))) { - std::cout << "yes\n"; - } - if (autoTypeSyntax - .exactMatch(QString("word 23}{F1 23}{~ 23}{% 23}{^}{F12}{(}{) 23}{[}{[}{]}{Delay=23}{+}{-}~+%@fixeds"))) { - std::cout << "no1\n"; - } - if (autoTypeSyntax - .exactMatch(QString("{@}{F1 23}{~ 23}{% 23}{^}{F12}{(}{) 23}{[}{[}{]}{Delay=23}{+}{-}~+%@fixeds"))) { - std::cout << "no2\n"; - } - if (highDelay.exactMatch("{asfd}{DELAY 10000}{dasf}")) { - std::cout << "yes1\n"; - } - if (highDelay.exactMatch("{asfd}{DELAY 1000}{dasf}")) { - std::cout << "no3\n"; - } - if (highRepetition.exactMatch("{asfd}{DELAY 100}{dasf}")) { - std::cout << "yes2\n"; - } - if (highRepetition.exactMatch("{asfd}{DELAY 10}{dasf}")) { - std::cout << "no4\n"; - } - - - - - if (!autoTypeSyntax.exactMatch(m_autoTypeUi->sequenceEdit->text())) { + if (!AutoType::checkSynatx(m_autoTypeUi->sequenceEdit->text())) { //@TODO handle wrong syntax + std::cout << "wrong syntax\n"; } - else if (highDelay.exactMatch(m_autoTypeUi->sequenceEdit->text())) { + else if (AutoType::checkHighDelay(m_autoTypeUi->sequenceEdit->text())) { //@TODO handle too long delay + std::cout << "too long delay\n"; } - else if (highRepetition.exactMatch(m_autoTypeUi->sequenceEdit->text())) { + else if (AutoType::checkHighRepetition(m_autoTypeUi->sequenceEdit->text())) { //@TODO handle too much repetition + std::cout << "too much repetition\n"; } entry->setDefaultAutoTypeSequence(m_autoTypeUi->sequenceEdit->text()); } From 7bb9ea201c1939e2d4d908daeb3320b5a5d05f9b Mon Sep 17 00:00:00 2001 From: Marco Date: Mon, 15 May 2017 17:47:35 +0200 Subject: [PATCH 06/18] fix typo --- src/autotype/AutoType.cpp | 2 +- src/autotype/AutoType.h | 2 +- src/gui/entry/EditEntryWidget.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index 02160738..ac3be5b9 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -693,7 +693,7 @@ bool AutoType::windowMatchesUrl(const QString& windowTitle, const QString& resol return false; } -bool AutoType::checkSynatx(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[0-9]*){0,1}"; diff --git a/src/autotype/AutoType.h b/src/autotype/AutoType.h index f38c19f6..92505b7d 100644 --- a/src/autotype/AutoType.h +++ b/src/autotype/AutoType.h @@ -42,7 +42,7 @@ public: bool registerGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers); void unregisterGlobalShortcut(); int callEventFilter(void* event); - static bool checkSynatx(const QString &string); + static bool checkSyntax(const QString &string); static bool checkHighRepetition(const QString &string); static bool checkHighDelay(const QString &string); diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp index cb04e900..f1bdc814 100644 --- a/src/gui/entry/EditEntryWidget.cpp +++ b/src/gui/entry/EditEntryWidget.cpp @@ -766,7 +766,7 @@ void EditEntryWidget::updateEntryData(Entry* entry) const entry->setDefaultAutoTypeSequence(QString()); } else { - if (!AutoType::checkSynatx(m_autoTypeUi->sequenceEdit->text())) { + if (!AutoType::checkSyntax(m_autoTypeUi->sequenceEdit->text())) { //@TODO handle wrong syntax std::cout << "wrong syntax\n"; } From fbfc2e4d070fe9475fa08e94d68e27ea7b7658fb Mon Sep 17 00:00:00 2001 From: Marco Date: Mon, 15 May 2017 21:06:14 +0200 Subject: [PATCH 07/18] create message boxes for saving editing autotypes statements, fix multiple messages problem on autotype execution You now get an error when you try to save incorrect autotype statements and warnings if you have high delays or much repetiton in your statement. Also you will now only get one warning if you want to perfom high delayed or often repeated statements. --- src/autotype/AutoType.cpp | 54 ++++++++++++++++--------------- src/gui/entry/EditEntryWidget.cpp | 35 ++++++++++++++++---- 2 files changed, 56 insertions(+), 33 deletions(-) diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index ac3be5b9..4ad83b08 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include "config-keepassx.h" @@ -328,8 +329,33 @@ bool AutoType::parseActions(const QString& sequence, const Entry* entry, QListget("AutoTypeDelay").toInt(); - for (const QChar& ch : sequence) { - if (inTmpl) { + if (!AutoType::checkSyntax(sequence)) { + QMessageBox messageBox; + messageBox.critical(0, "AutoType", tr("The Syntax of your AutoType statement is incorrect!")); + return false; + } + else if (AutoType::checkHighDelay(sequence)) { + QMessageBox::StandardButton reply; + reply = QMessageBox::question(0, + "AutoType", + tr("This AutoType command contains a very long delay. Do you really want to execute it?")); + + if (reply == QMessageBox::No) { + return false; + } + } + else if (AutoType::checkHighRepetition(sequence)) { + QMessageBox::StandardButton reply; + reply = QMessageBox::question(0, + "AutoType", + tr("This AutoType command contains arguments which are repeated very often. Do you really want to execute it?")); + + if (reply == QMessageBox::No) { + return false; + } + } + + for (const QChar &ch : sequence) { if (ch == '{') { qWarning("Syntax error in auto-type sequence."); return false; @@ -391,30 +417,6 @@ QList AutoType::createActionFromTemplate(const QString& tmpl, c if (num == 0) { return list; } - // some safety checks - else if (tmplName.compare("delay",Qt::CaseInsensitive)==0) { - if (num > 10000) { - QMessageBox::StandardButton reply; - reply = QMessageBox::question(0, - "AutoType", - tr("This AutoType command contains a very long delay. Do you really want to execute it?")); - - if (reply == QMessageBox::No) { - return list; - } - } - } - else if (num > 100) { - QMessageBox::StandardButton reply; - reply = QMessageBox::question(0, - "AutoType", - tr("This AutoType command contains arguments which are repeated very often. Do you really want to execute it?")); - - if (reply == QMessageBox::No) { - return list; - } - - } } if (tmplName.compare("tab", Qt::CaseInsensitive) == 0) { diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp index f1bdc814..17159051 100644 --- a/src/gui/entry/EditEntryWidget.cpp +++ b/src/gui/entry/EditEntryWidget.cpp @@ -767,18 +767,39 @@ void EditEntryWidget::updateEntryData(Entry* entry) const } else { if (!AutoType::checkSyntax(m_autoTypeUi->sequenceEdit->text())) { - //@TODO handle wrong syntax - std::cout << "wrong syntax\n"; + //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())) { - //@TODO handle too long delay - std::cout << "too long delay\n"; + //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())) { - //@TODO handle too much repetition - std::cout << "too much repetition\n"; + //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()); + } } - entry->setDefaultAutoTypeSequence(m_autoTypeUi->sequenceEdit->text()); + else { + entry->setDefaultAutoTypeSequence(m_autoTypeUi->sequenceEdit->text()); + } + } entry->autoTypeAssociations()->copyDataFrom(m_autoTypeAssoc); From a4bdc9a71d41a106396cbe3d42bffcb8de09147d Mon Sep 17 00:00:00 2001 From: thez3ro Date: Tue, 7 Nov 2017 14:07:47 +0100 Subject: [PATCH 08/18] fix syntax error --- src/autotype/AutoType.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index 4ad83b08..74f68702 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -356,13 +356,16 @@ bool AutoType::parseActions(const QString& sequence, const Entry* entry, QList autoType = createActionFromTemplate(tmpl, entry); - if (autoType.isEmpty()) return false; + QList autoType = createActionFromTemplate(tmpl, entry); + if (autoType.isEmpty()) { + return false; + } actions.append(autoType); inTmpl = false; tmpl.clear(); From 6057c9f27daff15f40a6ebb84192c00f428f12d6 Mon Sep 17 00:00:00 2001 From: Marco Date: Mon, 15 May 2017 21:48:47 +0200 Subject: [PATCH 09/18] fix comments --- src/autotype/AutoType.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index 74f68702..40052796 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -725,7 +725,7 @@ bool AutoType::checkSyntax(const QString &string) bool AutoType::checkHighDelay(const QString &string) { - QRegExp highDelay(".*\\{Delay\\s[0-9]{5,}\\}.*"); //the 3 means 3 digitnumbers are too much + QRegExp highDelay(".*\\{Delay\\s[0-9]{5,}\\}.*"); //5 digit numbers(10 seconds) are too much highDelay.setCaseSensitivity(Qt::CaseInsensitive); highDelay.setPatternSyntax(QRegExp::RegExp); return highDelay.exactMatch(string); @@ -733,7 +733,7 @@ bool AutoType::checkHighDelay(const QString &string) bool AutoType::checkHighRepetition(const QString &string) { - QRegExp highRepetition(".*\\s[0-9]{3,}.*"); + QRegExp highRepetition(".*\\s[0-9]{3,}.*");//3 digit numbers are too much highRepetition.setPatternSyntax(QRegExp::RegExp); return highRepetition.exactMatch(string); } From 393017cf3bc58f49e43b52b8701f98296a087df2 Mon Sep 17 00:00:00 2001 From: Marco Date: Tue, 16 May 2017 10:54:15 +0200 Subject: [PATCH 10/18] fix for loops now have diffrent variables. dont know why it worked before --- src/autotype/AutoType.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index 40052796..0d76e3de 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -581,8 +581,8 @@ QList AutoType::createActionFromTemplate(const QString& tmpl, c //allows to insert usernames and passwords multiple times if (!list.isEmpty()) { for (int i = 1; i < num; i++) { - for (int i = 0; i < resolved.size(); i++) { - list.append(list.at(i)->clone()); + for (int j = 0; j < resolved.size(); j++) { + list.append(list.at(j)->clone()); } } } From 4893d997740a53dff068a72a4eefcf348ec7ed89 Mon Sep 17 00:00:00 2001 From: Marco Date: Wed, 31 May 2017 21:23:33 +0200 Subject: [PATCH 11/18] move autotype syntax warning and error dialogs from AutoType to DatabaseWidget in the gui folder and replaced it with a checkSyntax call. this fixes part of why autotype test fails --- src/autotype/AutoType.cpp | 31 ++++--------------------------- src/gui/DatabaseWidget.cpp | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index 0d76e3de..fbe64b45 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -145,6 +145,10 @@ void AutoType::performAutoType(const Entry* entry, QWidget* hideWindow, const QS sequence = customSequence; } + if (!checkSyntax(sequence)) { + return; + } + sequence.replace("{{}", "{LEFTBRACE}"); sequence.replace("{}}", "{RIGHTBRACE}"); @@ -328,33 +332,6 @@ bool AutoType::parseActions(const QString& sequence, const Entry* entry, QListget("AutoTypeDelay").toInt(); - - if (!AutoType::checkSyntax(sequence)) { - QMessageBox messageBox; - messageBox.critical(0, "AutoType", tr("The Syntax of your AutoType statement is incorrect!")); - return false; - } - else if (AutoType::checkHighDelay(sequence)) { - QMessageBox::StandardButton reply; - reply = QMessageBox::question(0, - "AutoType", - tr("This AutoType command contains a very long delay. Do you really want to execute it?")); - - if (reply == QMessageBox::No) { - return false; - } - } - else if (AutoType::checkHighRepetition(sequence)) { - QMessageBox::StandardButton reply; - reply = QMessageBox::question(0, - "AutoType", - tr("This AutoType command contains arguments which are repeated very often. Do you really want to execute it?")); - - if (reply == QMessageBox::No) { - return false; - } - } - for (const QChar &ch : sequence) { if (inTmpl) { if (ch == '{') { diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp index 1ef91a4f..3fe403fc 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -584,6 +584,31 @@ void DatabaseWidget::performAutoType() return; } + if (!AutoType::checkSyntax(currentEntry->effectiveAutoTypeSequence())) { + QMessageBox messageBox; + messageBox.critical(0, "AutoType", tr("The Syntax of your AutoType statement is incorrect!")); + return; + } + else if (AutoType::checkHighDelay(currentEntry->effectiveAutoTypeSequence())) { + QMessageBox::StandardButton reply; + reply = QMessageBox::question(0, + "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(currentEntry->effectiveAutoTypeSequence())) { + QMessageBox::StandardButton reply; + reply = QMessageBox::question(0, + "AutoType", + tr("This AutoType command contains arguments which are repeated very often. Do you really want to execute it?")); + + if (reply == QMessageBox::No) { + return; + } + } autoType()->performAutoType(currentEntry, window()); } From 7ceac0539549d07a0f14e517f277f002c242495f Mon Sep 17 00:00:00 2001 From: Marco Date: Wed, 31 May 2017 21:27:04 +0200 Subject: [PATCH 12/18] add support for custom commands. all autotype tests are getting passed now --- src/autotype/AutoType.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index fbe64b45..e4618f74 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -679,7 +679,7 @@ bool AutoType::checkSyntax(const QString &string) { //checks things like {word 23}{F1 23}{~ 23}{% 23}{^}{F12}{(}{) 23}{[}{[}{]}{Delay=23}{+}{-}~+%@fixedstring QString allowRepetition = "(\\s[0-9]*){0,1}"; - QString normalCommands = "[A-Z]*" + allowRepetition; + QString normalCommands = "[A-Z:]*" + allowRepetition; //the ":" allows custom commands QString specialLiterals = "[\\^\\%\\(\\)~\\{\\}\\[\\]\\+-]" + allowRepetition; QString functionKeys = "(F[1-9]" + allowRepetition + "|F1[0-2])" + allowRepetition; QString numpad = "NUMPAD[0-9]" + allowRepetition; From 8ca444aee005dd37284d83591a6f3c18f5c2ef66 Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 3 Jun 2017 12:32:46 +0200 Subject: [PATCH 13/18] add a method to perform the autotype sequence showing graphical dialogs Dialogs are show when the syntax of the autotype statement is wrong or contains long delays or statements which are repeated very often --- src/autotype/AutoType.cpp | 38 +++++++++++++++++++++++++++++++++++++- src/autotype/AutoType.h | 4 ++++ src/gui/DatabaseWidget.cpp | 35 +++++------------------------------ 3 files changed, 46 insertions(+), 31 deletions(-) diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index e4618f74..319814a3 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -252,7 +252,8 @@ void AutoType::performAutoTypeFromGlobal(Entry* entry, const QString& sequence) m_plugin->raiseWindow(m_windowFromGlobal); m_inAutoType = false; - performAutoType(entry, nullptr, sequence, m_windowFromGlobal); + + performAutoTypeWithSyntaxCheckingDialog(entry, nullptr, sequence, m_windowFromGlobal); } void AutoType::resetInAutoType() @@ -714,3 +715,38 @@ bool AutoType::checkHighRepetition(const QString &string) highRepetition.setPatternSyntax(QRegExp::RegExp); return highRepetition.exactMatch(string); } + +void +AutoType::performAutoTypeWithSyntaxCheckingDialog(const Entry *entry, + QWidget *hideWindow, + const QString &customSequence, + WId window) +{ + if (!AutoType::checkSyntax(entry->effectiveAutoTypeSequence())) { + QMessageBox messageBox; + messageBox.critical(0, "AutoType", tr("The Syntax of your AutoType statement is incorrect!")); + return; + } + else if (AutoType::checkHighDelay(entry->effectiveAutoTypeSequence())) { + QMessageBox::StandardButton reply; + reply = QMessageBox::question(0, + "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, + "AutoType", + tr("This AutoType command contains arguments which are repeated very often. Do you really want to execute it?")); + + if (reply == QMessageBox::No) { + return; + } + } + performAutoType(entry, hideWindow, customSequence, window); + +} diff --git a/src/autotype/AutoType.h b/src/autotype/AutoType.h index 92505b7d..90d12a7f 100644 --- a/src/autotype/AutoType.h +++ b/src/autotype/AutoType.h @@ -45,6 +45,10 @@ public: static bool checkSyntax(const QString &string); static bool checkHighRepetition(const QString &string); static bool checkHighDelay(const QString &string); + void performAutoTypeWithSyntaxCheckingDialog(const Entry *entry, + QWidget *hideWindow = nullptr, + const QString &customSequence = QString(), + WId window = 0); inline bool isAvailable() { return m_plugin; diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp index 3fe403fc..3f5222e1 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -584,32 +584,7 @@ void DatabaseWidget::performAutoType() return; } - if (!AutoType::checkSyntax(currentEntry->effectiveAutoTypeSequence())) { - QMessageBox messageBox; - messageBox.critical(0, "AutoType", tr("The Syntax of your AutoType statement is incorrect!")); - return; - } - else if (AutoType::checkHighDelay(currentEntry->effectiveAutoTypeSequence())) { - QMessageBox::StandardButton reply; - reply = QMessageBox::question(0, - "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(currentEntry->effectiveAutoTypeSequence())) { - QMessageBox::StandardButton reply; - reply = QMessageBox::question(0, - "AutoType", - tr("This AutoType command contains arguments which are repeated very often. Do you really want to execute it?")); - - if (reply == QMessageBox::No) { - return; - } - } - autoType()->performAutoType(currentEntry, window()); + autoType()->performAutoTypeWithSyntaxCheckingDialog(currentEntry, window()); } void DatabaseWidget::openUrl() @@ -638,7 +613,7 @@ void DatabaseWidget::openUrlForEntry(Entry* entry) } return; } - + // otherwise ask user if (urlString.length() > 6) { QString cmdTruncated = urlString.mid(6); @@ -652,7 +627,7 @@ void DatabaseWidget::openUrlForEntry(Entry* entry) this ); msgbox.setDefaultButton(QMessageBox::No); - + QCheckBox* checkbox = new QCheckBox(tr("Remember my choice"), &msgbox); msgbox.setCheckBox(checkbox); bool remember = false; @@ -661,12 +636,12 @@ void DatabaseWidget::openUrlForEntry(Entry* entry) remember = true; } }); - + int result = msgbox.exec(); if (result == QMessageBox::Yes) { QProcess::startDetached(urlString.mid(6)); } - + if (remember) { entry->attributes()->set(EntryAttributes::RememberCmdExecAttr, result == QMessageBox::Yes ? "1" : "0"); From a02a49a1841aba425f6186e6e8b88470b3cdd008 Mon Sep 17 00:00:00 2001 From: thez3ro Date: Tue, 7 Nov 2017 17:58:08 +0100 Subject: [PATCH 14/18] add test for syntax checking --- src/autotype/AutoType.cpp | 32 +++++++++++-------------------- src/autotype/AutoType.h | 8 +++----- src/gui/DatabaseWidget.cpp | 2 +- src/gui/entry/EditEntryWidget.cpp | 2 +- tests/TestAutoType.cpp | 15 +++++++++++++++ tests/TestAutoType.h | 1 + 6 files changed, 32 insertions(+), 28 deletions(-) diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index 319814a3..00cb8d51 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -130,7 +130,7 @@ QStringList AutoType::windowTitles() return m_plugin->windowTitles(); } -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 (m_inAutoType || !m_plugin) { return; @@ -253,7 +253,7 @@ void AutoType::performAutoTypeFromGlobal(Entry* entry, const QString& sequence) m_inAutoType = false; - performAutoTypeWithSyntaxCheckingDialog(entry, nullptr, sequence, m_windowFromGlobal); + performAutoType(entry, nullptr, sequence, m_windowFromGlobal); } void AutoType::resetInAutoType() @@ -556,14 +556,6 @@ QList AutoType::createActionFromTemplate(const QString& tmpl, c } } - //allows to insert usernames and passwords multiple times - if (!list.isEmpty()) { - for (int i = 1; i < num; i++) { - for (int j = 0; j < resolved.size(); j++) { - list.append(list.at(j)->clone()); - } - } - } return list; } @@ -679,13 +671,13 @@ 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[0-9]*){0,1}"; + QString allowRepetition = "(\\s\\d*){0,1}"; QString normalCommands = "[A-Z:]*" + allowRepetition; //the ":" allows custom commands QString specialLiterals = "[\\^\\%\\(\\)~\\{\\}\\[\\]\\+-]" + allowRepetition; QString functionKeys = "(F[1-9]" + allowRepetition + "|F1[0-2])" + allowRepetition; - QString numpad = "NUMPAD[0-9]" + allowRepetition; - QString delay = "DELAY=[0-9]+"; - QString beep = "BEEP\\s[0-9]*\\s[0-9]*"; + QString numpad = "NUMPAD\\d" + allowRepetition; + QString delay = "DELAY=\\d+"; + QString beep = "BEEP\\s\\d*\\s\\d*"; QString vkey = "VKEY(-[EN]X){0,1}" + allowRepetition; //these arent in parenthesis @@ -703,7 +695,7 @@ bool AutoType::checkSyntax(const QString &string) bool AutoType::checkHighDelay(const QString &string) { - QRegExp highDelay(".*\\{Delay\\s[0-9]{5,}\\}.*"); //5 digit numbers(10 seconds) are too much + 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); @@ -711,16 +703,14 @@ bool AutoType::checkHighDelay(const QString &string) bool AutoType::checkHighRepetition(const QString &string) { - QRegExp highRepetition(".*\\s[0-9]{3,}.*");//3 digit numbers are too much + 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); } void -AutoType::performAutoTypeWithSyntaxCheckingDialog(const Entry *entry, - QWidget *hideWindow, - const QString &customSequence, - WId window) +AutoType::performAutoType(const Entry *entry, QWidget *hideWindow, const QString &customSequence, WId window) { if (!AutoType::checkSyntax(entry->effectiveAutoTypeSequence())) { QMessageBox messageBox; @@ -747,6 +737,6 @@ AutoType::performAutoTypeWithSyntaxCheckingDialog(const Entry *entry, return; } } - performAutoType(entry, hideWindow, customSequence, window); + _performAutoType(entry, hideWindow, customSequence, window); } diff --git a/src/autotype/AutoType.h b/src/autotype/AutoType.h index 90d12a7f..8aff7a94 100644 --- a/src/autotype/AutoType.h +++ b/src/autotype/AutoType.h @@ -37,7 +37,7 @@ class AutoType : public QObject public: QStringList windowTitles(); - void performAutoType(const Entry* entry, QWidget* hideWindow = nullptr, + void _performAutoType(const Entry* entry, QWidget* hideWindow = nullptr, const QString& customSequence = QString(), WId window = 0); bool registerGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers); void unregisterGlobalShortcut(); @@ -45,10 +45,8 @@ public: static bool checkSyntax(const QString &string); static bool checkHighRepetition(const QString &string); static bool checkHighDelay(const QString &string); - void performAutoTypeWithSyntaxCheckingDialog(const Entry *entry, - QWidget *hideWindow = nullptr, - const QString &customSequence = QString(), - WId window = 0); + void performAutoType(const Entry *entry, QWidget *hideWindow = nullptr, + const QString &customSequence = QString(), WId window = 0); inline bool isAvailable() { return m_plugin; diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp index 3f5222e1..387d5d2a 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -584,7 +584,7 @@ void DatabaseWidget::performAutoType() return; } - autoType()->performAutoTypeWithSyntaxCheckingDialog(currentEntry, window()); + autoType()->performAutoType(currentEntry, window()); } void DatabaseWidget::openUrl() diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp index 17159051..fdb8aa14 100644 --- a/src/gui/entry/EditEntryWidget.cpp +++ b/src/gui/entry/EditEntryWidget.cpp @@ -32,8 +32,8 @@ #include #include #include -#include +#include "autotype/AutoType.h" #include "core/Config.h" #include "core/Database.h" #include "core/Entry.h" diff --git a/tests/TestAutoType.cpp b/tests/TestAutoType.cpp index acc2df61..d1c09c26 100644 --- a/tests/TestAutoType.cpp +++ b/tests/TestAutoType.cpp @@ -282,3 +282,18 @@ void TestAutoType::testGlobalAutoTypeRegExp() QCOMPARE(m_test->actionChars(), QString("custom_attr_third")); m_test->clearActions(); } + +void TestAutoType::testAutoTypeSyntaxChecks() +{ + // Huge sequence + QCOMPARE(true, AutoType::checkSyntax("{word 23}{F1 23}{~ 23}{% 23}{^}{F12}{(}{) 23}{[}{[}{]}{Delay=23}{+}{-}~+%@fixedstring")); + // Bad sequence + QCOMPARE(false, AutoType::checkSyntax("{{{}}{}{}}{{}}")); + // High DelAY / low delay + QCOMPARE(true, AutoType::checkHighDelay("{DelAY 50000}")); + QCOMPARE(false, AutoType::checkHighDelay("{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}")); + QCOMPARE(false, AutoType::checkHighRepetition("{delay 5000000000}")); +} \ No newline at end of file diff --git a/tests/TestAutoType.h b/tests/TestAutoType.h index 0cd4a5bd..b7c33823 100644 --- a/tests/TestAutoType.h +++ b/tests/TestAutoType.h @@ -47,6 +47,7 @@ private slots: void testGlobalAutoTypeUrlSubdomainMatch(); void testGlobalAutoTypeTitleMatchDisabled(); void testGlobalAutoTypeRegExp(); + void testAutoTypeSyntaxChecks(); private: AutoTypePlatformInterface* m_platform; From 3d5ff723e99c99962d079fd0af02119bb28cbea5 Mon Sep 17 00:00:00 2001 From: thez3ro Date: Wed, 8 Nov 2017 17:21:56 +0100 Subject: [PATCH 15/18] fix codestyle --- src/autotype/AutoType.cpp | 239 ++++++++++++++------------------------ src/autotype/AutoType.h | 25 ++-- 2 files changed, 104 insertions(+), 160 deletions(-) diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index 00cb8d51..556dc2de 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -20,8 +20,8 @@ #include #include -#include #include +#include #include "config-keepassx.h" @@ -56,8 +56,7 @@ AutoType::AutoType(QObject* parent, bool test) QString pluginName = "keepassx-autotype-"; if (!test) { pluginName += QApplication::platformName(); - } - else { + } else { pluginName += "test"; } @@ -93,8 +92,7 @@ void AutoType::loadPlugin(const QString& pluginPath) if (m_plugin->isAvailable()) { m_executor = m_plugin->createExecutor(); connect(pluginInstance, SIGNAL(globalShortcutTriggered()), SIGNAL(globalShortcutTriggered())); - } - else { + } else { unloadPlugin(); } } @@ -140,8 +138,7 @@ void AutoType::_performAutoType(const Entry* entry, QWidget* hideWindow, const Q QString sequence; if (customSequence.isEmpty()) { sequence = autoTypeSequence(entry); - } - else { + } else { sequence = customSequence; } @@ -223,16 +220,14 @@ void AutoType::performGlobalAutoType(const QList& dbList) message.append("\n\n"); message.append(windowTitle); MessageBox::information(nullptr, tr("Auto-Type - KeePassXC"), message); - } - else if ((entryList.size() == 1) && !config()->get("security/autotypeask").toBool()) { + } else if ((entryList.size() == 1) && !config()->get("security/autotypeask").toBool()) { m_inAutoType = false; performAutoType(entryList.first(), nullptr, sequenceHash[entryList.first()]); - } - else { + } else { m_windowFromGlobal = m_plugin->activeWindow(); AutoTypeSelectDialog* selectDialog = new AutoTypeSelectDialog(); - connect(selectDialog, SIGNAL(entryActivated(Entry*,QString)), - SLOT(performAutoTypeFromGlobal(Entry*,QString))); + connect( + selectDialog, SIGNAL(entryActivated(Entry*, QString)), SLOT(performAutoTypeFromGlobal(Entry*, QString))); connect(selectDialog, SIGNAL(rejected()), SLOT(resetInAutoType())); selectDialog->setEntries(entryList, sequenceHash); #if defined(Q_OS_MAC) @@ -301,12 +296,10 @@ bool AutoType::registerGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifie m_currentGlobalKey = key; m_currentGlobalModifiers = modifiers; return true; - } - else { + } else { return false; } - } - else { + } else { return true; } } @@ -333,33 +326,28 @@ bool AutoType::parseActions(const QString& sequence, const Entry* entry, QListget("AutoTypeDelay").toInt(); - for (const QChar &ch : sequence) { + for (const QChar& ch : sequence) { if (inTmpl) { if (ch == '{') { qWarning("Syntax error in auto-type sequence."); return false; - } - else if (ch == '}') { - QList autoType = createActionFromTemplate(tmpl, entry); + } else if (ch == '}') { + QList autoType = createActionFromTemplate(tmpl, entry); if (autoType.isEmpty()) { return false; } actions.append(autoType); inTmpl = false; tmpl.clear(); - } - else { + } else { tmpl += ch; } - } - else if (ch == '{') { + } else if (ch == '{') { inTmpl = true; - } - else if (ch == '}') { + } else if (ch == '}') { qWarning("Syntax error in auto-type sequence."); return false; - } - else { + } else { actions.append(new AutoTypeChar(ch)); } } @@ -402,104 +390,72 @@ QList AutoType::createActionFromTemplate(const QString& tmpl, c if (tmplName.compare("tab", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Tab)); - } - else if (tmplName.compare("enter", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("enter", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Enter)); - } - else if (tmplName.compare("space", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("space", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Space)); - } - else if (tmplName.compare("up", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("up", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Up)); - } - else if (tmplName.compare("down", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("down", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Down)); - } - else if (tmplName.compare("left", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("left", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Left)); - } - else if (tmplName.compare("right", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("right", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Right)); - } - else if (tmplName.compare("insert", Qt::CaseInsensitive) == 0 || - tmplName.compare("ins", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("insert", Qt::CaseInsensitive) == 0 || + tmplName.compare("ins", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Insert)); - } - else if (tmplName.compare("delete", Qt::CaseInsensitive) == 0 || - tmplName.compare("del", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("delete", Qt::CaseInsensitive) == 0 || + tmplName.compare("del", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Delete)); - } - else if (tmplName.compare("home", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("home", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Home)); - } - else if (tmplName.compare("end", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("end", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_End)); - } - else if (tmplName.compare("pgup", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("pgup", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_PageUp)); - } - else if (tmplName.compare("pgdown", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("pgdown", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_PageDown)); - } - else if (tmplName.compare("backspace", Qt::CaseInsensitive) == 0 || - tmplName.compare("bs", Qt::CaseInsensitive) == 0 || - tmplName.compare("bksp", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("backspace", Qt::CaseInsensitive) == 0 || + tmplName.compare("bs", Qt::CaseInsensitive) == 0 || tmplName.compare("bksp", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Backspace)); - } - else if (tmplName.compare("break", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("break", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Pause)); - } - else if (tmplName.compare("capslock", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("capslock", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_CapsLock)); - } - else if (tmplName.compare("esc", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("esc", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Escape)); - } - else if (tmplName.compare("help", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("help", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Help)); - } - else if (tmplName.compare("numlock", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("numlock", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_NumLock)); - } - else if (tmplName.compare("ptrsc", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("ptrsc", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_Print)); - } - else if (tmplName.compare("scrolllock", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("scrolllock", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeKey(Qt::Key_ScrollLock)); } - // Qt doesn't know about keypad keys so use the normal ones instead - else if (tmplName.compare("add", Qt::CaseInsensitive) == 0 || - tmplName.compare("+", Qt::CaseInsensitive) == 0) { + // Qt doesn't know about keypad keys so use the normal ones instead + else if (tmplName.compare("add", Qt::CaseInsensitive) == 0 || tmplName.compare("+", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeChar('+')); - } - else if (tmplName.compare("subtract", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("subtract", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeChar('-')); - } - else if (tmplName.compare("multiply", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("multiply", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeChar('*')); - } - else if (tmplName.compare("divide", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("divide", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeChar('/')); - } - else if (tmplName.compare("^", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("^", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeChar('^')); - } - else if (tmplName.compare("%", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("%", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeChar('%')); - } - else if (tmplName.compare("~", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("~", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeChar('~')); - } - else if (tmplName.compare("(", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("(", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeChar('(')); - } - else if (tmplName.compare(")", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare(")", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeChar(')')); - } - else if (tmplName.compare("leftbrace", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("leftbrace", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeChar('{')); - } - else if (tmplName.compare("rightbrace", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("rightbrace", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeChar('}')); } @@ -520,14 +476,11 @@ QList AutoType::createActionFromTemplate(const QString& tmpl, c return list; } - if (tmplName.compare("delay", Qt::CaseInsensitive) == 0 && num > 0) { list.append(new AutoTypeDelay(num)); - } - else if (tmplName.compare("clearfield", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("clearfield", Qt::CaseInsensitive) == 0) { list.append(new AutoTypeClearField()); - } - else if (tmplName.compare("totp", Qt::CaseInsensitive) == 0) { + } else if (tmplName.compare("totp", Qt::CaseInsensitive) == 0) { QString totp = entry->totp(); if (!totp.isEmpty()) { for (const QChar& ch : totp) { @@ -546,11 +499,9 @@ QList AutoType::createActionFromTemplate(const QString& tmpl, c for (const QChar& ch : resolved) { if (ch == '\n') { list.append(new AutoTypeKey(Qt::Key_Enter)); - } - else if (ch == '\t') { + } else if (ch == '\t') { list.append(new AutoTypeKey(Qt::Key_Tab)); - } - else { + } else { list.append(new AutoTypeChar(ch)); } } @@ -575,8 +526,7 @@ QString AutoType::autoTypeSequence(const Entry* entry, const QString& windowTitl if (windowMatches(windowTitle, window)) { if (!assoc.sequence.isEmpty()) { sequence = assoc.sequence; - } - else { + } else { sequence = entry->defaultAutoTypeSequence(); } match = true; @@ -584,14 +534,14 @@ QString AutoType::autoTypeSequence(const Entry* entry, const QString& windowTitl } } - if (!match && config()->get("AutoTypeEntryTitleMatch").toBool() - && windowMatchesTitle(windowTitle, entry->resolvePlaceholder(entry->title()))) { + if (!match && config()->get("AutoTypeEntryTitleMatch").toBool() && + windowMatchesTitle(windowTitle, entry->resolvePlaceholder(entry->title()))) { sequence = entry->defaultAutoTypeSequence(); match = true; } - if (!match && config()->get("AutoTypeEntryURLMatch").toBool() - && windowMatchesUrl(windowTitle, entry->resolvePlaceholder(entry->url()))) { + if (!match && config()->get("AutoTypeEntryURLMatch").toBool() && + windowMatchesUrl(windowTitle, entry->resolvePlaceholder(entry->url()))) { sequence = entry->defaultAutoTypeSequence(); match = true; } @@ -599,18 +549,16 @@ QString AutoType::autoTypeSequence(const Entry* entry, const QString& windowTitl if (!match) { return QString(); } - } - else { + } else { sequence = entry->defaultAutoTypeSequence(); } - const Group *group = entry->group(); + const Group* group = entry->group(); do { if (!enableSet) { if (group->autoTypeEnabled() == Group::Disable) { return QString(); - } - else if (group->autoTypeEnabled() == Group::Enable) { + } else if (group->autoTypeEnabled() == Group::Enable) { enableSet = true; } } @@ -622,15 +570,13 @@ QString AutoType::autoTypeSequence(const Entry* entry, const QString& windowTitl group = group->parentGroup(); } while (group && (!enableSet || sequence.isEmpty())); - if (sequence.isEmpty() && (!entry->resolvePlaceholder(entry->username()).isEmpty() - || !entry->resolvePlaceholder(entry->password()).isEmpty())) { + if (sequence.isEmpty() && (!entry->resolvePlaceholder(entry->username()).isEmpty() || + !entry->resolvePlaceholder(entry->password()).isEmpty())) { if (entry->resolvePlaceholder(entry->username()).isEmpty()) { sequence = "{PASSWORD}{ENTER}"; - } - else if (entry->resolvePlaceholder(entry->password()).isEmpty()) { + } else if (entry->resolvePlaceholder(entry->password()).isEmpty()) { sequence = "{USERNAME}{ENTER}"; - } - else { + } else { sequence = "{USERNAME}{TAB}{PASSWORD}{ENTER}"; } } @@ -643,8 +589,7 @@ bool AutoType::windowMatches(const QString& windowTitle, const QString& windowPa if (windowPattern.startsWith("//") && windowPattern.endsWith("//") && windowPattern.size() >= 4) { QRegExp regExp(windowPattern.mid(2, windowPattern.size() - 4), Qt::CaseInsensitive, QRegExp::RegExp2); return (regExp.indexIn(windowTitle) != -1); - } - else { + } else { return WildcardMatcher(windowTitle).match(windowPattern); } } @@ -668,11 +613,11 @@ bool AutoType::windowMatchesUrl(const QString& windowTitle, const QString& resol return false; } -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 + // 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 normalCommands = "[A-Z:]*" + allowRepetition; // the ":" allows custom commands QString specialLiterals = "[\\^\\%\\(\\)~\\{\\}\\[\\]\\+-]" + allowRepetition; QString functionKeys = "(F[1-9]" + allowRepetition + "|F1[0-2])" + allowRepetition; QString numpad = "NUMPAD\\d" + allowRepetition; @@ -680,63 +625,57 @@ bool AutoType::checkSyntax(const QString &string) QString beep = "BEEP\\s\\d*\\s\\d*"; QString vkey = "VKEY(-[EN]X){0,1}" + allowRepetition; - //these arent in parenthesis + // these arent in parenthesis QString shortcutKeys = "[\\^\\%~\\+@]"; QString fixedStrings = "[^\\^\\%~\\+@\\{\\}]*"; - QRegExp autoTypeSyntax - ("(" + shortcutKeys + "|" + fixedStrings + "|\\{(" + normalCommands + "|" + specialLiterals + "|" - + functionKeys - + "|" + numpad + "|" + delay + "|" + beep + "|" + vkey + ")\\})*"); + QRegExp autoTypeSyntax("(" + shortcutKeys + "|" + fixedStrings + "|\\{(" + normalCommands + "|" + specialLiterals + + "|" + functionKeys + "|" + numpad + "|" + delay + "|" + beep + "|" + vkey + ")\\})*"); autoTypeSyntax.setCaseSensitivity(Qt::CaseInsensitive); autoTypeSyntax.setPatternSyntax(QRegExp::RegExp); return autoTypeSyntax.exactMatch(string); } -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 + 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); } -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 + 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); } -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())) { QMessageBox messageBox; - messageBox.critical(0, "AutoType", tr("The Syntax of your AutoType statement is incorrect!")); + messageBox.critical(0, tr("AutoType"), tr("The Syntax of your AutoType statement is incorrect!")); return; - } - else if (AutoType::checkHighDelay(entry->effectiveAutoTypeSequence())) { + } else if (AutoType::checkHighDelay(entry->effectiveAutoTypeSequence())) { QMessageBox::StandardButton reply; - reply = QMessageBox::question(0, - "AutoType", - tr("This AutoType command contains a very long delay. Do you really want to execute it?")); + 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())) { + } else if (AutoType::checkHighRepetition(entry->effectiveAutoTypeSequence())) { QMessageBox::StandardButton reply; - reply = QMessageBox::question(0, - "AutoType", - tr("This AutoType command contains arguments which are repeated very often. Do you really want to execute it?")); + 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; } } _performAutoType(entry, hideWindow, customSequence, window); - } diff --git a/src/autotype/AutoType.h b/src/autotype/AutoType.h index 8aff7a94..9c3685b5 100644 --- a/src/autotype/AutoType.h +++ b/src/autotype/AutoType.h @@ -34,21 +34,25 @@ class AutoType : public QObject { Q_OBJECT - public: QStringList windowTitles(); - void _performAutoType(const Entry* entry, QWidget* hideWindow = nullptr, - const QString& customSequence = QString(), WId window = 0); + void _performAutoType(const Entry* entry, + QWidget* hideWindow = nullptr, + const QString& customSequence = QString(), + WId window = 0); bool registerGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers); void unregisterGlobalShortcut(); int callEventFilter(void* event); - static bool checkSyntax(const QString &string); - static bool checkHighRepetition(const QString &string); - static bool checkHighDelay(const QString &string); - void performAutoType(const Entry *entry, QWidget *hideWindow = nullptr, - const QString &customSequence = QString(), WId window = 0); + static bool checkSyntax(const QString& string); + static bool checkHighRepetition(const QString& string); + static bool checkHighDelay(const QString& string); + void performAutoType(const Entry* entry, + QWidget* hideWindow = nullptr, + const QString& customSequence = QString(), + WId window = 0); - inline bool isAvailable() { + inline bool isAvailable() + { return m_plugin; } @@ -91,7 +95,8 @@ private: Q_DISABLE_COPY(AutoType) }; -inline AutoType* autoType() { +inline AutoType* autoType() +{ return AutoType::instance(); } From 203960b4b51837e1a73edb8f00794b1ae0778ed7 Mon Sep 17 00:00:00 2001 From: thez3ro Date: Thu, 30 Nov 2017 15:11:24 +0100 Subject: [PATCH 16/18] rename to executeAutoType --- src/autotype/AutoType.cpp | 4 ++-- src/autotype/AutoType.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index 556dc2de..fc098afd 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -128,7 +128,7 @@ QStringList AutoType::windowTitles() return m_plugin->windowTitles(); } -void AutoType::_performAutoType(const Entry* entry, QWidget* hideWindow, const QString& customSequence, WId window) +void AutoType::executeAutoType(const Entry* entry, QWidget* hideWindow, const QString& customSequence, WId window) { if (m_inAutoType || !m_plugin) { return; @@ -677,5 +677,5 @@ void AutoType::performAutoType(const Entry* entry, QWidget* hideWindow, const QS return; } } - _performAutoType(entry, hideWindow, customSequence, window); + executeAutoType(entry, hideWindow, customSequence, window); } diff --git a/src/autotype/AutoType.h b/src/autotype/AutoType.h index 9c3685b5..f800ab1e 100644 --- a/src/autotype/AutoType.h +++ b/src/autotype/AutoType.h @@ -36,7 +36,7 @@ class AutoType : public QObject public: QStringList windowTitles(); - void _performAutoType(const Entry* entry, + void executeAutoType(const Entry* entry, QWidget* hideWindow = nullptr, const QString& customSequence = QString(), WId window = 0); From e8030760632f224a85c6b9c19ff890d2811847ee Mon Sep 17 00:00:00 2001 From: thez3ro Date: Thu, 28 Dec 2017 14:12:17 +0100 Subject: [PATCH 17/18] improve regex filtering --- src/autotype/AutoType.cpp | 121 ++++++++++++++++++------------ src/autotype/AutoType.h | 4 +- src/gui/entry/EditEntryWidget.cpp | 33 +------- tests/TestAutoType.cpp | 12 +++ 4 files changed, 88 insertions(+), 82 deletions(-) diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index fc098afd..a3d8b053 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -20,8 +20,7 @@ #include #include -#include -#include +#include #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 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(); } +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) { - if (!AutoType::checkSyntax(entry->effectiveAutoTypeSequence())) { - QMessageBox messageBox; - messageBox.critical(0, tr("AutoType"), tr("The Syntax of your AutoType statement is incorrect!")); - 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; - } + 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 f800ab1e..eb366ae9 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 fdb8aa14..2c65d3ec 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 d1c09c26..da245d8c 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}")); From 6d046f251ef214c11b8794604d7eebd82ccfa4b7 Mon Sep 17 00:00:00 2001 From: thez3ro Date: Sat, 30 Dec 2017 14:16:18 +0100 Subject: [PATCH 18/18] Remove minus since it's an invalid literal --- src/autotype/AutoType.cpp | 2 +- src/gui/entry/EditEntryWidget.cpp | 1 - tests/TestAutoType.cpp | 6 +++++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index a3d8b053..2df3b4f1 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -616,7 +616,7 @@ bool AutoType::checkSyntax(const QString& string) // 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 specialLiterals = "[\\^\\%\\(\\)~\\{\\}\\[\\]\\+]" + allowRepetition; QString functionKeys = "(?:F[1-9]" + allowRepetition + "|F1[0-2])" + allowRepetition; QString numpad = "NUMPAD\\d" + allowRepetition; QString delay = "DELAY=\\d+"; diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp index 2c65d3ec..707d2f6d 100644 --- a/src/gui/entry/EditEntryWidget.cpp +++ b/src/gui/entry/EditEntryWidget.cpp @@ -31,7 +31,6 @@ #include #include #include -#include #include "autotype/AutoType.h" #include "core/Config.h" diff --git a/tests/TestAutoType.cpp b/tests/TestAutoType.cpp index da245d8c..2f980e54 100644 --- a/tests/TestAutoType.cpp +++ b/tests/TestAutoType.cpp @@ -286,7 +286,7 @@ void TestAutoType::testGlobalAutoTypeRegExp() void TestAutoType::testAutoTypeSyntaxChecks() { // 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}{+}{SUBTRACT}~+%@fixedstring")); QCOMPARE(true, AutoType::checkSyntax("{NUMPAD1 3}")); @@ -298,6 +298,10 @@ void TestAutoType::testAutoTypeSyntaxChecks() QCOMPARE(true, AutoType::checkSyntax("{VKEY-EX 0x01}")); // Bad sequence QCOMPARE(false, AutoType::checkSyntax("{{{}}{}{}}{{}}")); + // Good sequence + QCOMPARE(true, AutoType::checkSyntax("{{}{}}{}}{{}")); + QCOMPARE(true, AutoType::checkSyntax("{]}{[}{[}{]}")); + QCOMPARE(true, AutoType::checkSyntax("{)}{(}{(}{)}")); // High DelAY / low delay QCOMPARE(true, AutoType::checkHighDelay("{DelAY 50000}")); QCOMPARE(false, AutoType::checkHighDelay("{delay 50}"));