in source/mqtt.c [18:78]
static bool s_is_valid_topic(const struct aws_byte_cursor *topic, bool is_filter) {
/* [MQTT-4.7.3-1] Check existance and length */
if (!topic->ptr || !topic->len) {
return false;
}
/* [MQTT-4.7.3-2] Check for the null character */
if (memchr(topic->ptr, 0, topic->len)) {
return false;
}
/* [MQTT-4.7.3-3] Topic must not be too long */
if (topic->len > 65535) {
return false;
}
bool saw_hash = false;
struct aws_byte_cursor topic_part;
AWS_ZERO_STRUCT(topic_part);
while (aws_byte_cursor_next_split(topic, '/', &topic_part)) {
if (saw_hash) {
/* [MQTT-4.7.1-2] If last part was a '#' and there's still another part, it's an invalid topic */
return false;
}
if (topic_part.len == 0) {
/* 0 length parts are fine */
continue;
}
/* Check single level wildcard */
if (memchr(topic_part.ptr, '+', topic_part.len)) {
if (!is_filter) {
/* [MQTT-4.7.1-3] + only allowed on filters */
return false;
}
if (topic_part.len > 1) {
/* topic part must be 1 character long */
return false;
}
}
/* Check multi level wildcard */
if (memchr(topic_part.ptr, '#', topic_part.len)) {
if (!is_filter) {
/* [MQTT-4.7.1-2] # only allowed on filters */
return false;
}
if (topic_part.len > 1) {
/* topic part must be 1 character long */
return false;
}
saw_hash = true;
}
}
return true;
}