/* Copyright (c) 2009-2018 Roger Light All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 and Eclipse Distribution License v1.0 which accompany this distribution. The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License is available at http://www.eclipse.org/org/documents/edl-v10.php. Contributors: Roger Light - initial implementation and documentation. */ #include "config.h" #include #include #ifdef WIN32 # include # include # include # include #else # include #endif #ifdef WITH_BROKER #include "mosquitto_broker_internal.h" #endif #include "mosquitto.h" #include "memory_mosq.h" #include "net_mosq.h" #include "send_mosq.h" #include "time_mosq.h" #include "tls_mosq.h" #include "util_mosq.h" /* Check that a topic used for publishing is valid. * Search for + or # in a topic. Return MOSQ_ERR_INVAL if found. * Also returns MOSQ_ERR_INVAL if the topic string is too long. * Returns MOSQ_ERR_SUCCESS if everything is fine. */ int mosquitto_pub_topic_check(const char *str) { int len = 0; while(str && str[0]){ if(str[0] == '+' || str[0] == '#'){ return MOSQ_ERR_INVAL; } len++; str = &str[1]; } if(len > 65535) return MOSQ_ERR_INVAL; return MOSQ_ERR_SUCCESS; } int mosquitto_pub_topic_check2(const char *str, size_t len) { int i; if(len > 65535) return MOSQ_ERR_INVAL; for(i=0; i 65535) return MOSQ_ERR_INVAL; return MOSQ_ERR_SUCCESS; } int mosquitto_sub_topic_check2(const char *str, size_t len) { char c = '\0'; int i; if(len > 65535) return MOSQ_ERR_INVAL; for(i=0; i 0 && sub[spos-1] != '/'){ return MOSQ_ERR_INVAL; } /* Check for bad "foo+" or "foo+/a" subscription */ if(spos < sublen-1 && sub[spos+1] != '/'){ return MOSQ_ERR_INVAL; } spos++; while(tpos < topiclen && topic[tpos] != '/'){ tpos++; } if(tpos == topiclen && spos == sublen){ *result = true; return MOSQ_ERR_SUCCESS; } }else if(sub[spos] == '#'){ if(spos > 0 && sub[spos-1] != '/'){ return MOSQ_ERR_INVAL; } multilevel_wildcard = true; if(spos+1 != sublen){ return MOSQ_ERR_INVAL; }else{ *result = true; return MOSQ_ERR_SUCCESS; } }else{ /* Check for e.g. foo/bar matching foo/+/# */ if(spos > 0 && spos+2 == sublen && tpos == topiclen && sub[spos-1] == '+' && sub[spos] == '/' && sub[spos+1] == '#') { *result = true; multilevel_wildcard = true; return MOSQ_ERR_SUCCESS; } return MOSQ_ERR_SUCCESS; } }else{ if(tpos == topiclen-1){ /* Check for e.g. foo matching foo/# */ if(spos == sublen-3 && sub[spos+1] == '/' && sub[spos+2] == '#'){ *result = true; multilevel_wildcard = true; return MOSQ_ERR_SUCCESS; } } spos++; tpos++; if(spos == sublen && tpos == topiclen){ *result = true; return MOSQ_ERR_SUCCESS; }else if(tpos == topiclen && spos == sublen-1 && sub[spos] == '+'){ if(spos > 0 && sub[spos-1] != '/'){ return MOSQ_ERR_INVAL; } spos++; *result = true; return MOSQ_ERR_SUCCESS; } } } if(multilevel_wildcard == false && (tpos < topiclen || spos < sublen)){ *result = false; } return MOSQ_ERR_SUCCESS; }