Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fuzz] Add Fuzz testing for RegistryPreview #37607

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
change public parser to internel and private
  • Loading branch information
chenmy77 committed Feb 26, 2025
commit a7b8a27f841a400df1831703ce8e8b536d914716
24 changes: 24 additions & 0 deletions src/modules/registrypreview/RegistryPreview.FuzzTests/FuzzTests.cs
Original file line number Diff line number Diff line change
@@ -142,6 +142,30 @@ public static void FuzzStripFirstAndLast(ReadOnlySpan<byte> input)

// 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
{
18 changes: 14 additions & 4 deletions src/modules/registrypreview/RegistryPreviewUILib/ParseHelper.cs
Original file line number Diff line number Diff line change
@@ -10,14 +10,14 @@

namespace RegistryPreviewUILib
{
public class ParseHelper
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>
public static void CheckKeyLineForBrackets(ref string registryLine, ref string imageName)
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(']');
@@ -81,7 +81,7 @@ private static bool CheckForKnownGoodBranches(string key)
/// Rip the first and last character off a string,
/// checking that the string is at least 2 characters long to avoid errors
/// </summary>
public static string StripFirstAndLast(string line)
internal static string StripFirstAndLast(string line)
{
if (line.Length > 1)
{
@@ -92,9 +92,19 @@ public static string StripFirstAndLast(string line)
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.
public static string ProcessRegistryLine(string registryLine)
internal static string ProcessRegistryLine(string registryLine)
{
if (registryLine.StartsWith("@=-", StringComparison.InvariantCulture))
{
Original file line number Diff line number Diff line change
@@ -225,7 +225,17 @@ 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.
registryLine = ParseHelper.ProcessRegistryLine(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)\"=");
}

// continue until we have nothing left to read
// switch logic, based off what the current line we're reading is
@@ -235,21 +245,21 @@ private bool ParseRegistryFile(string filenameText)
registryLine = registryLine.Remove(1, 1);

string imageName = DELETEDKEYIMAGE;
ParseHelper.CheckKeyLineForBrackets(ref registryLine, ref imageName);
CheckKeyLineForBrackets(ref registryLine, ref imageName);

// this is a key, so remove the first [ and last ]
registryLine = ParseHelper.StripFirstAndLast(registryLine);
registryLine = StripFirstAndLast(registryLine);

// do not track the result of this node, since it should have no children
AddTextToTree(registryLine, imageName);
}
else if (registryLine.StartsWith('['))
{
string imageName = KEYIMAGE;
ParseHelper.CheckKeyLineForBrackets(ref registryLine, ref imageName);
CheckKeyLineForBrackets(ref registryLine, ref imageName);

// this is a key, so remove the first [ and last ]
registryLine = ParseHelper.StripFirstAndLast(registryLine);
registryLine = StripFirstAndLast(registryLine);

treeViewNode = AddTextToTree(registryLine, imageName);
lastKeyPath = registryLine;
@@ -260,7 +270,7 @@ private bool ParseRegistryFile(string filenameText)
registryLine = registryLine.Replace("=-", string.Empty);

// remove the "'s without removing all of them
registryLine = ParseHelper.StripFirstAndLast(registryLine);
registryLine = 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);
@@ -290,7 +300,7 @@ private bool ParseRegistryFile(string filenameText)

// trim the whitespace and quotes from the name
name = name.Trim();
name = ParseHelper.StripFirstAndLast(name);
name = StripFirstAndLast(name);

// Clean out any escaped characters in the value, only for the preview
name = StripEscapedCharacters(name);
@@ -316,7 +326,7 @@ private bool ParseRegistryFile(string filenameText)

if (value.StartsWith('"') && value.EndsWith('"'))
{
value = ParseHelper.StripFirstAndLast(value);
value = StripFirstAndLast(value);
}
else
{
@@ -957,12 +967,7 @@ private void SaveFile()
/// </summary>
private string StripFirstAndLast(string line)
{
if (line.Length > 1)
{
line = line.Remove(line.Length - 1, 1);
line = line.Remove(0, 1);
}

line = ParseHelper.StripFirstAndLast(line);
return line;
}

@@ -1025,6 +1030,14 @@ private void SetValueToolTip(RegistryValue registryValue)
registryValue.ToolTipText = value;
}

/// <summary>
/// Checks a Key line for the closing bracket and treat it as an error if it cannot be found
/// </summary>
private void CheckKeyLineForBrackets(ref string registryLine, ref string imageName)
{
ParseHelper.CheckKeyLineForBrackets(ref registryLine, ref imageName);
}

/// <summary>
/// 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
/// </summary>