Hello tech@, Attached a patch to remove the binc function from vi and replace it with recallocarray. The functions effectively do the same thing since BINC_{GOTO,RET} already do the nlen > llen comparison. I've run this without any issues, but since recallocarray does extra checks and binc ALWAYS allocates A LOT more than requested there might be some bugs lurking.
I haven't changed the name since the size component is always one and hence they don't expose a similar interface. OK? martijn@ Index: common/mem.h =================================================================== RCS file: /cvs/src/usr.bin/vi/common/mem.h,v retrieving revision 1.9 diff -u -p -r1.9 mem.h --- common/mem.h 7 May 2016 14:03:01 -0000 1.9 +++ common/mem.h 22 Jun 2017 19:02:28 -0000 @@ -14,30 +14,30 @@ /* Increase the size of a malloc'd buffer. Two versions, one that * returns, one that jumps to an error label. */ -#define BINC_GOTO(sp, lp, llen, nlen) { \ - void *L__bincp; \ +#define BINC_GOTO(sp, p, llen, nlen) { \ + void *tmpp; \ if ((nlen) > (llen)) { \ - if ((L__bincp = binc((sp), (lp), &(llen), (nlen))) \ - == NULL) \ + if (((tmpp) = recallocarray((p), (llen), (nlen), 1)) \ + == NULL) { \ + msgq((sp), M_SYSERR, NULL); \ + free(p); \ goto alloc_err; \ - /* \ - * !!! \ - * Possible pointer conversion. \ - */ \ - (lp) = L__bincp; \ + } \ + llen = nlen; \ + (p) = tmpp; \ } \ } -#define BINC_RET(sp, lp, llen, nlen) { \ - void *L__bincp; \ +#define BINC_RET(sp, p, llen, nlen) { \ + void *tmpp; \ if ((nlen) > (llen)) { \ - if ((L__bincp = binc((sp), (lp), &(llen), (nlen))) \ - == NULL) \ + if (((tmpp) = recallocarray((p), (llen), (nlen), 1)) \ + == NULL) { \ + msgq((sp), M_SYSERR, NULL); \ + free(p); \ return (1); \ - /* \ - * !!! \ - * Possible pointer conversion. \ - */ \ - (lp) = L__bincp; \ + } \ + llen = nlen; \ + (p) = tmpp; \ } \ } Index: common/util.c =================================================================== RCS file: /cvs/src/usr.bin/vi/common/util.c,v retrieving revision 1.15 diff -u -p -r1.15 util.c --- common/util.c 27 May 2016 09:18:11 -0000 1.15 +++ common/util.c 22 Jun 2017 19:02:28 -0000 @@ -24,43 +24,6 @@ #include "common.h" -#define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b)) - -/* - * binc -- - * Increase the size of a buffer. - * - * PUBLIC: void *binc(SCR *, void *, size_t *, size_t); - */ -void * -binc(SCR *sp, void *bp, size_t *bsizep, size_t min) -{ - size_t csize; - - /* If already larger than the minimum, just return. */ - if (min && *bsizep >= min) - return (bp); - - csize = *bsizep + MAXIMUM(min, 256); - REALLOC(sp, bp, csize); - - if (bp == NULL) { - /* - * Theoretically, realloc is supposed to leave any already - * held memory alone if it can't get more. Don't trust it. - */ - *bsizep = 0; - return (NULL); - } - /* - * Memory is guaranteed to be zero-filled, various parts of - * nvi depend on this. - */ - memset((char *)bp + *bsizep, 0, csize - *bsizep); - *bsizep = csize; - return (bp); -} - /* * nonblank -- * Set the column number of the first non-blank character Index: include/com_extern.h =================================================================== RCS file: /cvs/src/usr.bin/vi/include/com_extern.h,v retrieving revision 1.14 diff -u -p -r1.14 com_extern.h --- include/com_extern.h 27 May 2016 09:18:12 -0000 1.14 +++ include/com_extern.h 22 Jun 2017 19:02:28 -0000 @@ -103,7 +103,6 @@ void seq_close(GS *); int seq_dump(SCR *, seq_t, int); int seq_save(SCR *, FILE *, char *, seq_t); int e_memcmp(CHAR_T *, EVENT *, size_t); -void *binc(SCR *, void *, size_t *, size_t); int nonblank(SCR *, recno_t, size_t *); CHAR_T *v_strdup(SCR *, const CHAR_T *, size_t); enum nresult nget_uslong(u_long *, const char *, char **, int);