Skip to content

Commit

Permalink
printw: rework vw_printw so it uses open_memstream rather than funopen2
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
rsmarples authored and rofl0r committed Apr 2, 2019
1 parent 5815ef5 commit 31f12fd
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 25 deletions.
4 changes: 3 additions & 1 deletion libcurses/curses_private.h
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -152,6 +152,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'. */
Expand Down
3 changes: 2 additions & 1 deletion libcurses/delwin.c
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -107,6 +107,7 @@ delwin(WINDOW *win)
_cursesi_screen->__virtscr = NULL;
if (win->fp)
fclose(win->fp);
free(win->buf);
free(win);
return OK;
}
4 changes: 3 additions & 1 deletion libcurses/newwin.c
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -296,6 +296,8 @@ __makenew(SCREEN *screen, int nlines, int ncols, int by, int bx, int sub,
__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) {
Expand Down
38 changes: 16 additions & 22 deletions libcurses/printw.c
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -103,37 +103,31 @@ mvwprintw(WINDOW * win, int y, int x, const char *fmt,...)
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.
*/
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)
Expand Down

0 comments on commit 31f12fd

Please sign in to comment.