IndexOutOfRangeException following an attempt to type after running `dotnet build`
Prerequisites
- [x] Write a descriptive title.
- [x] Make sure you are able to repro it on the latest released version
- [x] Search the existing issues, especially the pinned issues.
Exception report
Oops, something went wrong.
Please report this bug with ALL the details below, including both the 'Environment' and 'Exception' sections.
Please report on GitHub: https://github.com/PowerShell/PSReadLine/issues/new?template=Bug_Report.yaml
Thank you!
### Environment
PSReadLine: 2.3.6+d2e770f93b7a53d8660a6402eb29d1ae1c35e767
PowerShell: 7.5.3
OS: Microsoft Windows 10.0.26100
BufferWidth: 133
BufferHeight: 71
Last 200 Keys:
F V . D o c s . C o r e Spacebar t o Spacebar . N E T Spacebar 7 Backspace 8 Escape 0 C g i t Spacebar l o g Enter g i t Spacebar c o Backspace Backspace s t a t u s Enter g i t Spacebar c o m m i t Spacebar - m Spacebar " U p g r a d e Spacebar F C Backspace V . D o c s . C o r e Spacebar t o Spacebar . N E T Spacebar 8 " Enter g i t Spacebar s t a t u s Enter Enter g i t Spacebar s t a t u s Enter d o t n e t Spacebar b u i l d Spacebar F i l e v i n e . S e r v i c e s / F i l e v i n e . / Backspace S e r v i c e s . c s p r o j Spacebar - c Spacebar R e l e a s e Enter UpArrow Enter UpArrow Enter Escape . \ r u
### Exception
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at System.Text.StringBuilder.get_Chars(Int32 index)
at Microsoft.PowerShell.PSConsoleReadLine.ReplaceCharInPlace(Nullable`1 key, Object arg)
at Microsoft.PowerShell.PSConsoleReadLine.InputLoop()
at Microsoft.PowerShell.PSConsoleReadLine.ReadLine(Runspace runspace, EngineIntrinsics engineIntrinsics, CancellationToken cancellationToken, Nullable`1 lastRunStatus)
Screenshot
The screenshot may contain sensitive information, but I can tell you that the last output was from a dotnet build command.
Environment data
PS Version: 7.5.3
PS HostName: ConsoleHost (Windows Terminal)
PSReadLine Version: 2.3.6
PSReadLine EditMode: Vi
OS: 10.0.26100.1 (WinBuild.160101.0800)
BufferWidth: 133
BufferHeight: 71
Steps to reproduce
I experienced a delay when attempting to type at the prompt, then I got the exception text. I do not have specific steps to reproduce. This is the first time I have encountered this message.
Expected behavior
Not having an exception.
Actual behavior
There was a delay when I attempted to type, then I got the exception test pasted earlier.
Breaking down your HistoryQueue:
R e l e a s e Enter <--- 1. executing dotnet build
UpArrow Enter <--- 2. PreviousHistory: executing dotnet build again
UpArrow Enter <--- 3. PreviousHistory: executing dotnet build again
Escape <--- 4. ViCommandMode: switch from insert to command mode
. <--- 5. RepeatLastCommand: repeat last text modification
\ <--- 6. inserts \ char
r u <--- 7. ReplaceCharInPlace: replace character under cursor with u char
After the last dotnet build (3) you have an empty line, cursor is at the beginning of the line, and you're in vi command mode (4). RepeatLastCommand does nothing since there are no edits (5). At this point you have this state:
buffer = []
cursor = 0
PS>█
Now the interesting part, \ in command mode inserts that char and moves the cursor forward (6) where there is no character, only adding \ to the buffer. This is putting the cursor outside bounds of the buffer and this state:
buffer = ['\']
cursor = 1
PS>\█
ReplaceCharInPlace takes the cursor position in the buffer i.e., cursor is index in the buffer array and replaces the character at that index with the read key u (7). In the current state, this is buffer[1] when the buffer length is only 1, hence System.IndexOutOfRangeException: Index was outside the bounds of the array..
It doesn't have anything to do with the dotnet CLI, you can reproduce the issue by:
- Start new PowerShell console
- Enter vi command mode (press
Esc) - Press
\ - Press
rand any char key e.g.,u
I haven't dug into the code to understand why \ gets inserted in vi command mode, but hopefully this helps point someone in the right direction. If vi emulation is the goal, \ in normal mode does nothing.