]> git.cameronkatri.com Git - mandoc.git/commitdiff
Merge from OpenBSD - Marc Espie improved the ohash interface:
authorIngo Schwarze <schwarze@openbsd.org>
Fri, 20 Jun 2014 02:24:40 +0000 (02:24 +0000)
committerIngo Schwarze <schwarze@openbsd.org>
Fri, 20 Jun 2014 02:24:40 +0000 (02:24 +0000)
* rename the halloc callback to calloc, provide overflow protection
* rename the hfree callback to free, drop the useless size argument
* prevent integer overflows in ohash_resize

compat_ohash.c
compat_ohash.h
mandocdb.c
mansearch.c

index 33c57afcb06be90c9d5ecda02bbe8b20936e2481..0992b3657dde5e76424c891a87c0607e1b527545 100644 (file)
@@ -29,6 +29,7 @@ int dummy;
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
+#include <limits.h>
 #include "compat_ohash.h"
 
 struct _ohash_record {
 #include "compat_ohash.h"
 
 struct _ohash_record {
@@ -69,8 +70,7 @@ ohash_create_entry(struct ohash_info *i, const char *start, const char **end)
 void
 ohash_delete(struct ohash *h)
 {
 void
 ohash_delete(struct ohash *h)
 {
-       (h->info.hfree)(h->t, sizeof(struct _ohash_record) * h->size,
-               h->info.data);
+       (h->info.free)(h->t, h->info.data);
 #ifndef NDEBUG
        h->t = NULL;
 #endif
 #ifndef NDEBUG
        h->t = NULL;
 #endif
@@ -80,13 +80,17 @@ static void
 ohash_resize(struct ohash *h)
 {
        struct _ohash_record *n;
 ohash_resize(struct ohash *h)
 {
        struct _ohash_record *n;
-       unsigned int    ns, j;
+       size_t ns;
+       unsigned int    j;
        unsigned int    i, incr;
 
        unsigned int    i, incr;
 
-       if (4 * h->deleted < h->total)
-               ns = h->size << 1;
-       else if (3 * h->deleted > 2 * h->total)
-               ns = h->size >> 1;
+       if (4 * h->deleted < h->total) {
+               if (h->size >= (UINT_MAX >> 1U))
+                       ns = UINT_MAX;
+               else
+                       ns = h->size << 1U;
+       } else if (3 * h->deleted > 2 * h->total)
+               ns = h->size >> 1U;
        else
                ns = h->size;
        if (ns < MINSIZE)
        else
                ns = h->size;
        if (ns < MINSIZE)
@@ -95,7 +99,8 @@ ohash_resize(struct ohash *h)
        STAT_HASH_EXPAND++;
        STAT_HASH_SIZE += ns - h->size;
 #endif
        STAT_HASH_EXPAND++;
        STAT_HASH_SIZE += ns - h->size;
 #endif
-       n = (h->info.halloc)(sizeof(struct _ohash_record) * ns, h->info.data);
+
+       n = (h->info.calloc)(ns, sizeof(struct _ohash_record), h->info.data);
        if (!n)
                return;
 
        if (!n)
                return;
 
@@ -112,8 +117,7 @@ ohash_resize(struct ohash *h)
                        n[i].p = h->t[j].p;
                }
        }
                        n[i].p = h->t[j].p;
                }
        }
-       (h->info.hfree)(h->t, sizeof(struct _ohash_record) * h->size, 
-               h->info.data);
+       (h->info.free)(h->t, h->info.data);
        h->t = n;
        h->size = ns;
        h->total -= h->deleted;
        h->t = n;
        h->size = ns;
        h->total -= h->deleted;
@@ -199,12 +203,12 @@ ohash_init(struct ohash *h, unsigned int size, struct ohash_info *info)
 #endif
        /* Copy info so that caller may free it.  */
        h->info.key_offset = info->key_offset;
 #endif
        /* Copy info so that caller may free it.  */
        h->info.key_offset = info->key_offset;
-       h->info.halloc = info->halloc;
-       h->info.hfree = info->hfree;
+       h->info.calloc = info->calloc;
+       h->info.free = info->free;
        h->info.alloc = info->alloc;
        h->info.data = info->data;
        h->info.alloc = info->alloc;
        h->info.data = info->data;
-       h->t = (h->info.halloc)(sizeof(struct _ohash_record) * h->size,
-           h->info.data);
+       h->t = (h->info.calloc)(h->size, sizeof(struct _ohash_record),
+                   h->info.data);
        h->total = h->deleted = 0;
 }
 
        h->total = h->deleted = 0;
 }
 
index d07df18e646c408d0248d61bef6d4c1ceb08e840..c5f81ec0ed10b9e97680db45ece7c26e5acbab67 100644 (file)
@@ -27,8 +27,8 @@
 struct ohash_info {
        ptrdiff_t key_offset;
        void *data;     /* user data */
 struct ohash_info {
        ptrdiff_t key_offset;
        void *data;     /* user data */
-       void *(*halloc)(size_t, void *);
-       void (*hfree)(void *, size_t, void *);
+       void *(*calloc)(size_t, size_t, void *);
+       void (*free)(void *, void *);
        void *(*alloc)(size_t, void *);
 };
 
        void *(*alloc)(size_t, void *);
 };
 
