Skip to content

Reject quotes that can't produce a valid Gmail query - #471

Merged
mbrt merged 2 commits into
masterfrom
bug/66
Sep 28, 2026
Merged

mbrt merged 2 commits into
masterfrom
bug/66

Conversation

@mbrt

@mbrt mbrt commented Sep 28, 2026 •

Copy link
Copy Markdown
Owner

Gmail's search syntax has no way to escape a double quote, so a " inside a value can only be valid as a pair around the whole value, e.g. subject: '"hello world"'. Since bc6bb81 such values are passed through unchanged, which fixed the example originally reported in #66. Any other quote still produced a malformed query without warning:

subject: 'say "hi" now'       ->  subject:"say "hi" now"
subject: '"unbalanced start'  ->  subject:""unbalanced start"
from: 'foo"bar'               ->  from:foo"bar
has: '"exact phrase" other'   ->  ""exact phrase" other"

The pass-through check also only looked at the first and last characters, so '"foo" OR "bar"' was treated as a single phrase. Nested in a larger query it rendered as subject:"foo" OR "bar", where "bar" matches anywhere in the message, not only in the subject.

A similar check was added in #260 and reverted in #299, because it rejected every quote, including values wrapped as a whole, which users rely on to force an exact match (e.g. to: '"foo+bar"'). Those keep working: the new check only rejects values that already generated broken queries. Configs containing them will now fail to apply until fixed, which is intended, but worth a release note.

gmailctl test also treated the quotes around a phrase as literal text, so rules like subject: '"hello world"' or to: '"foo+bar"' failed their own tests, even though Gmail matches them. The evaluators now strip those quotes before matching.

BREAKING CHANGE: Configs containing broken quotes now stop working (with an error). Even though these were already not doing what users intended, technically speaking, this is a breaking change.

Close #66.

Gmail's search syntax has no way to escape a double quote, so a `"`
inside a value can only be valid as a pair around the whole value,
e.g. subject: '"hello world"'. Since bc6bb81 such values are passed
through unchanged, which fixed the example originally reported in #66.
Any other quote still produced a malformed query without warning:

    subject: 'say "hi" now'       ->  subject:"say "hi" now"
    subject: '"unbalanced start'  ->  subject:""unbalanced start"
    from: 'foo"bar'               ->  from:foo"bar
    has: '"exact phrase" other'   ->  ""exact phrase" other"

The pass-through check also only looked at the first and last
characters, so '"foo" OR "bar"' was treated as a single phrase. Nested
in a larger query it rendered as `subject:"foo" OR "bar"`, where "bar"
matches anywhere in the message, not only in the subject.

Make quote() accept a quote only when the value is exactly one quoted
phrase (the new filter.IsQuoted), and fail otherwise, with a note on
how to fix the config: remove the quotes (they are added automatically
when needed), or write raw Gmail syntax with `isEscaped: true` or
`query`, which are not checked.

A similar check was added in #260 and reverted in #299, because it
rejected every quote, including values wrapped as a whole, which users
rely on to force an exact match (e.g. to: '"foo+bar"'). Those keep
working: the new check only rejects values that already generated
broken queries. Configs containing them will now fail to apply until
fixed, which is intended, but worth a release note.

`gmailctl test` also treated the quotes around a phrase as literal
text, so rules like subject: '"hello world"' or to: '"foo+bar"' failed
their own tests, even though Gmail matches them. The evaluators now
strip those quotes before matching, using the same IsQuoted check.

Close #66.
@mbrt mbrt added kind/bug Something isn't working breaking-change A change in the configuration format labels Sep 28, 2026
@codecov

codecov Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 42.26%. Comparing base (9cf4f0b) to head (7f2cbb1).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #471      +/-   ##
==========================================
+ Coverage   41.94%   42.26%   +0.32%     
==========================================
  Files          54       54              
  Lines        3710     3724      +14     
==========================================
+ Hits         1556     1574      +18     
+ Misses       2053     2049       -4     
  Partials      101      101              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@mbrt
mbrt merged commit 80e6d25 into master Sep 28, 2026
5 checks passed
@mbrt
mbrt deleted the bug/66 branch September 28, 2026 07:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking-change A change in the configuration format kind/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Subject (and possibly other rules) with quotes

1 participant