From 573461e4c264b299c2c232273d621062201a5f43 Mon Sep 17 00:00:00 2001 From: Andrew Schwartzmeyer Date: Thu, 28 Apr 2016 17:17:37 -0700 Subject: [PATCH] Fix comparison of keys in dispatch dictionary This compares the keys by a combination of their ConsoleKey and Modifiers fields. We cannot compare the KeyChar field as it is platform (and TTY configuration) dependent. --- .../KeyBindings.cs | 13 +++++++++++-- src/Microsoft.PowerShell.PSReadLine/Keys.cs | 18 +----------------- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/Microsoft.PowerShell.PSReadLine/KeyBindings.cs b/src/Microsoft.PowerShell.PSReadLine/KeyBindings.cs index 5216933c0e..8fff509483 100644 --- a/src/Microsoft.PowerShell.PSReadLine/KeyBindings.cs +++ b/src/Microsoft.PowerShell.PSReadLine/KeyBindings.cs @@ -82,12 +82,21 @@ namespace Microsoft.PowerShell { public bool Equals(ConsoleKeyInfo x, ConsoleKeyInfo y) { - return x.Key == y.Key && x.KeyChar == y.KeyChar && x.Modifiers == y.Modifiers; + // We *must not* compare the KeyChar field as its value is platform-dependent. + // We compare exactly the ConsoleKey enum field (which is platform-agnostic) + // and the modifiers. + + return x.Key == y.Key && x.Modifiers == y.Modifiers; } public int GetHashCode(ConsoleKeyInfo obj) { - return obj.GetHashCode(); + // Because a comparison of two ConsoleKeyInfo objects is a comparison of the + // combination of the ConsoleKey and Modifiers, we must combine their hashes. + // This is based on Tuple.GetHashCode + int h1 = obj.Key.GetHashCode(); + int h2 = obj.Modifiers.GetHashCode(); + return unchecked(((h1 << 5) + h1) ^ h2); } } diff --git a/src/Microsoft.PowerShell.PSReadLine/Keys.cs b/src/Microsoft.PowerShell.PSReadLine/Keys.cs index dbd1389911..5cf1975d67 100644 --- a/src/Microsoft.PowerShell.PSReadLine/Keys.cs +++ b/src/Microsoft.PowerShell.PSReadLine/Keys.cs @@ -11,22 +11,6 @@ namespace Microsoft.PowerShell { internal static class Keys { - static Keys() - { -#if CORECLR - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - { - Enter = new ConsoleKeyInfo((char)10, ConsoleKey.Enter, false, false, false); - } - else - { - Enter = new ConsoleKeyInfo((char)13, ConsoleKey.Enter, false, false, false); - } -#else - Enter = new ConsoleKeyInfo((char)13, ConsoleKey.Enter, false, false, false); -#endif - } - public static ConsoleKeyInfo A = new ConsoleKeyInfo('a', ConsoleKey.A, false, false, false); public static ConsoleKeyInfo B = new ConsoleKeyInfo('b', ConsoleKey.B, false, false, false); public static ConsoleKeyInfo C = new ConsoleKeyInfo('c', ConsoleKey.C, false, false, false); @@ -224,7 +208,7 @@ namespace Microsoft.PowerShell public static ConsoleKeyInfo End = new ConsoleKeyInfo((char)0, ConsoleKey.End, false, false, false); public static ConsoleKeyInfo CtrlEnd = new ConsoleKeyInfo((char)0, ConsoleKey.End, false, false, true); public static ConsoleKeyInfo ShiftEnd = new ConsoleKeyInfo((char)0, ConsoleKey.End, true, false, false); - public static ConsoleKeyInfo Enter; + public static ConsoleKeyInfo Enter = new ConsoleKeyInfo((char)13, ConsoleKey.Enter, false, false, false); public static ConsoleKeyInfo Escape = new ConsoleKeyInfo((char)27, ConsoleKey.Escape, false, false, false); public static ConsoleKeyInfo Home = new ConsoleKeyInfo((char)0, ConsoleKey.Home, false, false, false); public static ConsoleKeyInfo CtrlHome = new ConsoleKeyInfo((char)0, ConsoleKey.Home, false, false, true);