fix(glob): Correctly match longer strings with '*' or '**' pattern (#5001)

* fix(glob): Correctly match longer strings with '*' or '**' pattern

If string is longer than 16 chars we are using reflex library for
matching. When used pattern is '*' or '**' we are going to remove
trailing and leading star and have empty pattern. We should, in this,
edge case set manually star pattern.

Fixes #4948

Signed-off-by: mkaruza <mario@dragonflydb.io>

* Core matching test

---------

Signed-off-by: mkaruza <mario@dragonflydb.io>
This commit is contained in:
mkaruza 2025-04-28 11:54:54 +02:00 committed by GitHub
parent 23e6db900d
commit 98fb8fb38f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 23 additions and 1 deletions

View file

@ -155,6 +155,7 @@ TEST_F(StringMatchTest, Basic) {
// Wildcards
EXPECT_EQ(MatchLen("*", "hello", 0), 1);
EXPECT_EQ(MatchLen("*", "1234567890123456", 0), 1);
EXPECT_EQ(MatchLen("h*", "hello", 0), 1);
EXPECT_EQ(MatchLen("h*", "abc", 0), 0);
EXPECT_EQ(MatchLen("h*o", "hello", 0), 1);

View file

@ -236,7 +236,11 @@ GlobMatcher::GlobMatcher(string_view pattern, bool case_sensitive)
regex.push_back('i');
}
regex.push_back(')');
regex.append(Glob2Regex(pattern));
if (pattern.empty()) {
regex.append(Glob2Regex("*"));
} else {
regex.append(Glob2Regex(pattern));
}
matcher_.pattern(regex);
#elif USE_PCRE2
string regex("(?s"); // dotall mode

View file

@ -548,6 +548,23 @@ TEST_F(DflyEngineTest, PSubscribe) {
EXPECT_EQ("a*", msg.pattern);
}
TEST_F(DflyEngineTest, PSubscribeMatchOnlyStar) {
single_response_ = false;
auto resp = pp_->at(1)->Await([&] { return Run({"psubscribe", "*"}); });
EXPECT_THAT(resp, ArrLen(3));
resp = pp_->at(0)->Await([&] { return Run({"PUBLISH", "1234567890123456", "abc"}); });
EXPECT_THAT(resp, IntArg(1));
pp_->AwaitFiberOnAll([](ProactorBase* pb) {});
ASSERT_EQ(1, SubscriberMessagesLen("IO1"));
const auto& msg = GetPublishedMessage("IO1", 0);
EXPECT_EQ("abc", msg.message);
EXPECT_EQ("1234567890123456", msg.channel);
EXPECT_EQ("*", msg.pattern);
}
TEST_F(DflyEngineTest, Unsubscribe) {
auto resp = Run({"unsubscribe", "a"});
EXPECT_THAT(resp.GetVec(), ElementsAre("unsubscribe", "a", IntArg(0)));