Fix topic matching edge case.

Thanks to Tobias Assarsson.
This commit is contained in:
Roger Light 2014-05-08 22:56:16 +01:00
parent b8e34b0b05
commit 9ff56eefd0
3 changed files with 16 additions and 10 deletions

View File

@ -4,6 +4,9 @@
Broker: Broker:
- Ensure that bridges verify certificates by default when using TLS. - Ensure that bridges verify certificates by default when using TLS.
Client library:
- Fix topic matching edge case.
1.3.1 - 20140324 1.3.1 - 20140324
================ ================

View File

@ -216,6 +216,16 @@ int mosquitto_topic_matches_sub(const char *sub, const char *topic, bool *result
while(spos < slen && tpos < tlen){ while(spos < slen && tpos < tlen){
if(sub[spos] == topic[tpos]){ if(sub[spos] == topic[tpos]){
if(tpos == tlen-1){
/* Check for e.g. foo matching foo/# */
if(spos == slen-3
&& sub[spos+1] == '/'
&& sub[spos+2] == '#'){
*result = true;
multilevel_wildcard = true;
return MOSQ_ERR_SUCCESS;
}
}
spos++; spos++;
tpos++; tpos++;
if(spos == slen && tpos == tlen){ if(spos == slen && tpos == tlen){
@ -250,16 +260,6 @@ int mosquitto_topic_matches_sub(const char *sub, const char *topic, bool *result
return MOSQ_ERR_SUCCESS; return MOSQ_ERR_SUCCESS;
} }
} }
if(tpos == tlen-1){
/* Check for e.g. foo matching foo/# */
if(spos == slen-3
&& sub[spos+1] == '/'
&& sub[spos+2] == '#'){
*result = true;
multilevel_wildcard = true;
return MOSQ_ERR_SUCCESS;
}
}
} }
if(multilevel_wildcard == false && (tpos < tlen || spos < slen)){ if(multilevel_wildcard == false && (tpos < tlen || spos < slen)){
*result = false; *result = false;

View File

@ -16,10 +16,13 @@ void do_check(const char *sub, const char *topic, bool bad_res)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
do_check("test/6/#", "test/3", true);
do_check("foo/bar", "foo/bar", false); do_check("foo/bar", "foo/bar", false);
do_check("foo/+", "foo/bar", false); do_check("foo/+", "foo/bar", false);
do_check("foo/+/baz", "foo/bar/baz", false); do_check("foo/+/baz", "foo/bar/baz", false);
do_check("A/B/+/#", "A/B/B/C", false);
do_check("foo/+/#", "foo/bar/baz", false); do_check("foo/+/#", "foo/bar/baz", false);
do_check("#", "foo/bar/baz", false); do_check("#", "foo/bar/baz", false);