-/* $OpenBSD: wsemul_vt100.c,v 1.42 2023/01/12 20:39:37 nicm Exp $ */
+/* $OpenBSD: wsemul_vt100.c,v 1.43 2023/02/26 15:09:53 miod Exp $ */
/* $NetBSD: wsemul_vt100.c,v 1.13 2000/04/28 21:56:16 mycroft Exp $ */
/*
edp->dblwid = NULL;
edp->dw = 0;
#endif
- edp->dcsarg = 0;
+ edp->dcsarg = NULL;
edp->isolatin1tab = edp->decgraphtab = edp->dectechtab = NULL;
edp->nrctab = NULL;
wsemul_vt100_reset(edp);
edp->sschartab = 3;
break;
case 'M': /* RI */
- if (ROWS_ABOVE > 0) {
- edp->crow--;
+ i = ROWS_ABOVE;
+ if (i > 0) {
+ if (edp->crow > 0)
+ edp->crow--;
CHECK_DW;
- break;
+ } else if (i == 0) {
+ /* Top of scroll region. */
+ rc = wsemul_vt100_scrolldown(edp, 1);
}
- rc = wsemul_vt100_scrolldown(edp, 1);
break;
case 'P': /* DCS */
edp->nargs = 0;
wsemul_vt100_output_string(struct wsemul_vt100_emuldata *edp,
struct wsemul_inputstate *instate)
{
- if (edp->dcstype && edp->dcspos < DCS_MAXLEN) {
+ if (edp->dcsarg && edp->dcstype && edp->dcspos < DCS_MAXLEN) {
if (instate->inchar & ~0xff) {
#ifdef VT100_PRINTUNKNOWN
printf("unknown char %x in DCS\n", instate->inchar);
-/* $OpenBSD: wsemul_vt100_subr.c,v 1.29 2023/01/12 20:39:37 nicm Exp $ */
+/* $OpenBSD: wsemul_vt100_subr.c,v 1.30 2023/02/26 15:09:53 miod Exp $ */
/* $NetBSD: wsemul_vt100_subr.c,v 1.7 2000/04/28 21:56:16 mycroft Exp $ */
/*
ERASECOLS(edp->ccol, n, edp->bkgdattr));
break;
case 'A': /* CUU */
- edp->crow -= min(DEF1_ARG(0), ROWS_ABOVE);
+ n = ROWS_ABOVE;
+ if (n > 0)
+ edp->crow -= min(DEF1_ARG(0), n);
CHECK_DW;
break;
case 'B': /* CUD */
- edp->crow += min(DEF1_ARG(0), ROWS_BELOW);
+ n = ROWS_BELOW;
+ if (n > 0)
+ edp->crow += min(DEF1_ARG(0), n);
CHECK_DW;
break;
case 'C': /* CUF */
break;
case 'L': /* IL insert line */
case 'M': /* DL delete line */
- {
- int savscrstartrow, savscrnrows;
-
- n = min(DEF1_ARG(0), ROWS_BELOW + 1);
- savscrstartrow = edp->scrreg_startrow;
- savscrnrows = edp->scrreg_nrows;
- edp->scrreg_nrows -= ROWS_ABOVE;
- edp->scrreg_startrow = edp->crow;
- if (c == 'L')
- rc = wsemul_vt100_scrolldown(edp, n);
- else
- rc = wsemul_vt100_scrollup(edp, n);
- edp->scrreg_startrow = savscrstartrow;
- edp->scrreg_nrows = savscrnrows;
- }
+ if (edp->crow >= edp->scrreg_startrow &&
+ edp->crow < edp->scrreg_startrow + edp->scrreg_nrows) {
+ int savscrstartrow, savscrnrows;
+
+ n = min(DEF1_ARG(0), ROWS_BELOW + 1);
+ savscrstartrow = edp->scrreg_startrow;
+ savscrnrows = edp->scrreg_nrows;
+ edp->scrreg_nrows -= ROWS_ABOVE;
+ edp->scrreg_startrow = edp->crow;
+ if (c == 'L')
+ rc = wsemul_vt100_scrolldown(edp, n);
+ else
+ rc = wsemul_vt100_scrollup(edp, n);
+ edp->scrreg_startrow = savscrstartrow;
+ edp->scrreg_nrows = savscrnrows;
+ } /* else not within scrolling region, ignore the sequence */
break;
case 'P': /* DCH delete character */
n = min(DEF1_ARG(0), COLS_LEFT + 1);
{
char buf[20];
int row;
- if (edp->flags & VTFL_DECOM)
+ if (edp->flags & VTFL_DECOM) {
row = ROWS_ABOVE;
- else
+ if (row < 0)
+ row = 0;
+ } else
row = edp->crow;
n = snprintf(buf, sizeof buf, "\033[%d;%dR",
row + 1, edp->ccol + 1);
if (edp->tabs != NULL) {
memset(edp->tabs, 0, edp->ncols);
pos = 0;
+ if (edp->dcsarg == NULL)
+ goto out;
for (i = 0; i < edp->dcspos; i++) {
char c = edp->dcsarg[i];
switch (c) {
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
case '8': case '9':
- pos = pos * 10 + (edp->dcsarg[i] - '0');
+ pos = pos * 10 + (c - '0');
+ if (pos > edp->ncols)
+ goto out;
break;
case '/':
if (pos > 0)
#endif
break;
}
+out:
edp->dcstype = 0;
}