diff --git a/PowerToys.sln b/PowerToys.sln index 7a5f2831d876..5682f06179e3 100644 --- a/PowerToys.sln +++ b/PowerToys.sln @@ -644,6 +644,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerEditorLibrar EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hosts.FuzzTests", "src\modules\Hosts\Hosts.FuzzTests\Hosts.FuzzTests.csproj", "{EBED240C-8702-452D-B764-6DB9DA9179AF}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RegistryPreview.FuzzTests", "src\modules\registrypreview\RegistryPreview.FuzzTests\RegistryPreview.FuzzTests.csproj", "{50A9F3DE-CF0B-4CF0-AFDE-3A3E245D7734}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM64 = Debug|ARM64 @@ -2252,20 +2254,14 @@ Global {CA7D8106-30B9-4AEC-9D05-B69B31B8C461}.Release|ARM64.Build.0 = Release|ARM64 {CA7D8106-30B9-4AEC-9D05-B69B31B8C461}.Release|x64.ActiveCfg = Release|x64 {CA7D8106-30B9-4AEC-9D05-B69B31B8C461}.Release|x64.Build.0 = Release|x64 - {CA7D8106-30B9-4AEC-9D05-B69B31B8C461}.Release|x86.ActiveCfg = Release|x64 - {CA7D8106-30B9-4AEC-9D05-B69B31B8C461}.Release|x86.Build.0 = Release|x64 {A558C25D-2007-498E-8B6F-43405AFAE9E2}.Debug|ARM64.ActiveCfg = Debug|ARM64 {A558C25D-2007-498E-8B6F-43405AFAE9E2}.Debug|ARM64.Build.0 = Debug|ARM64 {A558C25D-2007-498E-8B6F-43405AFAE9E2}.Debug|x64.ActiveCfg = Debug|x64 {A558C25D-2007-498E-8B6F-43405AFAE9E2}.Debug|x64.Build.0 = Debug|x64 - {A558C25D-2007-498E-8B6F-43405AFAE9E2}.Debug|x86.ActiveCfg = Debug|x64 - {A558C25D-2007-498E-8B6F-43405AFAE9E2}.Debug|x86.Build.0 = Debug|x64 {A558C25D-2007-498E-8B6F-43405AFAE9E2}.Release|ARM64.ActiveCfg = Release|ARM64 {A558C25D-2007-498E-8B6F-43405AFAE9E2}.Release|ARM64.Build.0 = Release|ARM64 {A558C25D-2007-498E-8B6F-43405AFAE9E2}.Release|x64.ActiveCfg = Release|x64 {A558C25D-2007-498E-8B6F-43405AFAE9E2}.Release|x64.Build.0 = Release|x64 - {A558C25D-2007-498E-8B6F-43405AFAE9E2}.Release|x86.ActiveCfg = Release|x64 - {A558C25D-2007-498E-8B6F-43405AFAE9E2}.Release|x86.Build.0 = Release|x64 {08F9155D-B6DC-46E5-9C83-AF60B655898B}.Debug|ARM64.ActiveCfg = Debug|ARM64 {08F9155D-B6DC-46E5-9C83-AF60B655898B}.Debug|ARM64.Build.0 = Debug|ARM64 {08F9155D-B6DC-46E5-9C83-AF60B655898B}.Debug|x64.ActiveCfg = Debug|x64 @@ -2290,6 +2286,14 @@ Global {EBED240C-8702-452D-B764-6DB9DA9179AF}.Release|ARM64.Build.0 = Release|ARM64 {EBED240C-8702-452D-B764-6DB9DA9179AF}.Release|x64.ActiveCfg = Release|x64 {EBED240C-8702-452D-B764-6DB9DA9179AF}.Release|x64.Build.0 = Release|x64 + {50A9F3DE-CF0B-4CF0-AFDE-3A3E245D7734}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {50A9F3DE-CF0B-4CF0-AFDE-3A3E245D7734}.Debug|ARM64.Build.0 = Debug|ARM64 + {50A9F3DE-CF0B-4CF0-AFDE-3A3E245D7734}.Debug|x64.ActiveCfg = Debug|x64 + {50A9F3DE-CF0B-4CF0-AFDE-3A3E245D7734}.Debug|x64.Build.0 = Debug|x64 + {50A9F3DE-CF0B-4CF0-AFDE-3A3E245D7734}.Release|ARM64.ActiveCfg = Release|ARM64 + {50A9F3DE-CF0B-4CF0-AFDE-3A3E245D7734}.Release|ARM64.Build.0 = Release|ARM64 + {50A9F3DE-CF0B-4CF0-AFDE-3A3E245D7734}.Release|x64.ActiveCfg = Release|x64 + {50A9F3DE-CF0B-4CF0-AFDE-3A3E245D7734}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2529,6 +2533,7 @@ Global {08F9155D-B6DC-46E5-9C83-AF60B655898B} = {38BDB927-829B-4C65-9CD9-93FB05D66D65} {4382A954-179A-4078-92AF-715187DFFF50} = {38BDB927-829B-4C65-9CD9-93FB05D66D65} {EBED240C-8702-452D-B764-6DB9DA9179AF} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA} + {50A9F3DE-CF0B-4CF0-AFDE-3A3E245D7734} = {929C1324-22E8-4412-A9A8-80E85F3985A5} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0} diff --git a/src/modules/registrypreview/RegistryPreview.FuzzTests/FuzzTests.cs b/src/modules/registrypreview/RegistryPreview.FuzzTests/FuzzTests.cs new file mode 100644 index 000000000000..b0ebfa3c5e48 --- /dev/null +++ b/src/modules/registrypreview/RegistryPreview.FuzzTests/FuzzTests.cs @@ -0,0 +1,177 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +using System; +using System.Diagnostics; +using System.Globalization; +using System.Resources; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.Win32; +using RegistryPreviewUILib; + +namespace RegistryPreview.FuzzTests +{ + public class FuzzTests + { + private const string REGISTRYHEADER4 = "regedit4"; + private const string REGISTRYHEADER5 = "windows registry editor version 5.00"; + private const string KEYIMAGE = "ms-appx:///Assets/RegistryPreview/folder32.png"; + private const string DELETEDKEYIMAGE = "ms-appx:///Assets/RegistryPreview/deleted-folder32.png"; + + // Case 1: Fuzz test for CheckKeyLineForBrackets + public static void FuzzCheckKeyLineForBrackets(ReadOnlySpan input) + { + string registryLine; + + // Simulate registry file content as filenameText + var filenameText = GenerateRegistryHeader(input); + + string[] registryLines = filenameText.Split("\r"); + + if (registryLines.Length <= 1) + { + return; + } + + // REG files have to start with one of two headers and it's case-insensitive + // The header in the registry file is either REGISTRYHEADER4 or REGISTRYHEADER5 + registryLine = registryLines[0]; + + // Check if the registry header is valid + if (!IsValidRegistryHeader(registryLine)) + { + return; + } + + int index = 1; + registryLine = registryLines[index]; // Extract content after the header + + ParseHelper.ProcessRegistryLine(registryLine); + if (registryLine.StartsWith("[-", StringComparison.InvariantCulture)) + { + // remove the - as we won't need it but it will get special treatment in the UI + registryLine = registryLine.Remove(1, 1); + + string imageName = DELETEDKEYIMAGE; + + // Fuzz test for the CheckKeyLineForBrackets method + ParseHelper.CheckKeyLineForBrackets(ref registryLine, ref imageName); + } + else if (registryLine.StartsWith('[')) + { + string imageName = KEYIMAGE; + + // Fuzz test for the CheckKeyLineForBrackets method + ParseHelper.CheckKeyLineForBrackets(ref registryLine, ref imageName); + } + else + { + return; + } + } + + // Case 2: Fuzz test for StripFirstAndLast + public static void FuzzStripFirstAndLast(ReadOnlySpan input) + { + string registryLine; + + var filenameText = GenerateRegistryHeader(input); + + filenameText = filenameText.Replace("\r\n", "\r"); + string[] registryLines = filenameText.Split("\r"); + + if (registryLines.Length <= 1) + { + return; + } + + // REG files have to start with one of two headers and it's case-insensitive + registryLine = registryLines[0]; + + if (!IsValidRegistryHeader(registryLine)) + { + return; + } + + int index = 1; + registryLine = registryLines[index]; + + ParseHelper.ProcessRegistryLine(registryLine); + + if (registryLine.StartsWith("[-", StringComparison.InvariantCulture)) + { + // remove the - as we won't need it but it will get special treatment in the UI + registryLine = registryLine.Remove(1, 1); + + string imageName = DELETEDKEYIMAGE; + ParseHelper.CheckKeyLineForBrackets(ref registryLine, ref imageName); + + // Fuzz test for the StripFirstAndLast method + registryLine = ParseHelper.StripFirstAndLast(registryLine); + } + else if (registryLine.StartsWith('[')) + { + string imageName = KEYIMAGE; + ParseHelper.CheckKeyLineForBrackets(ref registryLine, ref imageName); + + // Fuzz test for the StripFirstAndLast method + registryLine = ParseHelper.StripFirstAndLast(registryLine); + } + else if (registryLine.StartsWith('"') && registryLine.EndsWith("=-", StringComparison.InvariantCulture)) + { + registryLine = registryLine.Replace("=-", string.Empty); + + // remove the "'s without removing all of them + // Fuzz test for the StripFirstAndLast method + registryLine = ParseHelper.StripFirstAndLast(registryLine); + } + else if (registryLine.StartsWith('"')) + { + int equal = registryLine.IndexOf('='); + if ((equal < 0) || (equal > registryLine.Length - 1)) + { + // something is very wrong + return; + } + + // set the name and the value + string name = registryLine.Substring(0, equal); + + // trim the whitespace and quotes from the name + name = name.Trim(); + + // Fuzz test for the StripFirstAndLast method + name = ParseHelper.StripFirstAndLast(name); + } + else + { + return; + } + } + + public static string GenerateRegistryHeader(ReadOnlySpan input) + { + string header = new Random().Next(2) == 0 ? REGISTRYHEADER4 : REGISTRYHEADER5; + + string inputText = System.Text.Encoding.UTF8.GetString(input); + string filenameText = header + "\r\n" + inputText; + + return filenameText.Replace("\r\n", "\r"); + } + + private static bool IsValidRegistryHeader(string line) + { + // Convert the line to lowercase once for comparison + var lineLower = line.ToLowerInvariant(); + + switch (line) + { + case REGISTRYHEADER4: + case REGISTRYHEADER5: + return true; + default: + return false; + } + } + } +} diff --git a/src/modules/registrypreview/RegistryPreview.FuzzTests/MSTestSettings.cs b/src/modules/registrypreview/RegistryPreview.FuzzTests/MSTestSettings.cs new file mode 100644 index 000000000000..5b05c0b86e3f --- /dev/null +++ b/src/modules/registrypreview/RegistryPreview.FuzzTests/MSTestSettings.cs @@ -0,0 +1,5 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)] diff --git a/src/modules/registrypreview/RegistryPreview.FuzzTests/OneFuzzConfig.json b/src/modules/registrypreview/RegistryPreview.FuzzTests/OneFuzzConfig.json new file mode 100644 index 000000000000..a074f41123f0 --- /dev/null +++ b/src/modules/registrypreview/RegistryPreview.FuzzTests/OneFuzzConfig.json @@ -0,0 +1,90 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +{ + "configVersion": 3, + "entries": [ + { + "fuzzer": { + "$type": "libfuzzerDotNet", + "dll": "RegistryPreview.FuzzTests.dll", + "class": "RegistryPreview.FuzzTests.FuzzTests", + "method": "FuzzCheckKeyLineForBrackets", + "FuzzingTargetBinaries": [ + "PowerToys.RegistryPreview.dll" + ] + }, + "adoTemplate": { + // supply the values appropriate to your + // project, where bugs will be filed + "org": "microsoft", + "project": "OS", + "AssignedTo": "mengyuanchen@microsoft.com", + "AreaPath": "OS\\Windows Client and Services\\WinPD\\DEEP-Developer Experience, Ecosystem and Partnerships\\SHINE\\PowerToys", + "IterationPath": "OS\\Future" + }, + "jobNotificationEmail": "mengyuanchen@microsoft.com", + "skip": false, + "rebootAfterSetup": false, + "oneFuzzJobs": [ + // at least one job is required + { + "projectName": "RegistryPreview", + "targetName": "RegistryPreview-dotnet-CheckKeyLineForBrackets-fuzzer" + } + ], + "jobDependencies": [ + // this should contain, at minimum, + // the DLL and PDB files + // you will need to add any other files required + // (globs are supported) + "RegistryPreview.FuzzTests.dll", + "RegistryPreview.FuzzTests.pdb", + "Microsoft.Windows.SDK.NET.dll", + "WinRT.Runtime.dll" + ], + "SdlWorkItemId": 49911822 + }, + { + "fuzzer": { + "$type": "libfuzzerDotNet", + "dll": "RegistryPreview.FuzzTests.dll", + "class": "RegistryPreview.FuzzTests.FuzzTests", + "method": "FuzzStripFirstAndLast", + "FuzzingTargetBinaries": [ + "PowerToys.RegistryPreview.dll" + ] + }, + "adoTemplate": { + // supply the values appropriate to your + // project, where bugs will be filed + "org": "microsoft", + "project": "OS", + "AssignedTo": "mengyuanchen@microsoft.com", + "AreaPath": "OS\\Windows Client and Services\\WinPD\\DEEP-Developer Experience, Ecosystem and Partnerships\\SHINE\\PowerToys", + "IterationPath": "OS\\Future" + }, + "jobNotificationEmail": "mengyuanchen@microsoft.com", + "skip": false, + "rebootAfterSetup": false, + "oneFuzzJobs": [ + // at least one job is required + { + "projectName": "RegistryPreview", + "targetName": "RegistryPreview-dotnet-StripFirstAndLasts-fuzzer" + } + ], + "jobDependencies": [ + // this should contain, at minimum, + // the DLL and PDB files + // you will need to add any other files required + // (globs are supported) + "RegistryPreview.FuzzTests.dll", + "RegistryPreview.FuzzTests.pdb", + "Microsoft.Windows.SDK.NET.dll", + "WinRT.Runtime.dll" + ], + "SdlWorkItemId": 49911822 + } + ] +} \ No newline at end of file diff --git a/src/modules/registrypreview/RegistryPreview.FuzzTests/RegistryPreview.FuzzTests.csproj b/src/modules/registrypreview/RegistryPreview.FuzzTests/RegistryPreview.FuzzTests.csproj new file mode 100644 index 000000000000..d59656463e3c --- /dev/null +++ b/src/modules/registrypreview/RegistryPreview.FuzzTests/RegistryPreview.FuzzTests.csproj @@ -0,0 +1,33 @@ + + + + net8.0-windows10.0.19041.0 + x64;ARM64 + latest + enable + enable + + + + ..\..\..\..\$(Platform)\$(Configuration)\tests\RegistryPreview.FuzzTests\ + + + + + + + + + PreserveNewest + + + + + + + + + + + + diff --git a/src/modules/registrypreview/RegistryPreviewUILib/ParseHelper.cs b/src/modules/registrypreview/RegistryPreviewUILib/ParseHelper.cs new file mode 100644 index 000000000000..cdfea8bcee05 --- /dev/null +++ b/src/modules/registrypreview/RegistryPreviewUILib/ParseHelper.cs @@ -0,0 +1,114 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RegistryPreviewUILib +{ + public class ParseHelper + { + private const string ERRORIMAGE = "ms-appx:///Assets/RegistryPreview/error32.png"; + + /// + /// Checks a Key line for the closing bracket and treat it as an error if it cannot be found + /// + public static void CheckKeyLineForBrackets(ref string registryLine, ref string imageName) + { + // following the current behavior of the registry editor, find the last ] and treat everything else as ignorable + int lastBracket = registryLine.LastIndexOf(']'); + if (lastBracket == -1) + { + // since we don't have a last bracket yet, add an extra space and continue processing + registryLine += " "; + imageName = ERRORIMAGE; + } + else + { + // having found the last ] and there is text after it, drop the rest of the string on the floor + if (lastBracket < registryLine.Length - 1) + { + registryLine = registryLine.Substring(0, lastBracket + 1); + } + + if (CheckForKnownGoodBranches(registryLine) == false) + { + imageName = ERRORIMAGE; + } + } + } + + /// + /// Make sure the root of a full path start with one of the five "hard coded" roots. Throw an error for the branch if it doesn't. + /// + private static bool CheckForKnownGoodBranches(string key) + { + if ((key.StartsWith("[HKEY_CLASSES_ROOT]", StringComparison.InvariantCultureIgnoreCase) == false && + key.StartsWith("[HKEY_CURRENT_USER]", StringComparison.InvariantCultureIgnoreCase) == false && + key.StartsWith("[HKEY_USERS]", StringComparison.InvariantCultureIgnoreCase) == false && + key.StartsWith("[HKEY_LOCAL_MACHINE]", StringComparison.InvariantCultureIgnoreCase) == false && + key.StartsWith("[HKEY_CURRENT_CONFIG]", StringComparison.InvariantCultureIgnoreCase) == false) + && + (key.StartsWith(@"[HKEY_CLASSES_ROOT\", StringComparison.InvariantCultureIgnoreCase) == false && + key.StartsWith(@"[HKEY_CURRENT_USER\", StringComparison.InvariantCultureIgnoreCase) == false && + key.StartsWith(@"[HKEY_USERS\", StringComparison.InvariantCultureIgnoreCase) == false && + key.StartsWith(@"[HKEY_LOCAL_MACHINE\", StringComparison.InvariantCultureIgnoreCase) == false && + key.StartsWith(@"[HKEY_CURRENT_CONFIG\", StringComparison.InvariantCultureIgnoreCase) == false) + && + (key.StartsWith("[HKCR]", StringComparison.InvariantCultureIgnoreCase) == false && + key.StartsWith("[HKCU]", StringComparison.InvariantCultureIgnoreCase) == false && + key.StartsWith("[HKU]", StringComparison.InvariantCultureIgnoreCase) == false && + key.StartsWith("[HKLM]", StringComparison.InvariantCultureIgnoreCase) == false && + key.StartsWith("[HKCC]", StringComparison.InvariantCultureIgnoreCase) == false) + && + (key.StartsWith(@"[HKCR\", StringComparison.InvariantCultureIgnoreCase) == false && + key.StartsWith(@"[HKCU\", StringComparison.InvariantCultureIgnoreCase) == false && + key.StartsWith(@"[HKU\", StringComparison.InvariantCultureIgnoreCase) == false && + key.StartsWith(@"[HKLM\", StringComparison.InvariantCultureIgnoreCase) == false && + key.StartsWith(@"[HKCC\", StringComparison.InvariantCultureIgnoreCase) == false)) + { + return false; + } + + return true; + } + + /// + /// Rip the first and last character off a string, + /// checking that the string is at least 2 characters long to avoid errors + /// + public static string StripFirstAndLast(string line) + { + if (line.Length > 1) + { + line = line.Remove(line.Length - 1, 1); + line = line.Remove(0, 1); + } + + return line; + } + + // special case for when the registryLine begins with a @ - make some tweaks and + // let the regular processing handle the rest. + public static string ProcessRegistryLine(string registryLine) + { + if (registryLine.StartsWith("@=-", StringComparison.InvariantCulture)) + { + // REG file has a callout to delete the @ Value which won't work *but* the Registry Editor will + // clear the value of the @ Value instead, so it's still a valid line. + registryLine = registryLine.Replace("@=-", "\"(Default)\"=\"\""); + } + else if (registryLine.StartsWith("@=", StringComparison.InvariantCulture)) + { + // This is the Value called "(Default)" so we tweak the line for the UX + registryLine = registryLine.Replace("@=", "\"(Default)\"="); + } + + return registryLine; + } + } +} diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs index b8fc6e4e1d9a..d35a43ca99e2 100644 --- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs +++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs @@ -225,17 +225,7 @@ private bool ParseRegistryFile(string filenameText) { // special case for when the registryLine begins with a @ - make some tweaks and // let the regular processing handle the rest. - if (registryLine.StartsWith("@=-", StringComparison.InvariantCulture)) - { - // REG file has a callout to delete the @ Value which won't work *but* the Registry Editor will - // clear the value of the @ Value instead, so it's still a valid line. - registryLine = registryLine.Replace("@=-", "\"(Default)\"=\"\""); - } - else if (registryLine.StartsWith("@=", StringComparison.InvariantCulture)) - { - // This is the Value called "(Default)" so we tweak the line for the UX - registryLine = registryLine.Replace("@=", "\"(Default)\"="); - } + registryLine = ParseHelper.ProcessRegistryLine(registryLine); // continue until we have nothing left to read // switch logic, based off what the current line we're reading is @@ -245,10 +235,10 @@ private bool ParseRegistryFile(string filenameText) registryLine = registryLine.Remove(1, 1); string imageName = DELETEDKEYIMAGE; - CheckKeyLineForBrackets(ref registryLine, ref imageName); + ParseHelper.CheckKeyLineForBrackets(ref registryLine, ref imageName); // this is a key, so remove the first [ and last ] - registryLine = StripFirstAndLast(registryLine); + registryLine = ParseHelper.StripFirstAndLast(registryLine); // do not track the result of this node, since it should have no children AddTextToTree(registryLine, imageName); @@ -256,10 +246,10 @@ private bool ParseRegistryFile(string filenameText) else if (registryLine.StartsWith('[')) { string imageName = KEYIMAGE; - CheckKeyLineForBrackets(ref registryLine, ref imageName); + ParseHelper.CheckKeyLineForBrackets(ref registryLine, ref imageName); // this is a key, so remove the first [ and last ] - registryLine = StripFirstAndLast(registryLine); + registryLine = ParseHelper.StripFirstAndLast(registryLine); treeViewNode = AddTextToTree(registryLine, imageName); lastKeyPath = registryLine; @@ -270,7 +260,7 @@ private bool ParseRegistryFile(string filenameText) registryLine = registryLine.Replace("=-", string.Empty); // remove the "'s without removing all of them - registryLine = StripFirstAndLast(registryLine); + registryLine = ParseHelper.StripFirstAndLast(registryLine); // Create a new listview item that will be used to display the delete value and store it registryValue = new RegistryValue(registryLine, string.Empty, string.Empty, lastKeyPath); @@ -300,7 +290,7 @@ private bool ParseRegistryFile(string filenameText) // trim the whitespace and quotes from the name name = name.Trim(); - name = StripFirstAndLast(name); + name = ParseHelper.StripFirstAndLast(name); // Clean out any escaped characters in the value, only for the preview name = StripEscapedCharacters(name); @@ -326,7 +316,7 @@ private bool ParseRegistryFile(string filenameText) if (value.StartsWith('"') && value.EndsWith('"')) { - value = StripFirstAndLast(value); + value = ParseHelper.StripFirstAndLast(value); } else { @@ -1035,34 +1025,6 @@ private void SetValueToolTip(RegistryValue registryValue) registryValue.ToolTipText = value; } - /// - /// Checks a Key line for the closing bracket and treat it as an error if it cannot be found - /// - private void CheckKeyLineForBrackets(ref string registryLine, ref string imageName) - { - // following the current behavior of the registry editor, find the last ] and treat everything else as ignorable - int lastBracket = registryLine.LastIndexOf(']'); - if (lastBracket == -1) - { - // since we don't have a last bracket yet, add an extra space and continue processing - registryLine += " "; - imageName = ERRORIMAGE; - } - else - { - // having found the last ] and there is text after it, drop the rest of the string on the floor - if (lastBracket < registryLine.Length - 1) - { - registryLine = registryLine.Substring(0, lastBracket + 1); - } - - if (CheckForKnownGoodBranches(registryLine) == false) - { - imageName = ERRORIMAGE; - } - } - } - /// /// Takes a binary registry value, sees if it has a ; and dumps the rest of the line - this does not work for REG_SZ values /// @@ -1079,41 +1041,6 @@ private string ScanAndRemoveComments(string value) return value.TrimEnd(); } - /// - /// Make sure the root of a full path start with one of the five "hard coded" roots. Throw an error for the branch if it doesn't. - /// - private bool CheckForKnownGoodBranches(string key) - { - if ((key.StartsWith("[HKEY_CLASSES_ROOT]", StringComparison.InvariantCultureIgnoreCase) == false && - key.StartsWith("[HKEY_CURRENT_USER]", StringComparison.InvariantCultureIgnoreCase) == false && - key.StartsWith("[HKEY_USERS]", StringComparison.InvariantCultureIgnoreCase) == false && - key.StartsWith("[HKEY_LOCAL_MACHINE]", StringComparison.InvariantCultureIgnoreCase) == false && - key.StartsWith("[HKEY_CURRENT_CONFIG]", StringComparison.InvariantCultureIgnoreCase) == false) - && - (key.StartsWith(@"[HKEY_CLASSES_ROOT\", StringComparison.InvariantCultureIgnoreCase) == false && - key.StartsWith(@"[HKEY_CURRENT_USER\", StringComparison.InvariantCultureIgnoreCase) == false && - key.StartsWith(@"[HKEY_USERS\", StringComparison.InvariantCultureIgnoreCase) == false && - key.StartsWith(@"[HKEY_LOCAL_MACHINE\", StringComparison.InvariantCultureIgnoreCase) == false && - key.StartsWith(@"[HKEY_CURRENT_CONFIG\", StringComparison.InvariantCultureIgnoreCase) == false) - && - (key.StartsWith("[HKCR]", StringComparison.InvariantCultureIgnoreCase) == false && - key.StartsWith("[HKCU]", StringComparison.InvariantCultureIgnoreCase) == false && - key.StartsWith("[HKU]", StringComparison.InvariantCultureIgnoreCase) == false && - key.StartsWith("[HKLM]", StringComparison.InvariantCultureIgnoreCase) == false && - key.StartsWith("[HKCC]", StringComparison.InvariantCultureIgnoreCase) == false) - && - (key.StartsWith(@"[HKCR\", StringComparison.InvariantCultureIgnoreCase) == false && - key.StartsWith(@"[HKCU\", StringComparison.InvariantCultureIgnoreCase) == false && - key.StartsWith(@"[HKU\", StringComparison.InvariantCultureIgnoreCase) == false && - key.StartsWith(@"[HKLM\", StringComparison.InvariantCultureIgnoreCase) == false && - key.StartsWith(@"[HKCC\", StringComparison.InvariantCultureIgnoreCase) == false)) - { - return false; - } - - return true; - } - /// /// Turns the Open Key button in the command bar on/off, depending on if a key is selected ///