From 7f0e430482ba4c08e83042fcfad661df49f1222b Mon Sep 17 00:00:00 2001 From: Ilya Date: Tue, 19 Mar 2019 11:21:53 +0500 Subject: [PATCH 1/7] Remove unused code with initialContent in ConsoleHost --- .../host/msh/ConsoleControl.cs | 10 ++---- .../host/msh/ConsoleHostUserInterface.cs | 31 ++++++------------- ...ConsoleHostUserInterfacePromptForChoice.cs | 1 - 3 files changed, 11 insertions(+), 31 deletions(-) diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs index 8ddeca197af..a440e8b952c 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs @@ -716,9 +716,6 @@ internal static void SetMode(ConsoleHandle consoleHandle, ConsoleModes mode) /// /// /// Handle to the console device returned by GetInputHandle - /// - /// Initial contents of the edit buffer, if any. charactersToRead should be at least as large as the length of this string. - /// /// /// Number of characters to read from the device. /// @@ -733,18 +730,15 @@ internal static void SetMode(ConsoleHandle consoleHandle, ConsoleModes mode) /// If Win32's ReadConsole fails /// - internal static string ReadConsole(ConsoleHandle consoleHandle, string initialContent, - int charactersToRead, bool endOnTab, out uint keyState) + internal static string ReadConsole(ConsoleHandle consoleHandle, int charactersToRead, bool endOnTab, out uint keyState) { Dbg.Assert(!consoleHandle.IsInvalid, "ConsoleHandle is not valid"); Dbg.Assert(!consoleHandle.IsClosed, "ConsoleHandle is closed"); - Dbg.Assert(initialContent != null, "if no initial content is desired, pass string.Empty"); keyState = 0; CONSOLE_READCONSOLE_CONTROL control = new CONSOLE_READCONSOLE_CONTROL(); control.nLength = (ULONG)Marshal.SizeOf(control); - control.nInitialChars = (ULONG)initialContent.Length; control.dwControlKeyState = 0; if (endOnTab) { @@ -754,7 +748,7 @@ internal static string ReadConsole(ConsoleHandle consoleHandle, string initialCo } DWORD charsReadUnused = 0; - StringBuilder buffer = new StringBuilder(initialContent, charactersToRead); + StringBuilder buffer = new StringBuilder(charactersToRead); bool result = NativeMethods.ReadConsole( consoleHandle.DangerousGetHandle(), diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs index d735428d1eb..ba8769385b3 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs @@ -169,7 +169,7 @@ public override string ReadLine() // call our internal version such that it does not end input on a tab ReadLineResult unused; - return ReadLine(false, string.Empty, out unused, true, true); + return ReadLine(false, out unused, true, true); } /// @@ -308,7 +308,7 @@ private object ReadLineSafe(bool isSecureString, char? printToken) ConsoleKeyInfo keyInfo = Console.ReadKey(true); #else uint unused = 0; - string key = ConsoleControl.ReadConsole(handle, string.Empty, 1, false, out unused); + string key = ConsoleControl.ReadConsole(handle, 1, false, out unused); #endif #if UNIX @@ -1297,10 +1297,6 @@ internal enum ReadLineResult /// true to end input when the user hits the tab or shift-tab keys, false to only end on the enter key (or a break /// event). Ignored if not reading from the console device. /// - /// - /// The initial contents of the input buffer. Nice if you want to have a default result. Ignored if not reading from the - /// console device. - /// /// /// Receives an enum value indicating how input was ended. /// @@ -1325,7 +1321,7 @@ internal enum ReadLineResult /// Win32's SetConsoleCursorPosition failed /// - internal string ReadLine(bool endOnTab, string initialContent, out ReadLineResult result, bool calledFromPipeline, bool transcribeResult) + internal string ReadLine(bool endOnTab, out ReadLineResult result, bool calledFromPipeline, bool transcribeResult) { result = ReadLineResult.endedOnEnter; @@ -1335,8 +1331,8 @@ internal string ReadLine(bool endOnTab, string initialContent, out ReadLineResul string restOfLine = null; string s = ReadFromStdin - ? ReadLineFromFile(initialContent) - : ReadLineFromConsole(endOnTab, initialContent, calledFromPipeline, ref restOfLine, ref result); + ? ReadLineFromFile() + : ReadLineFromConsole(endOnTab, calledFromPipeline, ref restOfLine, ref result); if (transcribeResult) { @@ -1353,15 +1349,9 @@ internal string ReadLine(bool endOnTab, string initialContent, out ReadLineResul return s; } - private string ReadLineFromFile(string initialContent) + private string ReadLineFromFile() { var sb = new StringBuilder(); - if (!string.IsNullOrEmpty(initialContent)) - { - sb.Append(initialContent); - sb.Append('\n'); - } - var consoleIn = _parent.ConsoleIn.Value; while (true) { @@ -1409,7 +1399,7 @@ private string ReadLineFromFile(string initialContent) return sb.ToString(); } - private string ReadLineFromConsole(bool endOnTab, string initialContent, bool calledFromPipeline, ref string restOfLine, ref ReadLineResult result) + private string ReadLineFromConsole(bool endOnTab, bool calledFromPipeline, ref string restOfLine, ref ReadLineResult result) { PreRead(); // Ensure that we're in the proper line-input mode. @@ -1474,7 +1464,7 @@ private string ReadLineFromConsole(bool endOnTab, string initialContent, bool ca #if UNIX keyInfo = Console.ReadKey(true); #else - s += ConsoleControl.ReadConsole(handle, initialContent, maxInputLineLength, endOnTab, out keyState); + s += ConsoleControl.ReadConsole(handle, maxInputLineLength, endOnTab, out keyState); Dbg.Assert(s != null, "s should never be null"); #endif @@ -1775,7 +1765,6 @@ private string RemoveNulls(string input) internal string ReadLineWithTabCompletion(Executor exec) { string input = null; - string lastInput = string.Empty; ReadLineResult rlResult = ReadLineResult.endedOnEnter; @@ -1801,7 +1790,7 @@ internal string ReadLineWithTabCompletion(Executor exec) break; } - input = ReadLine(true, lastInput, out rlResult, false, false); + input = ReadLine(true, out rlResult, false, false); if (input == null) { @@ -1921,8 +1910,6 @@ internal string ReadLineWithTabCompletion(Executor exec) { lastCompletion = completedInput; } - - lastInput = completedInput; } #endif } diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfacePromptForChoice.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfacePromptForChoice.cs index 3f10679b996..d4cb5cc4bfd 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfacePromptForChoice.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfacePromptForChoice.cs @@ -410,7 +410,6 @@ private string ReadChoiceResponse(out ReadLineResult result) ? string.Empty : ReadLine( endOnTab: false, - initialContent: string.Empty, result: out result, calledFromPipeline: true, transcribeResult: true); From ac0bfdc807e638d3a1cf7e87bfe345071cfc7850 Mon Sep 17 00:00:00 2001 From: Ilya Date: Tue, 19 Mar 2019 17:39:45 +0500 Subject: [PATCH 2/7] Replace StringBuilder with ArrayPool.Shared.Rent --- .../host/msh/ConsoleControl.cs | 55 ++++++++++++------- 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs index a440e8b952c..942bdc2978f 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs @@ -13,6 +13,7 @@ #pragma warning disable 1634, 1691 using System; +using System.Buffers; using System.Text; using System.Runtime.InteropServices; using System.Management.Automation; @@ -748,27 +749,43 @@ internal static string ReadConsole(ConsoleHandle consoleHandle, int charactersTo } DWORD charsReadUnused = 0; - StringBuilder buffer = new StringBuilder(charactersToRead); - bool result = - NativeMethods.ReadConsole( - consoleHandle.DangerousGetHandle(), - buffer, - (DWORD)charactersToRead, - out charsReadUnused, - ref control); - keyState = control.dwControlKeyState; - if (result == false) + + // +1 - to put a null in native code. + char[] inputBuffer = ArrayPool.Shared.Rent(charactersToRead + 1); + + try { - int err = Marshal.GetLastWin32Error(); + bool result = + NativeMethods.ReadConsole( + consoleHandle.DangerousGetHandle(), + inputBuffer, + (DWORD)charactersToRead, + out charsReadUnused, + ref control); + keyState = control.dwControlKeyState; + if (result == false) + { + int err = Marshal.GetLastWin32Error(); - HostException e = CreateHostException(err, "ReadConsole", - ErrorCategory.ReadError, ConsoleControlStrings.ReadConsoleExceptionTemplate); - throw e; - } + HostException e = CreateHostException( + err, + "ReadConsole", + ErrorCategory.ReadError, + ConsoleControlStrings.ReadConsoleExceptionTemplate); + throw e; + } - if (charsReadUnused > (uint)buffer.Length) - charsReadUnused = (uint)buffer.Length; - return buffer.ToString(0, (int)charsReadUnused); + if (charsReadUnused > (uint)charactersToRead) + { + charsReadUnused = (uint)charactersToRead; + } + + return new string(inputBuffer, 0, (int)charsReadUnused); + } + finally + { + ArrayPool.Shared.Return(inputBuffer); + } } /// @@ -3016,7 +3033,7 @@ IntPtr reserved internal static extern bool ReadConsole ( NakedWin32Handle consoleInput, - StringBuilder buffer, + char[] buffer, DWORD numberOfCharsToRead, out DWORD numberOfCharsRead, ref CONSOLE_READCONSOLE_CONTROL controlData From 4bbf15d1c9221b820ca95d26dea86bf7c26ad0f2 Mon Sep 17 00:00:00 2001 From: Ilya Date: Wed, 20 Mar 2019 20:35:18 +0500 Subject: [PATCH 3/7] Use stack edit buffer --- .../host/msh/ConsoleControl.cs | 98 ++++++++++++------- .../host/msh/ConsoleHostUserInterface.cs | 43 +++++--- ...ConsoleHostUserInterfacePromptForChoice.cs | 1 + 3 files changed, 92 insertions(+), 50 deletions(-) diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs index 942bdc2978f..faef6cc9f14 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs @@ -717,29 +717,48 @@ internal static void SetMode(ConsoleHandle consoleHandle, ConsoleModes mode) /// /// /// Handle to the console device returned by GetInputHandle + /// + /// Length of initial content of the edit buffer. Zero if no initial content exists. + /// Must be less than editBuffer length. + /// + /// + /// Edit buffer with optional initial content. + /// Caution! Last position in the edit buffer is for a null in native code. + /// /// /// Number of characters to read from the device. + /// Must be less than editBuffer length. /// /// - /// true to allow the user to terminate input by hitting the tab or shift-tab key, in addition to the enter key + /// True to allow the user to terminate input by hitting the tab or shift-tab key, in addition to the enter key /// /// - /// bit mask indicating the state of the control/shift keys at the point input was terminated. + /// Bit mask indicating the state of the control/shift keys at the point input was terminated. + /// /// /// /// /// If Win32's ReadConsole fails /// - internal static string ReadConsole(ConsoleHandle consoleHandle, int charactersToRead, bool endOnTab, out uint keyState) + internal static string ReadConsole( + ConsoleHandle consoleHandle, + int initialContentLength, + Span editBuffer, + int charactersToRead, + bool endOnTab, + out uint keyState) { Dbg.Assert(!consoleHandle.IsInvalid, "ConsoleHandle is not valid"); Dbg.Assert(!consoleHandle.IsClosed, "ConsoleHandle is closed"); + Dbg.Assert(initialContentLength < editBuffer.Length, "initialContentLength must be less than editBuffer.Length"); + Dbg.Assert(charactersToRead < editBuffer.Length, "charactersToRead must be less than editBuffer.Length"); keyState = 0; CONSOLE_READCONSOLE_CONTROL control = new CONSOLE_READCONSOLE_CONTROL(); control.nLength = (ULONG)Marshal.SizeOf(control); + control.nInitialChars = (ULONG)initialContentLength; control.dwControlKeyState = 0; if (endOnTab) { @@ -748,44 +767,34 @@ internal static string ReadConsole(ConsoleHandle consoleHandle, int charactersTo control.dwCtrlWakeupMask = (1 << TAB); } - DWORD charsReadUnused = 0; - - // +1 - to put a null in native code. - char[] inputBuffer = ArrayPool.Shared.Rent(charactersToRead + 1); + DWORD charsReaded = 0; - try + bool result = + NativeMethods.ReadConsole( + consoleHandle.DangerousGetHandle(), + editBuffer, + (DWORD)charactersToRead, + out charsReaded, + ref control); + keyState = control.dwControlKeyState; + if (result == false) { - bool result = - NativeMethods.ReadConsole( - consoleHandle.DangerousGetHandle(), - inputBuffer, - (DWORD)charactersToRead, - out charsReadUnused, - ref control); - keyState = control.dwControlKeyState; - if (result == false) - { - int err = Marshal.GetLastWin32Error(); - - HostException e = CreateHostException( - err, - "ReadConsole", - ErrorCategory.ReadError, - ConsoleControlStrings.ReadConsoleExceptionTemplate); - throw e; - } - - if (charsReadUnused > (uint)charactersToRead) - { - charsReadUnused = (uint)charactersToRead; - } + int err = Marshal.GetLastWin32Error(); - return new string(inputBuffer, 0, (int)charsReadUnused); + HostException e = CreateHostException( + err, + "ReadConsole", + ErrorCategory.ReadError, + ConsoleControlStrings.ReadConsoleExceptionTemplate); + throw e; } - finally + + if (charsReaded > (uint)charactersToRead) { - ArrayPool.Shared.Return(inputBuffer); + charsReaded = (uint)charactersToRead; } + + return editBuffer.Slice(0, (int)charsReaded).ToString(); } /// @@ -3030,15 +3039,30 @@ IntPtr reserved [DllImport(PinvokeDllNames.ReadConsoleDllName, SetLastError = true, CharSet = CharSet.Unicode)] [return: MarshalAs(UnmanagedType.Bool)] - internal static extern bool ReadConsole + internal static extern unsafe bool ReadConsole ( NakedWin32Handle consoleInput, - char[] buffer, + char* lpBuffer, DWORD numberOfCharsToRead, out DWORD numberOfCharsRead, ref CONSOLE_READCONSOLE_CONTROL controlData ); + internal static unsafe bool ReadConsole + ( + NakedWin32Handle consoleInput, + Span buffer, + DWORD numberOfCharsToRead, + out DWORD numberOfCharsRead, + ref CONSOLE_READCONSOLE_CONTROL controlData + ) + { + fixed (char* bufferPtr = &MemoryMarshal.GetReference(buffer)) + { + return ReadConsole(consoleInput, bufferPtr, numberOfCharsToRead, out numberOfCharsRead, ref controlData); + } + } + [DllImport(PinvokeDllNames.PeekConsoleInputDllName, SetLastError = true, CharSet = CharSet.Unicode)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool PeekConsoleInput diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs index ba8769385b3..6271941ce97 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs @@ -169,7 +169,7 @@ public override string ReadLine() // call our internal version such that it does not end input on a tab ReadLineResult unused; - return ReadLine(false, out unused, true, true); + return ReadLine(false, string.Empty, out unused, true, true); } /// @@ -307,8 +307,9 @@ private object ReadLineSafe(bool isSecureString, char? printToken) #if UNIX ConsoleKeyInfo keyInfo = Console.ReadKey(true); #else - uint unused = 0; - string key = ConsoleControl.ReadConsole(handle, 1, false, out unused); + const int CharactersToRead = 1; + Span inputBuffer = stackalloc char[CharactersToRead + 1]; + string key = ConsoleControl.ReadConsole(handle, initialContentLength: 0, inputBuffer, charactersToRead: CharactersToRead, endOnTab: false, out uint _); #endif #if UNIX @@ -1287,7 +1288,7 @@ internal enum ReadLineResult endedOnBreak = 3 } - private const int maxInputLineLength = 8192; + private const int MaxInputLineLength = 1024; /// /// Reads a line of input from the console. Returns when the user hits enter, a break key, a break event occurs. In @@ -1297,6 +1298,10 @@ internal enum ReadLineResult /// true to end input when the user hits the tab or shift-tab keys, false to only end on the enter key (or a break /// event). Ignored if not reading from the console device. /// + /// + /// The initial contents of the input buffer. Nice if you want to have a default result. Ignored if not reading from the + /// console device. + /// /// /// Receives an enum value indicating how input was ended. /// @@ -1321,7 +1326,7 @@ internal enum ReadLineResult /// Win32's SetConsoleCursorPosition failed /// - internal string ReadLine(bool endOnTab, out ReadLineResult result, bool calledFromPipeline, bool transcribeResult) + internal string ReadLine(bool endOnTab, string initialContent, out ReadLineResult result, bool calledFromPipeline, bool transcribeResult) { result = ReadLineResult.endedOnEnter; @@ -1331,8 +1336,8 @@ internal string ReadLine(bool endOnTab, out ReadLineResult result, bool calledFr string restOfLine = null; string s = ReadFromStdin - ? ReadLineFromFile() - : ReadLineFromConsole(endOnTab, calledFromPipeline, ref restOfLine, ref result); + ? ReadLineFromFile(initialContent) + : ReadLineFromConsole(endOnTab, initialContent, calledFromPipeline, ref restOfLine, ref result); if (transcribeResult) { @@ -1349,9 +1354,15 @@ internal string ReadLine(bool endOnTab, out ReadLineResult result, bool calledFr return s; } - private string ReadLineFromFile() + private string ReadLineFromFile(string initialContent) { var sb = new StringBuilder(); + if (!string.IsNullOrEmpty(initialContent)) + { + sb.Append(initialContent); + sb.Append('\n'); + } + var consoleIn = _parent.ConsoleIn.Value; while (true) { @@ -1399,7 +1410,7 @@ private string ReadLineFromFile() return sb.ToString(); } - private string ReadLineFromConsole(bool endOnTab, bool calledFromPipeline, ref string restOfLine, ref ReadLineResult result) + private string ReadLineFromConsole(bool endOnTab, string initialContent, bool calledFromPipeline, ref string restOfLine, ref ReadLineResult result) { PreRead(); // Ensure that we're in the proper line-input mode. @@ -1458,13 +1469,16 @@ private string ReadLineFromConsole(bool endOnTab, bool calledFromPipeline, ref s _rawui.ClearKeyCache(); uint keyState = 0; string s = string.Empty; + Span inputBuffer = stackalloc char[MaxInputLineLength + 1]; + initialContent.AsSpan().CopyTo(inputBuffer); + #endif do { #if UNIX keyInfo = Console.ReadKey(true); #else - s += ConsoleControl.ReadConsole(handle, maxInputLineLength, endOnTab, out keyState); + s += ConsoleControl.ReadConsole(handle, initialContent.Length, inputBuffer, MaxInputLineLength, endOnTab, out keyState); Dbg.Assert(s != null, "s should never be null"); #endif @@ -1765,6 +1779,7 @@ private string RemoveNulls(string input) internal string ReadLineWithTabCompletion(Executor exec) { string input = null; + string lastInput = string.Empty; ReadLineResult rlResult = ReadLineResult.endedOnEnter; @@ -1790,7 +1805,7 @@ internal string ReadLineWithTabCompletion(Executor exec) break; } - input = ReadLine(true, out rlResult, false, false); + input = ReadLine(true, lastInput, out rlResult, false, false); if (input == null) { @@ -1850,9 +1865,9 @@ internal string ReadLineWithTabCompletion(Executor exec) completedInput += restOfLine; } - if (completedInput.Length > (maxInputLineLength - 2)) + if (completedInput.Length > (MaxInputLineLength - 2)) { - completedInput = completedInput.Substring(0, maxInputLineLength - 2); + completedInput = completedInput.Substring(0, MaxInputLineLength - 2); } // Remove any nulls from the string... @@ -1910,6 +1925,8 @@ internal string ReadLineWithTabCompletion(Executor exec) { lastCompletion = completedInput; } + + lastInput = completedInput; } #endif } diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfacePromptForChoice.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfacePromptForChoice.cs index d4cb5cc4bfd..3f10679b996 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfacePromptForChoice.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfacePromptForChoice.cs @@ -410,6 +410,7 @@ private string ReadChoiceResponse(out ReadLineResult result) ? string.Empty : ReadLine( endOnTab: false, + initialContent: string.Empty, result: out result, calledFromPipeline: true, transcribeResult: true); From b818617e654720405c6fca88ea4b36adfab4bd9c Mon Sep 17 00:00:00 2001 From: Ilya Date: Thu, 21 Mar 2019 08:44:31 +0500 Subject: [PATCH 4/7] Fix unused var --- .../host/msh/ConsoleHostUserInterface.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs index 6271941ce97..ff9b71d86f0 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs @@ -309,7 +309,7 @@ private object ReadLineSafe(bool isSecureString, char? printToken) #else const int CharactersToRead = 1; Span inputBuffer = stackalloc char[CharactersToRead + 1]; - string key = ConsoleControl.ReadConsole(handle, initialContentLength: 0, inputBuffer, charactersToRead: CharactersToRead, endOnTab: false, out uint _); + string key = ConsoleControl.ReadConsole(handle, initialContentLength: 0, inputBuffer, charactersToRead: CharactersToRead, endOnTab: false, out _); #endif #if UNIX From 44e1af5312f392d4d2db86318a916ea99e8c0cd0 Mon Sep 17 00:00:00 2001 From: Ilya Date: Thu, 21 Mar 2019 10:36:48 +0500 Subject: [PATCH 5/7] Check initialContent.Length > 0 --- .../host/msh/ConsoleHostUserInterface.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs index ff9b71d86f0..bc8fa54f8a3 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs @@ -1470,7 +1470,10 @@ private string ReadLineFromConsole(bool endOnTab, string initialContent, bool ca uint keyState = 0; string s = string.Empty; Span inputBuffer = stackalloc char[MaxInputLineLength + 1]; - initialContent.AsSpan().CopyTo(inputBuffer); + if (initialContent.Length > 0) + { + initialContent.AsSpan().CopyTo(inputBuffer); + } #endif do From 4932596e5117ae946ada2ddafd78dc5a83aff257 Mon Sep 17 00:00:00 2001 From: Ilya Date: Fri, 22 Mar 2019 08:25:12 +0500 Subject: [PATCH 6/7] Remove using System.Buffers --- src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs index faef6cc9f14..a06bfe67c0d 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs @@ -13,7 +13,6 @@ #pragma warning disable 1634, 1691 using System; -using System.Buffers; using System.Text; using System.Runtime.InteropServices; using System.Management.Automation; From 63aff7ca646dc53d6325ddf44df9629786a93f8f Mon Sep 17 00:00:00 2001 From: Ilya Date: Fri, 22 Mar 2019 18:40:35 +0500 Subject: [PATCH 7/7] Make extern method private --- src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs index a06bfe67c0d..0a0775a18a5 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs @@ -3038,7 +3038,7 @@ IntPtr reserved [DllImport(PinvokeDllNames.ReadConsoleDllName, SetLastError = true, CharSet = CharSet.Unicode)] [return: MarshalAs(UnmanagedType.Bool)] - internal static extern unsafe bool ReadConsole + private static extern unsafe bool ReadConsole ( NakedWin32Handle consoleInput, char* lpBuffer,