Module Name: src Committed By: snj Date: Mon Dec 12 07:37:53 UTC 2016
Modified Files: src/lib/libterminfo [netbsd-7]: curterm.c term.c termcap.c terminfo.3 tparm.c Log Message: Pull up following revision(s) (requested by riastradh in ticket #1307): lib/libterminfo/curterm.c: revisions 1.11, 1.12 lib/libterminfo/term.c: revisions 1.18-1.20 lib/libterminfo/termcap.c: revisions 1.18, 1.19 lib/libterminfo/terminfo.3: revision 1.13 lib/libterminfo/tparm.c: revision 1.16 terminfo.3: fix ti_puts prototype -- PR/50092: Fix memory leak. -- PR/50092: Rin Okuyama: Fix memory leak. -- We have the max length; use snprintf. -- >From PR/50092: - handle calling _ti_readterm with an existing initialized terminal - simplify free code Also: - fix an inconsistency in userdefs count computation -- Always copy the area buffer, even when the length was the same (from Rin Okuyama) -- - if we are freeing cur_term, set it to NULL. - preserve and free "last" properly. -- off-by-one in memcpy. Found by ASAN (Carsten Kunze) To generate a diff of this commit: cvs rdiff -u -r1.10 -r1.10.4.1 src/lib/libterminfo/curterm.c cvs rdiff -u -r1.17 -r1.17.6.1 src/lib/libterminfo/term.c cvs rdiff -u -r1.17 -r1.17.18.1 src/lib/libterminfo/termcap.c cvs rdiff -u -r1.12 -r1.12.4.1 src/lib/libterminfo/terminfo.3 cvs rdiff -u -r1.15 -r1.15.6.1 src/lib/libterminfo/tparm.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libterminfo/curterm.c diff -u src/lib/libterminfo/curterm.c:1.10 src/lib/libterminfo/curterm.c:1.10.4.1 --- src/lib/libterminfo/curterm.c:1.10 Mon Nov 18 20:51:03 2013 +++ src/lib/libterminfo/curterm.c Mon Dec 12 07:37:53 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: curterm.c,v 1.10 2013/11/18 20:51:03 joerg Exp $ */ +/* $NetBSD: curterm.c,v 1.10.4.1 2016/12/12 07:37:53 snj Exp $ */ /* * Copyright (c) 2009, 2011 The NetBSD Foundation, Inc. @@ -28,7 +28,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: curterm.c,v 1.10 2013/11/18 20:51:03 joerg Exp $"); +__RCSID("$NetBSD: curterm.c,v 1.10.4.1 2016/12/12 07:37:53 snj Exp $"); #include <assert.h> #include <stdlib.h> @@ -139,7 +139,10 @@ del_curterm(TERMINAL *oterm) free(oterm->nums); free(oterm->flags); free(oterm->_userdefs); + free(oterm->_buf); free(oterm); + if (oterm == cur_term) + cur_term = NULL; return OK; } Index: src/lib/libterminfo/term.c diff -u src/lib/libterminfo/term.c:1.17 src/lib/libterminfo/term.c:1.17.6.1 --- src/lib/libterminfo/term.c:1.17 Fri Jun 7 13:16:18 2013 +++ src/lib/libterminfo/term.c Mon Dec 12 07:37:53 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: term.c,v 1.17 2013/06/07 13:16:18 roy Exp $ */ +/* $NetBSD: term.c,v 1.17.6.1 2016/12/12 07:37:53 snj Exp $ */ /* * Copyright (c) 2009, 2010, 2011 The NetBSD Foundation, Inc. @@ -28,7 +28,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: term.c,v 1.17 2013/06/07 13:16:18 roy Exp $"); +__RCSID("$NetBSD: term.c,v 1.17.6.1 2016/12/12 07:37:53 snj Exp $"); #include <sys/stat.h> @@ -54,6 +54,23 @@ const char *_ti_database; #include "compiled_terms.c" static int +allocset(void *pp, int init, size_t nelem, size_t elemsize) +{ + void **p = pp; + if (*p) { + memset(*p, init, nelem * elemsize); + return 0; + } + + if ((*p = calloc(nelem, elemsize)) == NULL) + return -1; + + if (init != 0) + memset(*p, init, nelem * elemsize); + return 0; +} + +static int _ti_readterm(TERMINAL *term, const char *cap, size_t caplen, int flags) { uint8_t ver; @@ -61,27 +78,30 @@ _ti_readterm(TERMINAL *term, const char size_t len; TERMUSERDEF *ud; + if (caplen == 0) + goto out; ver = *cap++; + caplen--; /* Only read version 1 structures */ - if (ver != 1) { - errno = EINVAL; - return -1; - } + if (ver != 1) + goto out; - term->flags = calloc(TIFLAGMAX + 1, sizeof(char)); - if (term->flags == NULL) - return -1; - term->nums = malloc((TINUMMAX + 1) * sizeof(short)); - if (term->nums == NULL) + + if (allocset(&term->flags, 0, TIFLAGMAX + 1, sizeof(*term->flags)) == -1) return -1; - memset(term->nums, (short)-1, (TINUMMAX + 1) * sizeof(short)); - term->strs = calloc(TISTRMAX + 1, sizeof(char *)); - if (term->strs == NULL) + + if (allocset(&term->nums, -1, TINUMMAX + 1, sizeof(*term->nums)) == -1) return -1; - term->_arealen = caplen; - term->_area = malloc(term->_arealen); - if (term->_area == NULL) + + if (allocset(&term->strs, 0, TISTRMAX + 1, sizeof(*term->strs)) == -1) return -1; + + if (term->_arealen != caplen) { + term->_arealen = caplen; + term->_area = realloc(term->_area, term->_arealen); + if (term->_area == NULL) + return -1; + } memcpy(term->_area, cap, term->_arealen); cap = term->_area; @@ -158,9 +178,16 @@ _ti_readterm(TERMINAL *term, const char num = le16dec(cap); cap += sizeof(uint16_t); if (num != 0) { - term->_nuserdefs = le16dec(cap); - term->_userdefs = malloc(sizeof(*term->_userdefs) * num); + num = le16dec(cap); cap += sizeof(uint16_t); + if (num != term->_nuserdefs) { + free(term->_userdefs); + term->_userdefs = NULL; + term->_nuserdefs = num; + } + if (allocset(&term->_userdefs, 0, term->_nuserdefs, + sizeof(*term->_userdefs)) == -1) + return -1; for (num = 0; num < term->_nuserdefs; num++) { ud = &term->_userdefs[num]; len = le16dec(cap); @@ -200,12 +227,21 @@ _ti_readterm(TERMINAL *term, const char cap += len; break; default: - errno = EINVAL; - return -1; + goto out; } } + } else { + term->_nuserdefs = 0; + if (term->_userdefs) { + free(term->_userdefs); + term->_userdefs = NULL; + } } + return 1; +out: + errno = EINVAL; + return -1; } static int @@ -350,13 +386,13 @@ _ti_findterm(TERMINAL *term, const char if (e != NULL) { if (c == NULL) e = strdup(e); /* So we don't destroy env */ - if (e == NULL) + if (e == NULL) tic = NULL; - else + else { tic = _ti_compile(e, TIC_WARNING | TIC_ALIAS | TIC_DESCRIPTION | TIC_EXTRA); - if (c == NULL && e != NULL) free(e); + } if (tic != NULL && ticcmp(tic, name) == 0) { len = _ti_flatten(&f, tic); if (len != -1) { Index: src/lib/libterminfo/termcap.c diff -u src/lib/libterminfo/termcap.c:1.17 src/lib/libterminfo/termcap.c:1.17.18.1 --- src/lib/libterminfo/termcap.c:1.17 Sun Nov 13 15:24:04 2011 +++ src/lib/libterminfo/termcap.c Mon Dec 12 07:37:53 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: termcap.c,v 1.17 2011/11/13 15:24:04 christos Exp $ */ +/* $NetBSD: termcap.c,v 1.17.18.1 2016/12/12 07:37:53 snj Exp $ */ /* * Copyright (c) 2009 The NetBSD Foundation, Inc. @@ -28,7 +28,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: termcap.c,v 1.17 2011/11/13 15:24:04 christos Exp $"); +__RCSID("$NetBSD: termcap.c,v 1.17.18.1 2016/12/12 07:37:53 snj Exp $"); #include <assert.h> #include <ctype.h> @@ -57,14 +57,17 @@ tgetent(__unused char *bp, const char *n _DIAGASSERT(name != NULL); /* Free the old term */ - if (last != NULL) { - del_curterm(last); - last = NULL; + if (cur_term != NULL) { + if (last != NULL && cur_term != last) + del_curterm(last); + last = cur_term; } errret = -1; if (setupterm(name, STDOUT_FILENO, &errret) != 0) return errret; - last = cur_term; + + if (last == NULL) + last = cur_term; if (pad_char != NULL) PC = pad_char[0]; @@ -553,8 +556,11 @@ captoinfo(char *cap) else len += rl; p = realloc(info, len); - if (p == NULL) + if (p == NULL) { + if (fv == 1) + free(val); return NULL; + } info = p; } Index: src/lib/libterminfo/terminfo.3 diff -u src/lib/libterminfo/terminfo.3:1.12 src/lib/libterminfo/terminfo.3:1.12.4.1 --- src/lib/libterminfo/terminfo.3:1.12 Tue Mar 18 18:20:38 2014 +++ src/lib/libterminfo/terminfo.3 Mon Dec 12 07:37:53 2016 @@ -1,4 +1,4 @@ -.\" $NetBSD: terminfo.3,v 1.12 2014/03/18 18:20:38 riastradh Exp $ +.\" $NetBSD: terminfo.3,v 1.12.4.1 2016/12/12 07:37:53 snj Exp $ .\" .\" Copyright (c) 2009, 2011 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -27,7 +27,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd January 25, 2013 +.Dd November 23, 2015 .Dt TERMINFO 3 .Os .Sh NAME @@ -85,7 +85,7 @@ .Ft char * .Fn ti_tiparm "TERMINAL *" "const char *cm" "..." .Ft int -.Fn ti_puts "const TERMINAL *term" "const char *str" "int affcnt" "int (*outc)(int, void *)" +.Fn ti_puts "const TERMINAL *term" "const char *str" "int affcnt" "int (*outc)(int ch, void *arg)" "void *arg" .Ft int .Fn ti_putp "const TERMINAL *term" "const char *str" .Sh DESCRIPTION Index: src/lib/libterminfo/tparm.c diff -u src/lib/libterminfo/tparm.c:1.15 src/lib/libterminfo/tparm.c:1.15.6.1 --- src/lib/libterminfo/tparm.c:1.15 Fri Jun 7 13:16:18 2013 +++ src/lib/libterminfo/tparm.c Mon Dec 12 07:37:53 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: tparm.c,v 1.15 2013/06/07 13:16:18 roy Exp $ */ +/* $NetBSD: tparm.c,v 1.15.6.1 2016/12/12 07:37:53 snj Exp $ */ /* * Copyright (c) 2009, 2011, 2013 The NetBSD Foundation, Inc. @@ -28,7 +28,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: tparm.c,v 1.15 2013/06/07 13:16:18 roy Exp $"); +__RCSID("$NetBSD: tparm.c,v 1.15.6.1 2016/12/12 07:37:53 snj Exp $"); #include <sys/param.h> #include <assert.h> @@ -130,7 +130,7 @@ onum(TERMINAL *term, const char *fmt, in len = LONG_STR_MAX; if (checkbuf(term, len + 2) == NULL) return 0; - l = sprintf(term->_buf + term->_bufpos, fmt, num); + l = snprintf(term->_buf + term->_bufpos, len + 2, fmt, num); term->_bufpos += l; return l; } @@ -342,7 +342,7 @@ _ti_tiparm(TERMINAL *term, const char *s l = olen; if (checkbuf(term, (size_t)(l + 1)) == NULL) return NULL; - l = sprintf(term->_buf + term->_bufpos, + l = snprintf(term->_buf + term->_bufpos, l + 1, fmt, ostr); term->_bufpos += l; }