From: Zbigniew Jędrzejewski-Szmek Date: Sun, 25 Mar 2018 20:43:43 +0000 (+0200) Subject: tree-wide: add bsearch_safe and use where appropriate X-Git-Tag: v239~470^2~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d6c5d19b66d61d9ca8293b31aaefe310ae691d30;p=thirdparty%2Fsystemd.git tree-wide: add bsearch_safe and use where appropriate Should fix #8557. --- diff --git a/src/basic/strbuf.c b/src/basic/strbuf.c index bc3e56cf71b..b1b1af9cd48 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 6f8d8bef34e..19e9eae1262 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 f579ef737ef..6b450b4bb11 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 dc3ae7484df..caa0a92335b 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;