From 8f11ee4365170e345b82aa238307fb323b924167 Mon Sep 17 00:00:00 2001
From: "Roger A. Light" <roger@atchoo.org>
Date: Thu, 20 Sep 2018 15:02:15 +0100
Subject: CVE-2018-12543 Revert "Remove some test that was always true"

This reverts commit 6fc7cadb63477a438f56745872a2046ed7026fc4.
---
 src/subs.c | 67 ++++++++++++++++++++++++++++++++----------------------
 1 file changed, 40 insertions(+), 27 deletions(-)

diff --git a/src/subs.c b/src/subs.c
index 0716fe1..5953055 100644
--- a/src/subs.c
+++ b/src/subs.c
@@ -459,7 +459,15 @@ int sub__add(struct mosquitto_db *db, struct mosquitto *context, const char *sub
 	if(sub__topic_tokenise(sub, &tokens)) return 1;
 
 	HASH_FIND(hh, *root, UHPA_ACCESS_TOPIC(tokens), tokens->topic_len, subhier);
-	assert(subhier);
+	if(!subhier){
+		subhier = sub__add_hier_entry(NULL, root, UHPA_ACCESS_TOPIC(tokens), tokens->topic_len);
+		if(!subhier){
+			sub__topic_tokens_free(tokens);
+			log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
+			return MOSQ_ERR_NOMEM;
+		}
+
+	}
 	rc = sub__add_recurse(db, context, qos, subhier, tokens);
 
 	sub__topic_tokens_free(tokens);
@@ -481,8 +489,9 @@ int sub__remove(struct mosquitto_db *db, struct mosquitto *context, const char *
 	if(sub__topic_tokenise(sub, &tokens)) return 1;
 
 	HASH_FIND(hh, root, UHPA_ACCESS_TOPIC(tokens), tokens->topic_len, subhier);
-	assert(subhier);
-	rc = sub__remove_recurse(db, context, subhier, tokens);
+	if(subhier){
+		rc = sub__remove_recurse(db, context, subhier, tokens);
+	}
 
 	sub__topic_tokens_free(tokens);
 
@@ -507,14 +516,15 @@ int sub__messages_queue(struct mosquitto_db *db, const char *source_id, const ch
 	(*stored)->ref_count++;
 
 	HASH_FIND(hh, db->subs, UHPA_ACCESS_TOPIC(tokens), tokens->topic_len, subhier);
-	assert(subhier);
-	if(retain){
-		/* We have a message that needs to be retained, so ensure that the subscription
-		 * tree for its topic exists.
-		 */
-		sub__add_recurse(db, NULL, 0, subhier, tokens);
+	if(subhier){
+		if(retain){
+			/* We have a message that needs to be retained, so ensure that the subscription
+			 * tree for its topic exists.
+			 */
+			sub__add_recurse(db, NULL, 0, subhier, tokens);
+		}
+		sub__search(db, subhier, tokens, source_id, topic, qos, retain, *stored, true);
 	}
-	sub__search(db, subhier, tokens, source_id, topic, qos, retain, *stored, true);
 	sub__topic_tokens_free(tokens);
 
 	/* Remove our reference and free if needed. */
@@ -611,23 +621,25 @@ void sub__tree_print(struct mosquitto__subhier *root, int level)
 	struct mosquitto__subleaf *leaf;
 
 	HASH_ITER(hh, root, branch, branch_tmp){
-	for(i=0; i<(level+2)*2; i++){
-		printf(" ");
-	}
-	printf("%s", UHPA_ACCESS_TOPIC(branch));
-	leaf = branch->subs;
-	while(leaf){
-		if(leaf->context){
-			printf(" (%s, %d)", leaf->context->id, leaf->qos);
-		}else{
-			printf(" (%s, %d)", "", leaf->qos);
+	if(level > -1){
+		for(i=0; i<(level+2)*2; i++){
+			printf(" ");
 		}
-		leaf = leaf->next;
-	}
-	if(branch->retained){
-		printf(" (r)");
+		printf("%s", UHPA_ACCESS_TOPIC(branch));
+		leaf = branch->subs;
+		while(leaf){
+			if(leaf->context){
+				printf(" (%s, %d)", leaf->context->id, leaf->qos);
+			}else{
+				printf(" (%s, %d)", "", leaf->qos);
+			}
+			leaf = leaf->next;
+		}
+		if(branch->retained){
+			printf(" (r)");
+		}
+		printf("\n");
 	}
-	printf("\n");
 
 		sub__tree_print(branch->children, level+1);
 	}
@@ -715,9 +727,10 @@ int sub__retain_queue(struct mosquitto_db *db, struct mosquitto *context, const
 	if(sub__topic_tokenise(sub, &tokens)) return 1;
 
 	HASH_FIND(hh, db->subs, UHPA_ACCESS_TOPIC(tokens), tokens->topic_len, subhier);
-	assert(subhier);
 
-	retain__search(db, subhier, tokens, context, sub, sub_qos, 0);
+	if(subhier){
+		retain__search(db, subhier, tokens, context, sub, sub_qos, 0);
+	}
 	while(tokens){
 		tail = tokens->next;
 		UHPA_FREE_TOPIC(tokens);
-- 
2.17.1

