[Filter] Allow spaces around the colon in search queries (#7529)

* [Filter] Allow spaces around the colon in search queries

* [Filter] Keep whitespace out of the color-identity operator

Allowing `ws?` between `color` and the identity marker made `c i: g`
parse as identity green, changing the meaning of text that previously
read as a generic `c` plus a field query on `i`. Whitespace belongs
around the separator, not inside an operator token: `ci : g` and
`ci: g` stay valid, `c i: g` keeps its old parse.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
BruebachL 2026-10-20 21:20:10 +02:00 • committed by GitHub
parent 9709fe4a1a
commit 9980c90cea
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 42 additions and 8 deletions

View file

@ -99,6 +99,17 @@ QUERY(SetCodeWrongSet2, doctor, "set:cat", false)
QUERY(BracketNextToUnquotedString, cat, "(o:woof OR o:meow)", true)
// Spaces around the colon are optional for all field queries (e.g. "o: flying")
QUERY(OracleSpaceAfterColon, cat, "o: meow", true)
QUERY(OracleSpaceBeforeColon, cat, "o :meow", true)
QUERY(OracleSpacesAroundColon, cat, "o : meow", true)
QUERY(OracleSpaceAfterColonNoMatch, cat, "o: woof", false)
QUERY(TypeSpaceAfterColon, cat, "t: creature", true)
QUERY(FieldSpaceAfterColon, cat, "pt: \"3/3\"", true)
QUERY(ColorSpaceAfterColon, cat, "c: g", true)
QUERY(ColorSpaceBeforeOperator, cat, "c !g", true)
QUERY(SetSpaceAfterColon, cat, "set: cat", true)
CardInfoPtr localizedCat()
{
CardInfoPtr localized = CardInfo::newInstance("Cat", "Meow!", false, {}, {}, {}, {}, {});
@ -107,6 +118,22 @@ CardInfoPtr localizedCat()
return localized;
}
CardInfoPtr greenIdentityCard()
{
return CardInfo::newInstance("Identity Cat", "", false, {{"colors", "G"}, {"coloridentity", "G"}}, {}, {}, {}, {});
}
// Whitespace belongs around the separator, never inside an operator token: "c i: g" must not
// be read as the color-identity operator "ci" (it is a generic "c" AND a field query on "i").
TEST_F(CardQuery, ColorIdentityOperatorIsNotSplitByWhitespace)
{
const CardData identityCard = greenIdentityCard();
ASSERT_TRUE(FilterString("ci:g").check(identityCard));
ASSERT_TRUE(FilterString("ci: g").check(identityCard));
ASSERT_TRUE(FilterString("ci : g").check(identityCard));
ASSERT_FALSE(FilterString("c i: g").check(identityCard));
}
TEST_F(CardQuery, SearchLanguageEnglishMatchesOnlyEnglish)
{
const CardData localized = localizedCat();
@ -136,6 +163,13 @@ TEST_F(CardQuery, SearchLanguageBothMatchesEitherLanguage)
ASSERT_TRUE(FilterString("Kater", CardSearchLanguage{"de", SearchLanguageMode::Both}).check(localized));
}
TEST_F(CardQuery, SearchLanguageBothMatchesOracleTextWithSpaceAfterColon)
{
const CardData localized = localizedCat();
ASSERT_TRUE(FilterString("o: Meow", CardSearchLanguage{"de", SearchLanguageMode::Both}).check(localized));
ASSERT_TRUE(FilterString("o: miaut", CardSearchLanguage{"de", SearchLanguageMode::Both}).check(localized));
}
TEST_F(CardQuery, SearchLanguageIsBoundPerInstance)
{
const CardData localized = localizedCat();