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)

Reply via email to