index 4066025ada65c008400fa91eac2f88752f742ebb..930133ccfdf55d762227c5817cd72afb257c2458 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mandocdb.c,v 1.151 2014/06/20 01:21:48 schwarze Exp $ */
+/*     $Id: mandocdb.c,v 1.152 2014/06/20 02:24:40 schwarze Exp $ */
 /*
  * Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
 /*
  * Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -145,8 +145,8 @@ static      int      dbopen(int);
 static void     dbprune(void);
 static void     filescan(const char *);
 static void    *hash_alloc(size_t, void *);
 static void     dbprune(void);
 static void     filescan(const char *);
 static void    *hash_alloc(size_t, void *);
-static void     hash_free(void *, size_t, void *);
-static void    *hash_halloc(size_t, void *);
+static void     hash_free(void *, void *);
+static void    *hash_calloc(size_t, size_t, void *);
 static void     mlink_add(struct mlink *, const struct stat *);
 static void     mlink_check(struct mpage *, struct mlink *);
 static void     mlink_free(struct mlink *);
 static void     mlink_add(struct mlink *, const struct stat *);
 static void     mlink_check(struct mpage *, struct mlink *);
 static void     mlink_free(struct mlink *);
@@ -336,8 +336,8 @@ main(int argc, char *argv[])
        memset(&dirs, 0, sizeof(struct manpaths));
 
        mpages_info.alloc  = mlinks_info.alloc  = hash_alloc;
        memset(&dirs, 0, sizeof(struct manpaths));
 
        mpages_info.alloc  = mlinks_info.alloc  = hash_alloc;
-       mpages_info.halloc = mlinks_info.halloc = hash_halloc;
-       mpages_info.hfree  = mlinks_info.hfree  = hash_free;
+       mpages_info.calloc = mlinks_info.calloc = hash_calloc;
+       mpages_info.free  = mlinks_info.free  = hash_free;
 
        mpages_info.key_offset = offsetof(struct mpage, inodev);
        mlinks_info.key_offset = offsetof(struct mlink, file);
 
        mpages_info.key_offset = offsetof(struct mpage, inodev);
        mlinks_info.key_offset = offsetof(struct mlink, file);
@@ -1088,8 +1088,8 @@ mpages_merge(struct mchars *mc, struct mparse *mp)
        enum mandoclevel         lvl;
 
        str_info.alloc = hash_alloc;
        enum mandoclevel         lvl;
 
        str_info.alloc = hash_alloc;
-       str_info.halloc = hash_halloc;
-       str_info.hfree = hash_free;
+       str_info.calloc = hash_calloc;
+       str_info.free = hash_free;
        str_info.key_offset = offsetof(struct str, key);
 
        if (0 == nodb)
        str_info.key_offset = offsetof(struct str, key);
 
        if (0 == nodb)
@@ -2348,10 +2348,10 @@ prepare_statements:
 }
 
 static void *
 }
 
 static void *
-hash_halloc(size_t sz, void *arg)
+hash_calloc(size_t n, size_t sz, void *arg)
 {
 
 {
 
-       return(mandoc_calloc(1, sz));
+       return(mandoc_calloc(n, sz));
 }
 
 static void *
 }
 
 static void *
@@ -2362,7 +2362,7 @@ hash_alloc(size_t sz, void *arg)
 }
 
 static void
 }
 
 static void
-hash_free(void *p, size_t sz, void *arg)
+hash_free(void *p, void *arg)
 {
 
        free(p);
 {
 
        free(p);
index f9892218fb6f3da292eef02c37c34ac7e917f5ae..7f554b27df794ab1fb7d6780f47aee0873b3ebd0 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mansearch.c,v 1.36 2014/04/23 21:06:41 schwarze Exp $ */
+/*     $Id: mansearch.c,v 1.37 2014/06/20 02:24:40 schwarze Exp $ */
 /*
  * Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
 /*
  * Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -85,8 +85,8 @@ static        void             buildnames(struct manpage *, sqlite3 *,
 static char            *buildoutput(sqlite3 *, sqlite3_stmt *,
                                 uint64_t, uint64_t);
 static void            *hash_alloc(size_t, void *);
 static char            *buildoutput(sqlite3 *, sqlite3_stmt *,
                                 uint64_t, uint64_t);
 static void            *hash_alloc(size_t, void *);
-static void             hash_free(void *, size_t, void *);
-static void            *hash_halloc(size_t, void *);
+static void             hash_free(void *, void *);
+static void            *hash_calloc(size_t, size_t, void *);
 static struct expr     *exprcomp(const struct mansearch *,
                                int, char *[]);
 static void             exprfree(struct expr *);
 static struct expr     *exprcomp(const struct mansearch *,
                                int, char *[]);
 static void             exprfree(struct expr *);
@@ -171,11 +171,9 @@ mansearch(const struct mansearch *search,
        unsigned int     idx;
        size_t           i, j, cur, maxres;
 
        unsigned int     idx;
        size_t           i, j, cur, maxres;
 
-       memset(&info, 0, sizeof(struct ohash_info));
-
-       info.halloc = hash_halloc;
+       info.calloc = hash_calloc;
        info.alloc = hash_alloc;
        info.alloc = hash_alloc;
-       info.hfree = hash_free;
+       info.free = hash_free;
        info.key_offset = offsetof(struct match, pageid);
 
        *sz = cur = maxres = 0;
        info.key_offset = offsetof(struct match, pageid);
 
        *sz = cur = maxres = 0;
@@ -790,10 +788,10 @@ exprfree(struct expr *p)
 }
 
 static void *
 }
 
 static void *
-hash_halloc(size_t sz, void *arg)
+hash_calloc(size_t nmemb, size_t sz, void *arg)
 {
 
 {
 
-       return(mandoc_calloc(1, sz));
+       return(mandoc_calloc(nmemb, sz));
 }
 
 static void *
 }
 
 static void *
@@ -804,7 +802,7 @@ hash_alloc(size_t sz, void *arg)
 }
 
 static void
 }
 
 static void
-hash_free(void *p, size_t sz, void *arg)
+hash_free(void *p, void *arg)
 {
 
        free(p);
 {
 
        free(p);