aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/searchterm.cpp11
-rw-r--r--src/searchterm.h5
2 files changed, 10 insertions, 6 deletions
diff --git a/src/searchterm.cpp b/src/searchterm.cpp
index 6bfb521..16936df 100644
--- a/src/searchterm.cpp
+++ b/src/searchterm.cpp
@@ -34,10 +34,13 @@ QString quote(const QString &value)
if (cleaned.size() > kMaxValueLength)
cleaned.truncate(kMaxValueLength);
- // Backslashes first: escaping the quotes first would then escape the
- // backslashes this step adds, doubling them.
- cleaned.replace(QLatin1Char('\\'), QStringLiteral("\\\\"));
- cleaned.replace(QLatin1Char('"'), QStringLiteral("\\\""));
+ // notmuch escapes a quote inside a quoted term by DOUBLING it and has no
+ // backslash escape at all. A backslash-escaped quote ENDS the term, so
+ // `subject:"x \" or tag:inbox or id:"` let a selection walk out of the
+ // query it was meant to narrow: measured matching every message under a
+ // `tag:nomatch and` scope, where the doubled form matched none. A
+ // backslash is literal to notmuch and is left as it is.
+ cleaned.replace(QLatin1Char('"'), QStringLiteral("\"\""));
return QLatin1Char('"') + cleaned + QLatin1Char('"');
}
diff --git a/src/searchterm.h b/src/searchterm.h
index 3a0cac2..8ca67e4 100644
--- a/src/searchterm.h
+++ b/src/searchterm.h
@@ -59,8 +59,9 @@ enum class SearchMode {
/// Quotes an arbitrary value for use as a notmuch term.
///
/// Whitespace and newlines collapse to single spaces, embedded quotes are
-/// escaped, the value is capped at kMaxValueLength, and an empty or
-/// whitespace-only value yields an EMPTY STRING rather than `""`. Callers
+/// doubled (notmuch has no backslash escape), the value is capped at
+/// kMaxValueLength, and an empty or whitespace-only value yields an EMPTY
+/// STRING rather than `""`. Callers
/// test for empty to decide whether to offer a menu entry at all.
QString quote(const QString &value);