Fix parameters

Explicit zero parameters should still default to one.  Limit parameters
to a maximum value of 32767.
This commit is contained in:
Jason Hood 2017-12-09 22:16:47 +10:00
parent c11447fc8b
commit 645f57e59c
2 changed files with 53 additions and 67 deletions

118
ANSI.c
View File

@ -167,7 +167,9 @@
added palette sequences; added palette sequences;
change the scan lines in the graphics set to their actual Unicode chars; change the scan lines in the graphics set to their actual Unicode chars;
added IND, NEL & RI (using buffer, in keeping with LF); added IND, NEL & RI (using buffer, in keeping with LF);
added DA, DECCOLM, DECNCSM, DECSC & DECRC. added DA, DECCOLM, DECNCSM, DECSC & DECRC;
an explicit zero parameter should still default to one;
restrict parameters to a maximum value of 32767.
*/ */
#include "ansicon.h" #include "ansicon.h"
@ -721,6 +723,7 @@ void send_palette_sequence( COLORREF c )
void InterpretEscSeq( void ) void InterpretEscSeq( void )
{ {
int i; int i;
int p1, p2;
WORD attribut; WORD attribut;
CONSOLE_SCREEN_BUFFER_INFO Info; CONSOLE_SCREEN_BUFFER_INFO Info;
CONSOLE_CURSOR_INFO CursInfo; CONSOLE_CURSOR_INFO CursInfo;
@ -827,6 +830,10 @@ void InterpretEscSeq( void )
if (prefix2 != 0) if (prefix2 != 0)
return; return;
// Even an explicit parameter of 0 should be defaulted to 1.
p1 = (es_argv[0] == 0) ? 1 : es_argv[0];
p2 = (es_argv[1] == 0) ? 1 : es_argv[1];
GetConsoleScreenBufferInfo( hConOut, &Info ); GetConsoleScreenBufferInfo( hConOut, &Info );
if (suffix2 == '+') if (suffix2 == '+')
{ {
@ -841,7 +848,7 @@ void InterpretEscSeq( void )
switch (suffix) switch (suffix)
{ {
case 'm': case 'm':
if (es_argc == 0) es_argv[es_argc++] = 0; if (es_argc == 0) es_argc++; // ESC[m == ESC[0m
for (i = 0; i < es_argc; i++) for (i = 0; i < es_argc; i++)
{ {
if (30 <= es_argv[i] && es_argv[i] <= 37) if (30 <= es_argv[i] && es_argv[i] <= 37)
@ -955,8 +962,7 @@ void InterpretEscSeq( void )
return; return;
case 'J': case 'J':
if (es_argc == 0) es_argv[es_argc++] = 0; // ESC[J == ESC[0J if (es_argc > 1) return; // ESC[J == ESC[0J
if (es_argc != 1) return;
switch (es_argv[0]) switch (es_argv[0])
{ {
case 0: // ESC[0J erase from cursor to end of display case 0: // ESC[0J erase from cursor to end of display
@ -1014,8 +1020,7 @@ void InterpretEscSeq( void )
} }
case 'K': case 'K':
if (es_argc == 0) es_argv[es_argc++] = 0; // ESC[K == ESC[0K if (es_argc > 1) return; // ESC[K == ESC[0K
if (es_argc != 1) return;
switch (es_argv[0]) switch (es_argv[0])
{ {
case 0: // ESC[0K Clear to end of line case 0: // ESC[0K Clear to end of line
@ -1040,20 +1045,18 @@ void InterpretEscSeq( void )
} }
case 'X': // ESC[#X Erase # characters. case 'X': // ESC[#X Erase # characters.
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[X == ESC[1X if (es_argc > 1) return; // ESC[X == ESC[1X
if (es_argc != 1) return; FillBlank( p1, CUR );
FillBlank( es_argv[0], CUR );
return; return;
case 'L': // ESC[#L Insert # blank lines. case 'L': // ESC[#L Insert # blank lines.
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[L == ESC[1L if (es_argc > 1) return; // ESC[L == ESC[1L
if (es_argc != 1) return;
Rect.Left = WIN.Left = LEFT; Rect.Left = WIN.Left = LEFT;
Rect.Right = WIN.Right = RIGHT; Rect.Right = WIN.Right = RIGHT;
Rect.Top = CUR.Y; Rect.Top = CUR.Y;
Rect.Bottom = bottom; Rect.Bottom = bottom;
Pos.X = LEFT; Pos.X = LEFT;
Pos.Y = CUR.Y + es_argv[0]; Pos.Y = CUR.Y + p1;
CharInfo.Char.UnicodeChar = ' '; CharInfo.Char.UnicodeChar = ' ';
CharInfo.Attributes = Info.wAttributes; CharInfo.Attributes = Info.wAttributes;
ScrollConsoleScreenBuffer( hConOut, &Rect, &WIN, Pos, &CharInfo ); ScrollConsoleScreenBuffer( hConOut, &Rect, &WIN, Pos, &CharInfo );
@ -1061,12 +1064,11 @@ void InterpretEscSeq( void )
return; return;
case 'M': // ESC[#M Delete # lines. case 'M': // ESC[#M Delete # lines.
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[M == ESC[1M if (es_argc > 1) return; // ESC[M == ESC[1M
if (es_argc != 1) return;
Rect.Left = WIN.Left = LEFT; Rect.Left = WIN.Left = LEFT;
Rect.Right = WIN.Right = RIGHT; Rect.Right = WIN.Right = RIGHT;
Rect.Bottom = bottom; Rect.Bottom = bottom;
Rect.Top = CUR.Y - es_argv[0]; Rect.Top = CUR.Y - p1;
Pos.X = LEFT; Pos.X = LEFT;
Pos.Y = TOP = CUR.Y; Pos.Y = TOP = CUR.Y;
CharInfo.Char.UnicodeChar = ' '; CharInfo.Char.UnicodeChar = ' ';
@ -1076,11 +1078,10 @@ void InterpretEscSeq( void )
return; return;
case 'P': // ESC[#P Delete # characters. case 'P': // ESC[#P Delete # characters.
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[P == ESC[1P if (es_argc > 1) return; // ESC[P == ESC[1P
if (es_argc != 1) return;
Rect.Left = WIN.Left = CUR.X; Rect.Left = WIN.Left = CUR.X;
Rect.Right = WIN.Right = RIGHT; Rect.Right = WIN.Right = RIGHT;
Pos.X = CUR.X - es_argv[0]; Pos.X = CUR.X - p1;
Pos.Y = Pos.Y =
Rect.Top = Rect.Top =
Rect.Bottom = CUR.Y; Rect.Bottom = CUR.Y;
@ -1090,11 +1091,10 @@ void InterpretEscSeq( void )
return; return;
case '@': // ESC[#@ Insert # blank characters. case '@': // ESC[#@ Insert # blank characters.
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[@ == ESC[1@ if (es_argc > 1) return; // ESC[@ == ESC[1@
if (es_argc != 1) return;
Rect.Left = WIN.Left = CUR.X; Rect.Left = WIN.Left = CUR.X;
Rect.Right = WIN.Right = RIGHT; Rect.Right = WIN.Right = RIGHT;
Pos.X = CUR.X + es_argv[0]; Pos.X = CUR.X + p1;
Pos.Y = Pos.Y =
Rect.Top = Rect.Top =
Rect.Bottom = CUR.Y; Rect.Bottom = CUR.Y;
@ -1105,9 +1105,8 @@ void InterpretEscSeq( void )
case 'k': // ESC[#k case 'k': // ESC[#k
case 'A': // ESC[#A Moves cursor up # lines case 'A': // ESC[#A Moves cursor up # lines
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[A == ESC[1A if (es_argc > 1) return; // ESC[A == ESC[1A
if (es_argc != 1) return; Pos.Y = CUR.Y - p1;
Pos.Y = CUR.Y - es_argv[0];
if (Pos.Y < top) Pos.Y = top; if (Pos.Y < top) Pos.Y = top;
Pos.X = CUR.X; Pos.X = CUR.X;
SetConsoleCursorPosition( hConOut, Pos ); SetConsoleCursorPosition( hConOut, Pos );
@ -1115,9 +1114,8 @@ void InterpretEscSeq( void )
case 'e': // ESC[#e case 'e': // ESC[#e
case 'B': // ESC[#B Moves cursor down # lines case 'B': // ESC[#B Moves cursor down # lines
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[B == ESC[1B if (es_argc > 1) return; // ESC[B == ESC[1B
if (es_argc != 1) return; Pos.Y = CUR.Y + p1;
Pos.Y = CUR.Y + es_argv[0];
if (Pos.Y > bottom) Pos.Y = bottom; if (Pos.Y > bottom) Pos.Y = bottom;
Pos.X = CUR.X; Pos.X = CUR.X;
SetConsoleCursorPosition( hConOut, Pos ); SetConsoleCursorPosition( hConOut, Pos );
@ -1125,9 +1123,8 @@ void InterpretEscSeq( void )
case 'a': // ESC[#a case 'a': // ESC[#a
case 'C': // ESC[#C Moves cursor forward # spaces case 'C': // ESC[#C Moves cursor forward # spaces
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[C == ESC[1C if (es_argc > 1) return; // ESC[C == ESC[1C
if (es_argc != 1) return; Pos.X = CUR.X + p1;
Pos.X = CUR.X + es_argv[0];
if (Pos.X > RIGHT) Pos.X = RIGHT; if (Pos.X > RIGHT) Pos.X = RIGHT;
Pos.Y = CUR.Y; Pos.Y = CUR.Y;
SetConsoleCursorPosition( hConOut, Pos ); SetConsoleCursorPosition( hConOut, Pos );
@ -1135,27 +1132,24 @@ void InterpretEscSeq( void )
case 'j': // ESC[#j case 'j': // ESC[#j
case 'D': // ESC[#D Moves cursor back # spaces case 'D': // ESC[#D Moves cursor back # spaces
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[D == ESC[1D if (es_argc > 1) return; // ESC[D == ESC[1D
if (es_argc != 1) return; Pos.X = CUR.X - p1;
Pos.X = CUR.X - es_argv[0];
if (Pos.X < LEFT) Pos.X = LEFT; if (Pos.X < LEFT) Pos.X = LEFT;
Pos.Y = CUR.Y; Pos.Y = CUR.Y;
SetConsoleCursorPosition( hConOut, Pos ); SetConsoleCursorPosition( hConOut, Pos );
return; return;
case 'E': // ESC[#E Moves cursor down # lines, column 1. case 'E': // ESC[#E Moves cursor down # lines, column 1.
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[E == ESC[1E if (es_argc > 1) return; // ESC[E == ESC[1E
if (es_argc != 1) return; Pos.Y = CUR.Y + p1;
Pos.Y = CUR.Y + es_argv[0];
if (Pos.Y > bottom) Pos.Y = bottom; if (Pos.Y > bottom) Pos.Y = bottom;
Pos.X = LEFT; Pos.X = LEFT;
SetConsoleCursorPosition( hConOut, Pos ); SetConsoleCursorPosition( hConOut, Pos );
return; return;
case 'F': // ESC[#F Moves cursor up # lines, column 1. case 'F': // ESC[#F Moves cursor up # lines, column 1.
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[F == ESC[1F if (es_argc > 1) return; // ESC[F == ESC[1F
if (es_argc != 1) return; Pos.Y = CUR.Y - p1;
Pos.Y = CUR.Y - es_argv[0];
if (Pos.Y < top) Pos.Y = top; if (Pos.Y < top) Pos.Y = top;
Pos.X = LEFT; Pos.X = LEFT;
SetConsoleCursorPosition( hConOut, Pos ); SetConsoleCursorPosition( hConOut, Pos );
@ -1163,9 +1157,8 @@ void InterpretEscSeq( void )
case '`': // ESC[#` case '`': // ESC[#`
case 'G': // ESC[#G Moves cursor column # in current row. case 'G': // ESC[#G Moves cursor column # in current row.
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[G == ESC[1G if (es_argc > 1) return; // ESC[G == ESC[1G
if (es_argc != 1) return; Pos.X = p1 - 1;
Pos.X = es_argv[0] - 1;
if (Pos.X > RIGHT) Pos.X = RIGHT; if (Pos.X > RIGHT) Pos.X = RIGHT;
if (Pos.X < LEFT) Pos.X = LEFT; if (Pos.X < LEFT) Pos.X = LEFT;
Pos.Y = CUR.Y; Pos.Y = CUR.Y;
@ -1173,9 +1166,8 @@ void InterpretEscSeq( void )
return; return;
case 'd': // ESC[#d Moves cursor row #, current column. case 'd': // ESC[#d Moves cursor row #, current column.
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[d == ESC[1d if (es_argc > 1) return; // ESC[d == ESC[1d
if (es_argc != 1) return; Pos.Y = top + p1 - 1;
Pos.Y = top + es_argv[0] - 1;
if (Pos.Y < top) Pos.Y = top; if (Pos.Y < top) Pos.Y = top;
if (Pos.Y > bottom) Pos.Y = bottom; if (Pos.Y > bottom) Pos.Y = bottom;
SetConsoleCursorPosition( hConOut, Pos ); SetConsoleCursorPosition( hConOut, Pos );
@ -1183,45 +1175,38 @@ void InterpretEscSeq( void )
case 'f': // ESC[#;#f case 'f': // ESC[#;#f
case 'H': // ESC[#;#H Moves cursor to line #, column # case 'H': // ESC[#;#H Moves cursor to line #, column #
if (es_argc == 0) if (es_argc > 2) return; // ESC[H == ESC[1;1H ESC[#H == ESC[#;1H
es_argv[es_argc++] = 1; // ESC[H == ESC[1;1H Pos.X = p2 - 1;
if (es_argc == 1)
es_argv[es_argc++] = 1; // ESC[#H == ESC[#;1H
if (es_argc > 2) return;
Pos.X = es_argv[1] - 1;
if (Pos.X < LEFT) Pos.X = LEFT; if (Pos.X < LEFT) Pos.X = LEFT;
if (Pos.X > RIGHT) Pos.X = RIGHT; if (Pos.X > RIGHT) Pos.X = RIGHT;
Pos.Y = top + es_argv[0] - 1; Pos.Y = top + p1 - 1;
if (Pos.Y < top) Pos.Y = top; if (Pos.Y < top) Pos.Y = top;
if (Pos.Y > bottom) Pos.Y = bottom; if (Pos.Y > bottom) Pos.Y = bottom;
SetConsoleCursorPosition( hConOut, Pos ); SetConsoleCursorPosition( hConOut, Pos );
return; return;
case 'I': // ESC[#I Moves cursor forward # tabs case 'I': // ESC[#I Moves cursor forward # tabs
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[I == ESC[1I if (es_argc > 1) return; // ESC[I == ESC[1I
if (es_argc != 1) return;
Pos.Y = CUR.Y; Pos.Y = CUR.Y;
Pos.X = (CUR.X & -8) + es_argv[0] * 8; Pos.X = (CUR.X & -8) + p1 * 8;
if (Pos.X > RIGHT) Pos.X = RIGHT; if (Pos.X > RIGHT) Pos.X = RIGHT;
SetConsoleCursorPosition( hConOut, Pos ); SetConsoleCursorPosition( hConOut, Pos );
return; return;
case 'Z': // ESC[#Z Moves cursor back # tabs case 'Z': // ESC[#Z Moves cursor back # tabs
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[Z == ESC[1Z if (es_argc > 1) return; // ESC[Z == ESC[1Z
if (es_argc != 1) return;
Pos.Y = CUR.Y; Pos.Y = CUR.Y;
if ((CUR.X & 7) == 0) if ((CUR.X & 7) == 0)
Pos.X = CUR.X - es_argv[0] * 8; Pos.X = CUR.X - p1 * 8;
else else
Pos.X = (CUR.X & -8) - (es_argv[0] - 1) * 8; Pos.X = (CUR.X & -8) - (p1 - 1) * 8;
if (Pos.X < LEFT) Pos.X = LEFT; if (Pos.X < LEFT) Pos.X = LEFT;
SetConsoleCursorPosition( hConOut, Pos ); SetConsoleCursorPosition( hConOut, Pos );
return; return;
case 'b': // ESC[#b Repeat character case 'b': // ESC[#b Repeat character
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[b == ESC[1b if (es_argc > 1) return; // ESC[b == ESC[1b
if (es_argc != 1) return; while (--p1 >= 0)
while (--es_argv[0] >= 0)
PushBuffer( ChPrev ); PushBuffer( ChPrev );
return; return;
@ -1239,8 +1224,7 @@ void InterpretEscSeq( void )
return; return;
case 'c': // ESC[#c Device attributes case 'c': // ESC[#c Device attributes
if (es_argc == 0) es_argv[es_argc++] = 0; // ESC[c == ESC[0c if (es_argc > 1 || es_argv[0] != 0) return; // ESC[c == ESC[0c
if (es_argc != 1 || es_argv[0] != 0) return;
SendSequence( L"\33[?62;1c" ); // VT220 with 132 columns SendSequence( L"\33[?62;1c" ); // VT220 with 132 columns
return; return;
@ -1655,6 +1639,8 @@ ParseAndPrintString( HANDLE hDev,
FlushBuffer(); FlushBuffer();
prefix = c; prefix = c;
prefix2 = 0; prefix2 = 0;
es_argc = 0;
es_argv[0] = es_argv[1] = 0;
Pt_len = 0; Pt_len = 0;
*Pt_arg = '\0'; *Pt_arg = '\0';
state = 3; state = 3;
@ -1678,15 +1664,12 @@ ParseAndPrintString( HANDLE hDev,
{ {
if (is_digit( c )) if (is_digit( c ))
{ {
es_argc = 0;
es_argv[0] = c - '0'; es_argv[0] = c - '0';
state = 4; state = 4;
} }
else if (c == ';') else if (c == ';')
{ {
es_argc = 1; es_argc = 1;
es_argv[0] = 0;
es_argv[1] = 0;
state = 4; state = 4;
} }
else if (c == ':') else if (c == ':')
@ -1718,6 +1701,7 @@ ParseAndPrintString( HANDLE hDev,
if (is_digit( c )) if (is_digit( c ))
{ {
es_argv[es_argc] = 10 * es_argv[es_argc] + (c - '0'); es_argv[es_argc] = 10 * es_argv[es_argc] + (c - '0');
if (es_argv[es_argc] > 32767) es_argv[es_argc] = 32767;
} }
else if (c == ';') else if (c == ';')
{ {

View File

@ -311,6 +311,8 @@ Version History
(fixes redirecting to CON and Microsoft's conio); (fixes redirecting to CON and Microsoft's conio);
- fix cursor report with duplicated digits (e.g. "11" was only writing "1"); - fix cursor report with duplicated digits (e.g. "11" was only writing "1");
- fix issues with CRM; - fix issues with CRM;
- fix explicit zero parameters not defaulting to 1;
* limit parameters to a maximum value of 32767;
* go back to saving the buffer cursor position; * go back to saving the buffer cursor position;
* preserve escape that isn't part of a sequence; * preserve escape that isn't part of a sequence;
* escape control characters; * escape control characters;