Skip to content

Commit bcfe498

Browse files
committed
Guard ProgressPane for pseudo-TTYs
Again due to the fact that relying on Console.IsOutputRedirected (as System.Console does for these APIs) causes bugs when pseudo-TTYs are used (since the output is not redirected, but the APIs nonetheless can't be used properly). So we ran into a problem where the value of CursorTop and Console.BufferHeight were lies, and so we accidentally attempted to set it numbers below zero. Guard everything.
1 parent 79daea0 commit bcfe498

2 files changed

Lines changed: 41 additions & 48 deletions

File tree

src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostRawUserInterface.cs

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1577,7 +1577,8 @@ public override Size BufferSize
15771577
public override Coordinates CursorPosition
15781578
{
15791579
get { return new Coordinates(Console.CursorLeft, Console.CursorTop); }
1580-
set { Console.SetCursorPosition(value.X, value.Y); }
1580+
set { Console.SetCursorPosition(value.X < 0 ? 0 : value.X,
1581+
value.Y < 0 ? 0 : value.Y); }
15811582
}
15821583

15831584
/// <summary>
@@ -1796,54 +1797,49 @@ public override void ScrollBufferContents(Rectangle source, Coordinates destinat
17961797
public override void SetBufferContents(Coordinates origin,
17971798
BufferCell[,] contents)
17981799
{
1799-
//if there are no contents, there is nothing to set the buffer to
1800+
//if there are no contents, there is nothing to set the buffer to
18001801
if (contents == null)
18011802
{
18021803
PSTraceSource.NewArgumentNullException("contents");
18031804
}
18041805

1805-
//variables to traverse through the buffer
1806-
int cursorX = origin.X;
1807-
int cursorY = origin.Y;
1808-
18091806
//if the cursor is on the last line, we need to make more space to print the specified buffer
1810-
if (cursorY == Console.BufferHeight -1 && cursorX >= Console.BufferWidth)
1811-
{
1812-
//for each row in the buffer, create a new line
1807+
if (origin.Y == BufferSize.Height - 1 && origin.X >= BufferSize.Width)
1808+
{
1809+
//for each row in the buffer, create a new line
18131810
int rows = contents.GetLength(0);
1814-
for (int i=0; i < rows; i++)
1811+
ScrollBuffer(rows);
1812+
// for each row in the buffer, move the cursor y up to the beginning of the created blank space
1813+
// but not above zero
1814+
if (origin.Y >= rows)
18151815
{
1816-
ScrollBuffer(1);
1816+
origin.Y -= rows;
18171817
}
1818-
1819-
//for each row in the buffer, move the cursor y up to the beginning of the created blank space
1820-
cursorY -= rows;
18211818
}
18221819

1823-
//iterate through the buffer to set
1820+
//iterate through the buffer to set
18241821
foreach (var charitem in contents)
18251822
{
1826-
//set the cursor to false to prevent cursor flicker
1823+
//set the cursor to false to prevent cursor flicker
18271824
Console.CursorVisible = false;
1828-
1829-
//if x is exceeding buffer width, reset to the next line
1830-
if (cursorX >= Console.BufferWidth)
1825+
1826+
//if x is exceeding buffer width, reset to the next line
1827+
if (origin.X >= BufferSize.Width)
18311828
{
1832-
cursorX = 1;
1833-
}
1829+
origin.X = 1;
1830+
}
18341831

1835-
//write the character from contents
1832+
//write the character from contents
18361833
Console.Out.Write(charitem.Character);
18371834

18381835
//advance the character one position
1839-
cursorX++;
1840-
}
1836+
origin.X++;
1837+
}
18411838

18421839
//reset the cursor to the original position
1843-
Console.SetCursorPosition(cursorX, cursorY);
1844-
//reset the cursor to visible
1845-
Console.CursorVisible = true;
1846-
1840+
CursorPosition = origin;
1841+
//reset the cursor to visible
1842+
Console.CursorVisible = true;
18471843
}
18481844

18491845
/// <summary>

src/Microsoft.PowerShell.ConsoleHost/host/msh/ProgressPane.cs

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -102,32 +102,29 @@ class ProgressPane
102102
location.X = 0;
103103
location.Y = Math.Min(location.Y + 2, bufSize.Height);
104104

105-
if (System.Management.Automation.Platform.IsWindows)
106-
{
107-
// Save off the current contents of the screen buffer in the region that we will occupy
108-
savedRegion =
109-
rawui.GetBufferContents(
110-
new Rectangle(location.X, location.Y, location.X + cols - 1, location.Y + rows - 1));
111-
}
105+
#if UNIX
106+
// replace the saved region in the screen buffer with our progress display
107+
location = rawui.CursorPosition;
112108

113-
//Platform is either OSX or Linux
114-
else
109+
//set the cursor position back to the beginning of the region to overwrite write-progress
110+
//if the cursor is at the bottom, back it up to overwrite the previous write progress
111+
if (location.Y >= rawui.BufferSize.Height - rows)
115112
{
116-
// replace the saved region in the screen buffer with our progress display
117-
location.X = rawui.CursorPosition.X;
118-
location.Y = rawui.CursorPosition.Y;
119-
120-
//set the cursor position back to the beginning of the region to overwrite write-progress
121-
//if the cursor is at the bottom, back it up to overwrite the previous write progress
122-
if (location.Y >= Console.BufferHeight - rows)
113+
Console.Out.Write('\n');
114+
if (location.Y >= rows)
123115
{
124-
Console.Out.Write('\n');
125116
location.Y -= rows;
126117
}
127-
128-
Console.SetCursorPosition(location.X, location.Y);
129118
}
130-
119+
120+
rawui.CursorPosition = location;
121+
#else
122+
// Save off the current contents of the screen buffer in the region that we will occupy
123+
savedRegion =
124+
rawui.GetBufferContents(
125+
new Rectangle(location.X, location.Y, location.X + cols - 1, location.Y + rows - 1));
126+
#endif
127+
131128
// replace the saved region in the screen buffer with our progress display
132129
rawui.SetBufferContents(location, tempProgressRegion);
133130
}

0 commit comments

Comments
 (0)