mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-08 12:18:50 +02:00
[Fuzz] Add Fuzz testing for RegistryPreview (#37607)
* Add fuzz test cases
* add fuzz tests framework in registrypreview
* add registrypreview fuzzing code
* add annotations and change net7.0--net8.0
* merge main into code
* add registry fuzz sln
* change fuzzing tests scope
* remove unuse annotations
* fix typos
* change public parser to internel and private
* fix linelower error and modify filenametext to registryContent
* Revert "fix linelower error and modify filenametext to registryContent"
This reverts commit e8269b8af2.
* add fuzz tests in sln
* modify typos
* clean code
Co-authored-by: leileizhang <leilzh@microsoft.com>
* add annotations
---------
Co-authored-by: leileizhang <leilzh@microsoft.com>
This commit is contained in:
@@ -646,6 +646,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hosts.FuzzTests", "src\modu
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hosts.UITests", "src\modules\Hosts\Hosts.UITests\Hosts.UITests.csproj", "{4E0AE3A4-2EE0-44D7-A2D0-8769977254A0}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hosts.UITests", "src\modules\Hosts\Hosts.UITests\Hosts.UITests.csproj", "{4E0AE3A4-2EE0-44D7-A2D0-8769977254A0}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RegistryPreview.FuzzTests", "src\modules\registrypreview\RegistryPreview.FuzzTests\RegistryPreview.FuzzTests.csproj", "{5702B3CC-8575-48D5-83D8-15BB42269CD3}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|ARM64 = Debug|ARM64
|
Debug|ARM64 = Debug|ARM64
|
||||||
@@ -2294,6 +2296,14 @@ Global
|
|||||||
{4E0AE3A4-2EE0-44D7-A2D0-8769977254A0}.Release|ARM64.Build.0 = Release|ARM64
|
{4E0AE3A4-2EE0-44D7-A2D0-8769977254A0}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
{4E0AE3A4-2EE0-44D7-A2D0-8769977254A0}.Release|x64.ActiveCfg = Release|x64
|
{4E0AE3A4-2EE0-44D7-A2D0-8769977254A0}.Release|x64.ActiveCfg = Release|x64
|
||||||
{4E0AE3A4-2EE0-44D7-A2D0-8769977254A0}.Release|x64.Build.0 = Release|x64
|
{4E0AE3A4-2EE0-44D7-A2D0-8769977254A0}.Release|x64.Build.0 = Release|x64
|
||||||
|
{5702B3CC-8575-48D5-83D8-15BB42269CD3}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
|
{5702B3CC-8575-48D5-83D8-15BB42269CD3}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
|
{5702B3CC-8575-48D5-83D8-15BB42269CD3}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{5702B3CC-8575-48D5-83D8-15BB42269CD3}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{5702B3CC-8575-48D5-83D8-15BB42269CD3}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||||
|
{5702B3CC-8575-48D5-83D8-15BB42269CD3}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
|
{5702B3CC-8575-48D5-83D8-15BB42269CD3}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{5702B3CC-8575-48D5-83D8-15BB42269CD3}.Release|x64.Build.0 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@@ -2534,6 +2544,7 @@ Global
|
|||||||
{4382A954-179A-4078-92AF-715187DFFF50} = {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}
|
{EBED240C-8702-452D-B764-6DB9DA9179AF} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}
|
||||||
{4E0AE3A4-2EE0-44D7-A2D0-8769977254A0} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}
|
{4E0AE3A4-2EE0-44D7-A2D0-8769977254A0} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}
|
||||||
|
{5702B3CC-8575-48D5-83D8-15BB42269CD3} = {929C1324-22E8-4412-A9A8-80E85F3985A5}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}
|
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}
|
||||||
|
|||||||
@@ -0,0 +1,200 @@
|
|||||||
|
// 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<byte> input)
|
||||||
|
{
|
||||||
|
string registryLine;
|
||||||
|
|
||||||
|
// Simulate registry file content as registryContent
|
||||||
|
var registryContent = GenerateRegistryHeader(input);
|
||||||
|
|
||||||
|
string[] registryLines = registryContent.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<byte> input)
|
||||||
|
{
|
||||||
|
string registryLine;
|
||||||
|
|
||||||
|
var registryContent = GenerateRegistryHeader(input);
|
||||||
|
|
||||||
|
registryContent = registryContent.Replace("\r\n", "\r");
|
||||||
|
string[] registryLines = registryContent.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))
|
||||||
|
{
|
||||||
|
// remove "=-"
|
||||||
|
registryLine = registryLine[..^2];
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// Clean out any escaped characters in the value, only for the preview
|
||||||
|
name = ParseHelper.StripEscapedCharacters(name);
|
||||||
|
|
||||||
|
// set the value
|
||||||
|
string value = registryLine.Substring(equal + 1);
|
||||||
|
|
||||||
|
// trim the whitespace from the value
|
||||||
|
value = value.Trim();
|
||||||
|
|
||||||
|
// if the first character is a " then this is a string value, so find the last most " which will avoid comments
|
||||||
|
if (value.StartsWith('"'))
|
||||||
|
{
|
||||||
|
int last = value.LastIndexOf('"');
|
||||||
|
if (last >= 0)
|
||||||
|
{
|
||||||
|
value = value.Substring(0, last + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.StartsWith('"') && value.EndsWith('"'))
|
||||||
|
{
|
||||||
|
value = ParseHelper.StripFirstAndLast(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GenerateRegistryHeader(ReadOnlySpan<byte> input)
|
||||||
|
{
|
||||||
|
string header = new Random().Next(2) == 0 ? REGISTRYHEADER4 : REGISTRYHEADER5;
|
||||||
|
|
||||||
|
string inputText = System.Text.Encoding.UTF8.GetString(input);
|
||||||
|
string registryContent = header + "\r" + inputText;
|
||||||
|
|
||||||
|
return registryContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsValidRegistryHeader(string line)
|
||||||
|
{
|
||||||
|
// Convert the line to lowercase once for comparison
|
||||||
|
switch (line)
|
||||||
|
{
|
||||||
|
case REGISTRYHEADER4:
|
||||||
|
case REGISTRYHEADER5:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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)]
|
||||||
@@ -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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
|
||||||
|
<Platforms>x64;ARM64</Platforms>
|
||||||
|
<LangVersion>latest</LangVersion>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputPath>..\..\..\..\$(Platform)\$(Configuration)\tests\RegistryPreview.FuzzTests\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="..\RegistryPreviewUILib\ParseHelper.cs" Link="ParseHelper.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="OneFuzzConfig.json">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="MSTest" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Using Include="Microsoft.VisualStudio.TestTools.UnitTesting" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
124
src/modules/registrypreview/RegistryPreviewUILib/ParseHelper.cs
Normal file
124
src/modules/registrypreview/RegistryPreviewUILib/ParseHelper.cs
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
// 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
|
||||||
|
{
|
||||||
|
internal static class ParseHelper
|
||||||
|
{
|
||||||
|
private const string ERRORIMAGE = "ms-appx:///Assets/RegistryPreview/error32.png";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks a Key line for the closing bracket and treat it as an error if it cannot be found
|
||||||
|
/// </summary>
|
||||||
|
internal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 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.
|
||||||
|
/// </summary>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Rip the first and last character off a string,
|
||||||
|
/// checking that the string is at least 2 characters long to avoid errors
|
||||||
|
/// </summary>
|
||||||
|
internal static string StripFirstAndLast(string line)
|
||||||
|
{
|
||||||
|
if (line.Length > 1)
|
||||||
|
{
|
||||||
|
line = line.Remove(line.Length - 1, 1);
|
||||||
|
line = line.Remove(0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Replace any escaped characters in the REG file with their counterparts, for the UX
|
||||||
|
/// </summary>
|
||||||
|
internal static string StripEscapedCharacters(string value)
|
||||||
|
{
|
||||||
|
value = value.Replace("\\\\", "\\"); // Replace \\ with \ in the UI
|
||||||
|
value = value.Replace("\\\"", "\""); // Replace \" with " in the UI
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// special case for when the registryLine begins with a @ - make some tweaks and
|
||||||
|
// let the regular processing handle the rest.
|
||||||
|
internal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -967,12 +967,7 @@ namespace RegistryPreviewUILib
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private string StripFirstAndLast(string line)
|
private string StripFirstAndLast(string line)
|
||||||
{
|
{
|
||||||
if (line.Length > 1)
|
line = ParseHelper.StripFirstAndLast(line);
|
||||||
{
|
|
||||||
line = line.Remove(line.Length - 1, 1);
|
|
||||||
line = line.Remove(0, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1040,27 +1035,7 @@ namespace RegistryPreviewUILib
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void CheckKeyLineForBrackets(ref string registryLine, ref string imageName)
|
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
|
ParseHelper.CheckKeyLineForBrackets(ref registryLine, ref imageName);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1079,41 +1054,6 @@ namespace RegistryPreviewUILib
|
|||||||
return value.TrimEnd();
|
return value.TrimEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 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.
|
|
||||||
/// </summary>
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Turns the Open Key button in the command bar on/off, depending on if a key is selected
|
/// Turns the Open Key button in the command bar on/off, depending on if a key is selected
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user