Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libcurses Fix for PR lib/55433
details: https://anonhg.NetBSD.org/src/rev/9a9f02f81994
branches: trunk
changeset: 1026257:9a9f02f81994
user: blymn <blymn%NetBSD.org@localhost>
date: Mon Nov 15 06:27:06 2021 +0000
description:
Fix for PR lib/55433
Correct the behaviour for ins_wstr:
* Properly check the string will fit by processing any special
characters present when preforming the check.
* Simplify the routine by removing code that duplicates the code in
_cursesi_addwchar and just call _cursesi_addwchar.
diffstat:
lib/libcurses/ins_wstr.c | 375 +++++++++++++++++++++++++++++-----------------
1 files changed, 232 insertions(+), 143 deletions(-)
diffs (truncated from 429 to 300 lines):
diff -r e57678fecaf1 -r 9a9f02f81994 lib/libcurses/ins_wstr.c
--- a/lib/libcurses/ins_wstr.c Sun Nov 14 21:18:30 2021 +0000
+++ b/lib/libcurses/ins_wstr.c Mon Nov 15 06:27:06 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ins_wstr.c,v 1.17 2021/09/06 07:45:48 rin Exp $ */
+/* $NetBSD: ins_wstr.c,v 1.18 2021/11/15 06:27:06 blymn Exp $ */
/*
* Copyright (c) 2005 The NetBSD Foundation Inc.
@@ -36,7 +36,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: ins_wstr.c,v 1.17 2021/09/06 07:45:48 rin Exp $");
+__RCSID("$NetBSD: ins_wstr.c,v 1.18 2021/11/15 06:27:06 blymn Exp $");
#endif /* not lint */
#include <string.h>
@@ -133,8 +133,9 @@
__LDATA *start, *temp1, *temp2;
__LINE *lnp;
const wchar_t *scp;
- int width, len, sx, x, y, cw, pcw, newx;
- nschar_t *np;
+ cchar_t cc;
+ wchar_t *lstr, *slstr;
+ int i, width, len, lx, sx, x, y, tx, ty, cw, pcw, newx, tn, w;
wchar_t ws[] = L" ";
/* check for leading non-spacing character */
@@ -146,171 +147,259 @@
if (!cw)
return ERR;
+ lstr = malloc(sizeof(wchar_t) * win->maxx);
+ if (lstr == NULL)
+ return ERR;
+
scp = wstr + 1;
width = cw;
len = 1;
n--;
+ y = win->cury;
+ x = win->curx;
+ tn = n;
+
+ /*
+ * Firstly, make sure the string will fit...
+ */
while (*scp) {
- int w;
- if (!n)
+ if (!tn)
break;
+ switch (*scp) {
+ case L'\b':
+ if (--x < 0)
+ x = 0;
+ cw = wcwidth(*(scp - 1));
+ if (cw < 0)
+ cw = 1;
+ width -= cw;
+ scp++;
+ continue;;
+
+ case L'\r':
+ width = 0;
+ x = 0;
+ scp++;
+ continue;
+
+ case L'\n':
+ if (y == win->scr_b) {
+ if (!(win->flags & __SCROLLOK)) {
+ free(lstr);
+ return ERR;
+ }
+ }
+ y++;
+ scp++;
+ continue;
+
+ case L'\t':
+ w = min(win->maxx - x, TABSIZE - (x % TABSIZE));
+ width += w * wcwidth(ws[0]);
+ x += w * wcwidth(ws[0]);
+ scp++;
+ continue;
+ }
w = wcwidth(*scp);
if (w < 0)
w = 1;
- n--, len++, width += w;
+ tn--, width += w;
scp++;
}
__CTRACE(__CTRACE_INPUT, "wins_nwstr: width=%d,len=%d\n", width, len);
- if (cw > win->maxx - win->curx + 1)
+ if (width > win->maxx - win->curx + 1) {
+ free(lstr);
return ERR;
- start = &win->alines[win->cury]->line[win->curx];
- sx = win->curx;
- lnp = win->alines[win->cury];
- pcw = WCOL(*start);
- if (pcw < 0) {
- sx += pcw;
- start += pcw;
- }
- __CTRACE(__CTRACE_INPUT, "wins_nwstr: start@(%d)\n", sx);
- pcw = WCOL(*start);
- lnp->flags |= __ISDIRTY;
- newx = sx + win->ch_off;
- if (newx < *lnp->firstchp)
- *lnp->firstchp = newx;
-#ifdef DEBUG
- {
- __CTRACE(__CTRACE_INPUT, "========before=======\n");
- for (x = 0; x < win->maxx; x++)
- __CTRACE(__CTRACE_INPUT,
- "wins_nwstr: (%d,%d)=(%x,%x,%p)\n",
- win->cury, x,
- win->alines[win->cury]->line[x].ch,
- win->alines[win->cury]->line[x].attr,
- win->alines[win->cury]->line[x].nsp);
- }
-#endif /* DEBUG */
-
- /* shift all complete characters */
- if (sx + width + pcw <= win->maxx) {
- __CTRACE(__CTRACE_INPUT, "wins_nwstr: shift all characters\n");
- temp1 = &win->alines[win->cury]->line[win->maxx - 1];
- temp2 = temp1 - width;
- pcw = WCOL(*(temp2 + 1));
- if (pcw < 0) {
- __CTRACE(__CTRACE_INPUT,
- "wins_nwstr: clear from %d to EOL(%d)\n",
- win->maxx + pcw, win->maxx - 1);
- temp2 += pcw;
- while (temp1 > temp2 + width) {
- temp1->ch = (wchar_t)btowc((int) win->bch);
- if (_cursesi_copy_nsp(win->bnsp, temp1) == ERR)
- return ERR;
- temp1->attr = win->battr;
- SET_WCOL(*temp1, 1);
- __CTRACE(__CTRACE_INPUT,
- "wins_nwstr: empty cell(%p)\n", temp1);
- temp1--;
- }
- }
- while (temp2 >= start) {
- (void)memcpy(temp1, temp2, sizeof(__LDATA));
- temp1--, temp2--;
- }
-#ifdef DEBUG
- {
- __CTRACE(__CTRACE_INPUT, "=====after shift====\n");
- for (x = 0; x < win->maxx; x++)
- __CTRACE(__CTRACE_INPUT,
- "wins_nwstr: (%d,%d)=(%x,%x,%p)\n",
- win->cury, x,
- win->alines[win->cury]->line[x].ch,
- win->alines[win->cury]->line[x].attr,
- win->alines[win->cury]->line[x].nsp);
- }
-#endif /* DEBUG */
}
- /* update string columns */
+ scp = wstr;
x = win->curx;
y = win->cury;
- for (scp = wstr, temp1 = start; len; len--, scp++) {
- switch (*scp) {
- case L'\b':
- if (--x < 0)
+ len = 0;
+ width = 0;
+ slstr = lstr;
+
+ while (*scp && n) {
+ lstr = slstr;
+ lx = x;
+ while (*scp) {
+ if (!n)
+ break;
+ switch (*scp) {
+ case L'\b':
+ if (--x < 0)
+ x = 0;
+ if (--len < 0)
+ len = 0;
+ cw = wcwidth(*(scp - 1));
+ if (cw < 0)
+ cw = 1;
+ width -= cw;
+ scp++;
+ if (lstr != slstr)
+ lstr--;
+ continue;;
+
+ case L'\r':
+ width = 0;
+ len = 0;
x = 0;
- win->curx = x;
- continue;;
- case L'\r':
- win->curx = 0;
- continue;
- case L'\n':
- wclrtoeol(win);
- if (y == win->scr_b) {
- if (!(win->flags & __SCROLLOK))
- return ERR;
- scroll(win);
- }
- continue;
- case L'\t':
- if (wins_nwstr(win, ws,
- min(win->maxx - x, TABSIZE - (x % TABSIZE)))
- == ERR)
- return ERR;
- continue;
+ scp++;
+ lstr = slstr;
+ continue;
+
+ case L'\n':
+ goto loopdone;
+ break;
+
+ case L'\t':
+ w = min(win->maxx - x,
+ TABSIZE - (x % TABSIZE));
+ width += w * wcwidth(ws[0]);
+ x += w * wcwidth(ws[0]);
+ len += w;
+ scp++;
+ for (i = 0; i < w; i++ ) {
+ *lstr = *ws;
+ lstr++;
+ }
+ continue;
+ }
+ w = wcwidth(*scp);
+ if (w < 0)
+ w = 1;
+ *lstr = *scp;
+ n--, len++, width += w;
+ scp++, lstr++;
}
- cw = wcwidth(*scp);
- if (cw < 0)
- cw = 1;
- if (cw) {
- /* 1st column */
- temp1->ch = (wchar_t)*scp;
- temp1->attr = win->wattr;
- SET_WCOL(*temp1, cw);
- temp1->nsp = NULL;
+
+loopdone:
+ start = &win->alines[y]->line[x];
+ sx = x;
+ lnp = win->alines[y];
+ pcw = WCOL(*start);
+ if (pcw < 0) {
+ sx += pcw;
+ start += pcw;
+ }
+ __CTRACE(__CTRACE_INPUT, "wins_nwstr: start@(%d)\n", sx);
+ pcw = WCOL(*start);
+ lnp->flags |= __ISDIRTY;
+ newx = sx + win->ch_off;
+ if (newx < *lnp->firstchp)
+ *lnp->firstchp = newx;
+#ifdef DEBUG
+ {
+ __CTRACE(__CTRACE_INPUT, "========before=======\n");
+ for (i = 0; i < win->maxx; i++)
__CTRACE(__CTRACE_INPUT,
- "wins_nwstr: add spacing char(%x)\n", temp1->ch);
- temp2 = temp1++;
- if (cw > 1) {
- x = -1;
- while (temp1 < temp2 + cw) {
- /* the rest columns */
- temp1->ch = (wchar_t)*scp;
- temp1->attr = win->wattr;
- temp1->nsp = NULL;
- SET_WCOL(*temp1, x);
- temp1++, x--;
+ "wins_nwstr: (%d,%d)=(%x,%x,%p)\n",
+ y, i, win->alines[y]->line[i].ch,
+ win->alines[y]->line[i].attr,
+ win->alines[y]->line[i].nsp);
+ }
+#endif /* DEBUG */
Home |
Main Index |
Thread Index |
Old Index