diff --git a/src/basic/strbuf.c b/src/basic/strbuf.c index bc3e56cf71..b1b1af9cd4 100644 --- a/src/basic/strbuf.c +++ b/src/basic/strbuf.c @@ -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; diff --git a/src/basic/util.h b/src/basic/util.h index 6f8d8bef34..19e9eae126 100644 --- a/src/basic/util.h +++ b/src/basic/util.h @@ -91,6 +91,19 @@ void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size, int (*compar) (const void *, const void *, void *), 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. diff --git a/src/hwdb/hwdb.c b/src/hwdb/hwdb.c index f579ef737e..6b450b4bb1 100644 --- a/src/hwdb/hwdb.c +++ b/src/hwdb/hwdb.c @@ -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; diff --git a/src/udev/udevadm-hwdb.c b/src/udev/udevadm-hwdb.c index dc3ae7484d..caa0a92335 100644 --- a/src/udev/udevadm-hwdb.c +++ b/src/udev/udevadm-hwdb.c @@ -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;