[670] Fix topic matching of foo/bar against foo/+/#

Thanks to mrdis.

Bug: https://github.com/eclipse/mosquitto/issues/670
This commit is contained in:
Roger A. Light 2018-01-09 14:36:19 +00:00
parent 254f30cdb1
commit b02c1a41bb
3 changed files with 46 additions and 27 deletions

View File

@ -18,6 +18,8 @@ Client library:
- Initialise "result" variable as soon as possible in
mosquitto_topic_matches_sub. Closes #654.
- No need to close socket again if setting non-blocking failed. Closes #649.
- Fix mosquitto_topic_matches_sub() not correctly matching foo/bar against
foo/+/#. Closes #670.
Build:
- Don't run TLS-PSK tests if TLS-PSK disabled at compile time. Closes #636.

View File

@ -308,6 +308,18 @@ int mosquitto_topic_matches_sub(const char *sub, const char *topic, bool *result
return MOSQ_ERR_SUCCESS;
}
}else{
/* Check for e.g. foo/bar matching foo/+/# */
if(spos > 0
&& spos+2 == slen
&& tpos == tlen
&& sub[spos-1] == '+'
&& sub[spos] == '/'
&& sub[spos+1] == '#')
{
*result = true;
multilevel_wildcard = true;
return MOSQ_ERR_SUCCESS;
}
return MOSQ_ERR_SUCCESS;
}
}

View File

@ -2,6 +2,9 @@
#include <stdlib.h>
#include <mosquitto.h>
#define EXPECT_MATCH(A, B) do_check((A), (B), false)
#define EXPECT_NOMATCH(A, B) do_check((A), (B), true)
void do_check(const char *sub, const char *topic, bool bad_res)
{
bool match;
@ -16,42 +19,44 @@ void do_check(const char *sub, const char *topic, bool bad_res)
int main(int argc, char *argv[])
{
do_check("foo/#", "foo/", false);
do_check("foo#", "foo", true);
do_check("fo#o/", "foo", true);
do_check("foo#", "fooa", true);
do_check("foo+", "foo", true);
do_check("foo+", "fooa", true);
EXPECT_MATCH("foo/#", "foo/");
EXPECT_NOMATCH("foo#", "foo");
EXPECT_NOMATCH("fo#o/", "foo");
EXPECT_NOMATCH("foo#", "fooa");
EXPECT_NOMATCH("foo+", "foo");
EXPECT_NOMATCH("foo+", "fooa");
do_check("test/6/#", "test/3", true);
do_check("foo/bar", "foo/bar", false);
do_check("foo/+", "foo/bar", false);
do_check("foo/+/baz", "foo/bar/baz", false);
EXPECT_NOMATCH("test/6/#", "test/3");
EXPECT_MATCH("foo/bar", "foo/bar");
EXPECT_MATCH("foo/+", "foo/bar");
EXPECT_MATCH("foo/+/baz", "foo/bar/baz");
do_check("A/B/+/#", "A/B/B/C", false);
EXPECT_MATCH("A/B/+/#", "A/B/B/C");
do_check("foo/+/#", "foo/bar/baz", false);
do_check("#", "foo/bar/baz", false);
EXPECT_MATCH("foo/+/#", "foo/bar/baz");
EXPECT_MATCH("foo/+/#", "foo/bar");
EXPECT_MATCH("#", "foo/bar/baz");
EXPECT_MATCH("#", "foo/bar/baz");
do_check("foo/bar", "foo", true);
do_check("foo/+", "foo/bar/baz", true);
do_check("foo/+/baz", "foo/bar/bar", true);
EXPECT_NOMATCH("foo/bar", "foo");
EXPECT_NOMATCH("foo/+", "foo/bar/baz");
EXPECT_NOMATCH("foo/+/baz", "foo/bar/bar");
do_check("foo/+/#", "fo2/bar/baz", true);
EXPECT_NOMATCH("foo/+/#", "fo2/bar/baz");
do_check("#", "/foo/bar", false);
do_check("/#", "/foo/bar", false);
do_check("/#", "foo/bar", true);
EXPECT_MATCH("#", "/foo/bar");
EXPECT_MATCH("/#", "/foo/bar");
EXPECT_NOMATCH("/#", "foo/bar");
do_check("foo//bar", "foo//bar", false);
do_check("foo//+", "foo//bar", false);
do_check("foo/+/+/baz", "foo///baz", false);
do_check("foo/bar/+", "foo/bar/", false);
EXPECT_MATCH("foo//bar", "foo//bar");
EXPECT_MATCH("foo//+", "foo//bar");
EXPECT_MATCH("foo/+/+/baz", "foo///baz");
EXPECT_MATCH("foo/bar/+", "foo/bar/");
do_check("$SYS/bar", "$SYS/bar", false);
do_check("#", "$SYS/bar", true);
do_check("$BOB/bar", "$SYS/bar", true);
EXPECT_MATCH("$SYS/bar", "$SYS/bar");
EXPECT_NOMATCH("#", "$SYS/bar");
EXPECT_NOMATCH("$BOB/bar", "$SYS/bar");
return 0;
}