Module Name: src Committed By: roy Date: Mon Apr 1 11:39:15 UTC 2019
Modified Files: src/lib/libcurses: curses_private.h delwin.c newwin.c printw.c Log Message: printw: rework vw_printw so it uses open_memstream rather than funopen2 This makes it more portable as open_memstream is POSIX and fixes a potential issue with wide characters not fully being printed due to any buffer overflow. To generate a diff of this commit: cvs rdiff -u -r1.68 -r1.69 src/lib/libcurses/curses_private.h cvs rdiff -u -r1.20 -r1.21 src/lib/libcurses/delwin.c cvs rdiff -u -r1.54 -r1.55 src/lib/libcurses/newwin.c cvs rdiff -u -r1.26 -r1.27 src/lib/libcurses/printw.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/libcurses/curses_private.h diff -u src/lib/libcurses/curses_private.h:1.68 src/lib/libcurses/curses_private.h:1.69 --- src/lib/libcurses/curses_private.h:1.68 Fri Nov 16 10:12:00 2018 +++ src/lib/libcurses/curses_private.h Mon Apr 1 11:39:15 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: curses_private.h,v 1.68 2018/11/16 10:12:00 blymn Exp $ */ +/* $NetBSD: curses_private.h,v 1.69 2019/04/01 11:39:15 roy Exp $ */ /*- * Copyright (c) 1998-2000 Brett Lymn @@ -151,6 +151,8 @@ struct __window { /* Window structure. nschar_t *bnsp; /* Background non-spacing char list */ #endif /* HAVE_WCHAR */ FILE *fp; /* for window formatted printf */ + char *buf; /* buffer for window formatted printf */ + size_t buflen; /* length of above buffer */ }; /* Set of attributes unset by 'me' - 'mb', 'md', 'mh', 'mk', 'mp' and 'mr'. */ Index: src/lib/libcurses/delwin.c diff -u src/lib/libcurses/delwin.c:1.20 src/lib/libcurses/delwin.c:1.21 --- src/lib/libcurses/delwin.c:1.20 Fri Jan 6 13:53:18 2017 +++ src/lib/libcurses/delwin.c Mon Apr 1 11:39:15 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: delwin.c,v 1.20 2017/01/06 13:53:18 roy Exp $ */ +/* $NetBSD: delwin.c,v 1.21 2019/04/01 11:39:15 roy Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)delwin.c 8.2 (Berkeley) 5/4/94"; #else -__RCSID("$NetBSD: delwin.c,v 1.20 2017/01/06 13:53:18 roy Exp $"); +__RCSID("$NetBSD: delwin.c,v 1.21 2019/04/01 11:39:15 roy Exp $"); #endif #endif /* not lint */ @@ -114,6 +114,7 @@ delwin(WINDOW *win) _cursesi_screen->__virtscr = NULL; if (win->fp) fclose(win->fp); + free(win->buf); free(win); return OK; } Index: src/lib/libcurses/newwin.c diff -u src/lib/libcurses/newwin.c:1.54 src/lib/libcurses/newwin.c:1.55 --- src/lib/libcurses/newwin.c:1.54 Wed Oct 10 09:40:11 2018 +++ src/lib/libcurses/newwin.c Mon Apr 1 11:39:15 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: newwin.c,v 1.54 2018/10/10 09:40:11 roy Exp $ */ +/* $NetBSD: newwin.c,v 1.55 2019/04/01 11:39:15 roy Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)newwin.c 8.3 (Berkeley) 7/27/94"; #else -__RCSID("$NetBSD: newwin.c,v 1.54 2018/10/10 09:40:11 roy Exp $"); +__RCSID("$NetBSD: newwin.c,v 1.55 2019/04/01 11:39:15 roy Exp $"); #endif #endif /* not lint */ @@ -303,6 +303,8 @@ __makenew(SCREEN *screen, int nlines, in __CTRACE(__CTRACE_WINDOW, "makenew: win = %p\n", win); #endif win->fp = NULL; + win->buf = NULL; + win->buflen = 0; /* Set up line pointer array and line space. */ if ((win->alines = malloc(nlines * sizeof(__LINE *))) == NULL) { Index: src/lib/libcurses/printw.c diff -u src/lib/libcurses/printw.c:1.26 src/lib/libcurses/printw.c:1.27 --- src/lib/libcurses/printw.c:1.26 Thu Mar 28 23:24:22 2019 +++ src/lib/libcurses/printw.c Mon Apr 1 11:39:15 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: printw.c,v 1.26 2019/03/28 23:24:22 uwe Exp $ */ +/* $NetBSD: printw.c,v 1.27 2019/04/01 11:39:15 roy Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)printw.c 8.3 (Berkeley) 5/4/94"; #else -__RCSID("$NetBSD: printw.c,v 1.26 2019/03/28 23:24:22 uwe Exp $"); +__RCSID("$NetBSD: printw.c,v 1.27 2019/04/01 11:39:15 roy Exp $"); #endif #endif /* not lint */ @@ -110,22 +110,7 @@ mvwprintw(WINDOW * win, int y, int x, co va_end(ap); return ret; } -/* - * Internal write-buffer-to-window function. - */ -static ssize_t -winwrite(void *cookie, const void *vbuf, size_t n) -{ - WINDOW *win = cookie; - const char *buf = vbuf; - int status; - - status = waddnstr(win, buf, n); - if (status == ERR) - return -1; - return (ssize_t)n; -} /* * vw_printw -- * This routine actually executes the printf and adds it to the window. @@ -133,14 +118,23 @@ winwrite(void *cookie, const void *vbuf, int vw_printw(WINDOW *win, const char *fmt, va_list ap) { + int n; + if (win->fp == NULL) { - win->fp = funopen2(win, NULL, winwrite, NULL, NULL, NULL); - if (win->fp == NULL) + win->fp = open_memstream(&win->buf, &win->buflen); + if (__predict_false(win->fp == NULL)) return ERR; - } - vfprintf(win->fp, fmt, ap); - fflush(win->fp); - return OK; + } else + rewind(win->fp); + + n = vfprintf(win->fp, fmt, ap); + if (__predict_false(n == 0)) + return OK; + if (__predict_false(n == -1)) + return ERR; + if (__predict_false(fflush(win->fp) != 0)) + return ERR; + return waddnstr(win, win->buf, n); } __strong_alias(vwprintw, vw_printw)