tree-wide: add bsearch_safe and use where appropriate
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sun, 25 Mar 2018 20:43:43 +0000 (22:43 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 26 Mar 2018 13:28:03 +0000 (15:28 +0200)
Should fix #8557.

src/basic/strbuf.c
src/basic/util.h
src/hwdb/hwdb.c
src/udev/udevadm-hwdb.c

index bc3e56c..b1b1af9 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "alloc-util.h"
 #include "strbuf.h"
+#include "util.h"
 
 /*
  * Strbuf stores given strings in a single continuous allocated memory
@@ -144,7 +145,6 @@ ssize_t strbuf_add_string(struct strbuf *str, const char *s, size_t len) {
         str->in_len += len;
 
         node = str->root;
-        c = s[len-1];
         for (depth = 0; depth <= len; depth++) {
                 struct strbuf_child_entry search;
 
@@ -158,15 +158,11 @@ ssize_t strbuf_add_string(struct strbuf *str, const char *s, size_t len) {
 
                 c = s[len - 1 - depth];
 
-                /* bsearch is not allowed on a NULL sequence */
-                if (node->children_count == 0)
-                        break;
-
                 /* lookup child node */
                 search.c = c;
-                child = bsearch(&search, node->children, node->children_count,
-                                sizeof(struct strbuf_child_entry),
-                                (__compar_fn_t) strbuf_children_cmp);
+                child = bsearch_safe(&search, node->children, node->children_count,
+                                     sizeof(struct strbuf_child_entry),
+                                     (__compar_fn_t) strbuf_children_cmp);
                 if (!child)
                         break;
                 node = child->child;
index 6f8d8be..19e9eae 100644 (file)
@@ -92,6 +92,19 @@ void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
                  void *arg);
 
 /**
+ * Normal bsearch requires base to be nonnull. Here were require
+ * that only if nmemb > 0.
+ */
+static inline void* bsearch_safe(const void *key, const void *base,
+                                 size_t nmemb, size_t size, comparison_fn_t compar) {
+        if (nmemb <= 0)
+                return NULL;
+
+        assert(base);
+        return bsearch(key, base, nmemb, size, compar);
+}
+
+/**
  * Normal qsort requires base to be nonnull. Here were require
  * that only if nmemb > 0.
  */
index f579ef7..6b450b4 100644 (file)
@@ -123,7 +123,7 @@ static struct trie_node *node_lookup(const struct trie_node *node, uint8_t c) {
         struct trie_child_entry search;
 
         search.c = c;
-        child = bsearch(&search, node->children, node->children_count, sizeof(struct trie_child_entry), trie_children_cmp);
+        child = bsearch_safe(&search, node->children, node->children_count, sizeof(struct trie_child_entry), trie_children_cmp);
         if (child)
                 return child->child;
         return NULL;
index dc3ae74..caa0a92 100644 (file)
@@ -114,7 +114,9 @@ static struct trie_node *node_lookup(const struct trie_node *node, uint8_t c) {
         struct trie_child_entry search;
 
         search.c = c;
-        child = bsearch(&search, node->children, node->children_count, sizeof(struct trie_child_entry), trie_children_cmp);
+        child = bsearch_safe(&search,
+                             node->children, node->children_count, sizeof(struct trie_child_entry),
+                             trie_children_cmp);
         if (child)
                 return child->child;
         return NULL;