From d8d5ddcab64edd2740eff63362ef66a1144f4754 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Sun, 5 Jun 2022 21:56:48 -0400 Subject: [PATCH] Auto-Type: PICKCHARS can specify attribute and ignore BEEP * Fix #7726 - Ignore BEEP Auto-Type token when it includes spaces and numbers as well * Close #8103 - Allow specifying specific attribute to use with PICKCHARS. If none specified, it defaults to Password. --- share/translations/keepassxc_en.ts | 4 ++++ src/autotype/AutoType.cpp | 25 +++++++++++++++++++------ tests/TestAutoType.cpp | 2 +- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/share/translations/keepassxc_en.ts b/share/translations/keepassxc_en.ts index 4df6cef14..b8f34456c 100644 --- a/share/translations/keepassxc_en.ts +++ b/share/translations/keepassxc_en.ts @@ -644,6 +644,10 @@ Invalid placeholder: %1 + + Entry does not have attribute for PICKCHARS: %1 + + AutoTypeAssociationsModel diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index 57299fb66..750053955 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -647,13 +647,26 @@ AutoType::parseSequence(const QString& entrySequence, const Entry* entry, QStrin for (const auto& ch : totp) { actions << QSharedPointer::create(ch); } - } else if (placeholder == "pickchars") { - // Ignore this if we are syntax checking + } else if (placeholder.startsWith("pickchars")) { + // Reset to the original capture to preserve case + placeholder = match.captured(3); + + auto attribute = EntryAttributes::PasswordKey; + if (placeholder.contains(":")) { + attribute = placeholder.section(":", 1); + if (!entry->attributes()->hasKey(attribute)) { + error = tr("Entry does not have attribute for PICKCHARS: %1").arg(attribute); + return {}; + } + } + + // Bail out if we are just syntax checking if (syntaxOnly) { continue; } - // Show pickchars dialog for entry's password - auto password = entry->resolvePlaceholder(entry->password()); + + // Show pickchars dialog for the desired attribute + auto password = entry->resolvePlaceholder(entry->attribute(attribute)); if (!password.isEmpty()) { PickcharsDialog pickcharsDialog(password); if (pickcharsDialog.exec() == QDialog::Accepted && !pickcharsDialog.selectedChars().isEmpty()) { @@ -746,8 +759,8 @@ AutoType::parseSequence(const QString& entrySequence, const Entry* entry, QStrin mode = AutoTypeExecutor::Mode::VIRTUAL; } actions << QSharedPointer::create(mode); - } else if (placeholder == "beep" || placeholder.startsWith("vkey") || placeholder.startsWith("appactivate") - || placeholder.startsWith("c:")) { + } else if (placeholder.startsWith("beep") || placeholder.startsWith("vkey") + || placeholder.startsWith("appactivate") || placeholder.startsWith("c:")) { // Ignore these commands } else { // Attempt to resolve an entry attribute diff --git a/tests/TestAutoType.cpp b/tests/TestAutoType.cpp index 235ba5a86..445735f9f 100644 --- a/tests/TestAutoType.cpp +++ b/tests/TestAutoType.cpp @@ -337,7 +337,7 @@ void TestAutoType::testAutoTypeSyntaxChecks() QVERIFY2(AutoType::verifyAutoTypeSyntax("{S:FOO}{S:HELLO WORLD}", entry, error), error.toLatin1()); QVERIFY2(!AutoType::verifyAutoTypeSyntax("{S:SPECIAL_TOKEN{}}", entry, error), error.toLatin1()); - QVERIFY2(!AutoType::verifyAutoTypeSyntax("{BEEP 3 3}", entry, error), error.toLatin1()); + QVERIFY2(AutoType::verifyAutoTypeSyntax("{BEEP 3 3}", entry, error), error.toLatin1()); QVERIFY2(AutoType::verifyAutoTypeSyntax("{BEEP 3}", entry, error), error.toLatin1()); QVERIFY2(AutoType::verifyAutoTypeSyntax("{VKEY 0x01}", entry, error), error.toLatin1());