diff --git a/ProtectionScan/Features/MainFeature.cs b/ProtectionScan/Features/MainFeature.cs index 61edd476..c19680fc 100644 --- a/ProtectionScan/Features/MainFeature.cs +++ b/ProtectionScan/Features/MainFeature.cs @@ -1,6 +1,9 @@ using System; using System.Collections.Generic; using System.IO; +#if NETCOREAPP +using System.Text.Json; +#endif using BinaryObjectScanner; using SabreTools.CommandLine; using SabreTools.CommandLine.Inputs; @@ -255,18 +258,14 @@ namespace ProtectionScan.Features try { - var jsonSerializerOptions = new System.Text.Json.JsonSerializerOptions { WriteIndented = true }; + var jsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true }; string serializedData; if (Nested) { // A nested dictionary is used to achieve proper serialization. - var nestedDictionary = new Dictionary(); - var trimmedPath = path.TrimEnd(['\\', '/']); - - // Move nested dictionary into final dictionary with the base path as a key. - //var finalDictionary = new Dictionary>(); - //finalDictionary.Add(trimmedPath, nestedDictionary); + Dictionary nestedDictionary = []; + path = path.TrimEnd(['\\', '/']); // Sort the keys for consistent output string[] keys = [.. protections.Keys]; @@ -287,7 +286,7 @@ namespace ProtectionScan.Features Array.Sort(fileProtections); // Inserts key and protections into nested dictionary, with the key trimmed of the base path. - InsertNode(nestedDictionary, key[trimmedPath.Length..], trimmedPath, fileProtections, modifyNodeList); + InsertNode(nestedDictionary, key, path, fileProtections, modifyNodeList); } // Adds the non-leaf-node protections back in @@ -301,14 +300,14 @@ namespace ProtectionScan.Features modifyNodeList[i].Item1[modifyNodeList[i].Item2] = modifyNode; } - + // Create the output data - serializedData = System.Text.Json.JsonSerializer.Serialize(nestedDictionary, jsonSerializerOptions); + serializedData = JsonSerializer.Serialize(nestedDictionary, jsonSerializerOptions); } else { // Create the output data - serializedData = System.Text.Json.JsonSerializer.Serialize(protections, jsonSerializerOptions); + serializedData = JsonSerializer.Serialize(protections, jsonSerializerOptions); } // Write the output data @@ -327,31 +326,37 @@ namespace ProtectionScan.Features /// /// Inserts file protection dictionary entries into a nested dictionary based on path /// - /// File or directory path - /// The "key" for the given protection entry, already trimmed of its base path - /// The scanned protection(s) for a given file - private static void InsertNode(Dictionary nestedDictionary, + /// Existing output dictionary + /// The key for the given protection entry + /// Original base path used for scanning + /// Set of protections found, if any + /// Set representing overlapping nodes to be processed after + private static void InsertNode(Dictionary dict, + string key, string path, - string fullPath, string[] protections, List<(Dictionary, string, string[])> modifyNodeList) { - var pathParts = path.Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries); - if (pathParts.Length <= 0) + // Remove the base path from the key for processing + key = key[path.Length..]; + + // Split the input path, if possible + var pathParts = key.Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries); + if (pathParts.Length == 0) { - modifyNodeList.Add((nestedDictionary, fullPath, protections)); + modifyNodeList.Add((dict, path, protections)); return; } - - if (!nestedDictionary.ContainsKey(fullPath)) - nestedDictionary[fullPath] = new Dictionary(); - var current = (Dictionary)nestedDictionary[fullPath]; - + // Create the node if it doesn't already exist + if (!dict.ContainsKey(path)) + dict[path] = new Dictionary(); + + var current = (Dictionary)dict[path]; + // Traverses the nested dictionary until the "leaf" dictionary is reached. for (int i = 0; i < pathParts.Length - 1; i++) { - var part = pathParts[i]; // Inserts new subdictionaries if one doesn't already exist @@ -376,23 +381,10 @@ namespace ProtectionScan.Features } // If the "leaf" dictionary has been reached, add the file and its protections. - if (current.ContainsKey(pathParts[^1])) + if (current.ContainsKey(pathParts[^1]) && current[pathParts[^1]] is string[] existing) { - var array1 = (string[])current[pathParts[^1]]; - var array2 = protections; - - string[] result = new string[array1.Length + array2.Length]; - for (int i = 0; i < array1.Length; i++) - { - result[i] = array1[i]; - } - - for (int i = 0; i < array2.Length; i++) - { - result[array1.Length + i] = array2[i]; - } - - current[pathParts[^1]] = result; + string[] combined = [.. existing, .. protections]; + current[pathParts[^1]] = combined; } else {