/ src / modules / launcher / Plugins / Community.PowerToys.Run.Plugin.ValueGenerator / InputParser.cs
InputParser.cs
1 // Copyright (c) Microsoft Corporation 2 // The Microsoft Corporation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System; 6 using System.Security.Cryptography; 7 using System.Text; 8 9 using Community.PowerToys.Run.Plugin.ValueGenerator.Base64; 10 using Community.PowerToys.Run.Plugin.ValueGenerator.GUID; 11 using Community.PowerToys.Run.Plugin.ValueGenerator.Hashing; 12 using Community.PowerToys.Run.Plugin.ValueGenerator.Uri; 13 using Wox.Plugin; 14 using Wox.Plugin.Logger; 15 16 namespace Community.PowerToys.Run.Plugin.ValueGenerator 17 { 18 public class InputParser 19 { 20 public IComputeRequest ParseInput(Query query) 21 { 22 IComputeRequest request; 23 24 if (query.Terms.Count == 0) 25 { 26 throw new FormatException("Empty request"); 27 } 28 29 string command = query.Terms[0]; 30 31 if (command.Equals("md5", StringComparison.OrdinalIgnoreCase)) 32 { 33 int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase); 34 string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim(); 35 36 if (content == string.Empty) 37 { 38 throw new FormatException("Empty hash request"); 39 } 40 41 Log.Debug($"Will calculate MD5 hash for: {content}", GetType()); 42 request = new HashRequest(HashAlgorithmName.MD5, Encoding.UTF8.GetBytes(content)); 43 } 44 else if (command.StartsWith("sha", StringComparison.InvariantCultureIgnoreCase)) 45 { 46 int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase); 47 string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim(); 48 HashAlgorithmName algorithmName; 49 50 switch (command.Substring(3)) 51 { 52 case "1": 53 algorithmName = HashAlgorithmName.SHA1; 54 break; 55 56 case "256": 57 algorithmName = HashAlgorithmName.SHA256; 58 break; 59 60 case "384": 61 algorithmName = HashAlgorithmName.SHA384; 62 break; 63 64 case "512": 65 algorithmName = HashAlgorithmName.SHA512; 66 break; 67 default: 68 throw new FormatException("Unknown SHA variant. Supported variants: SHA1, SHA256, SHA384, SHA512"); 69 } 70 71 if (content == string.Empty) 72 { 73 throw new FormatException("Empty hash request"); 74 } 75 76 Log.Debug($"Will calculate {algorithmName} hash for: {content}", GetType()); 77 request = new HashRequest(algorithmName, Encoding.UTF8.GetBytes(content)); 78 } 79 else if (command.StartsWith("guid", StringComparison.InvariantCultureIgnoreCase) || 80 command.StartsWith("uuid", StringComparison.InvariantCultureIgnoreCase)) 81 { 82 string content = query.Search.Substring(command.Length).Trim(); 83 84 // Default to version 4 85 int version = 4; 86 string versionQuery = command.Substring(4); 87 88 if (versionQuery.Length > 0) 89 { 90 if (versionQuery.StartsWith("v", StringComparison.InvariantCultureIgnoreCase)) 91 { 92 versionQuery = versionQuery.Substring(1); 93 } 94 95 if (!int.TryParse(versionQuery, null, out version)) 96 { 97 throw new FormatException("Could not determine requested GUID version. Supported versions are 1, 3, 4, 5, and 7"); 98 } 99 } 100 101 if (version == 3 || version == 5) 102 { 103 string[] sParameters = content.Split(" "); 104 105 if (sParameters.Length != 2) 106 { 107 throw new ArgumentException($"GUID version {version} require 2 parameters - a namespace GUID and a name.\nExample: uuidv{version} ns:<DNS, URL, OID, or X500> <your input>"); 108 } 109 110 string namespaceParameter = sParameters[0]; 111 string nameParameter = sParameters[1]; 112 113 request = new GUIDRequest(version, namespaceParameter, nameParameter); 114 } 115 else 116 { 117 request = new GUIDRequest(version); 118 } 119 } 120 else if (command.Equals("base64", StringComparison.OrdinalIgnoreCase)) 121 { 122 int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase); 123 string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim(); 124 request = new Base64Request(Encoding.UTF8.GetBytes(content)); 125 } 126 else if (command.Equals("base64d", StringComparison.OrdinalIgnoreCase)) 127 { 128 int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase); 129 string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim(); 130 request = new Base64DecodeRequest(content); 131 } 132 else if (command.StartsWith("esc:", StringComparison.OrdinalIgnoreCase)) 133 { 134 // Escape things 135 if (command.Equals("esc:data", StringComparison.OrdinalIgnoreCase)) 136 { 137 int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase); 138 string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim(); 139 request = new DataEscapeRequest(content); 140 } 141 else if (command.Equals("esc:hex", StringComparison.OrdinalIgnoreCase)) 142 { 143 int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase); 144 string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim(); 145 146 // This is only for single chars 147 if (content.Length > 1) 148 { 149 throw new ArgumentException($"Invalid Query: {query.RawUserQuery} (Too many characters.)"); 150 } 151 else if (content.Length == 0) 152 { 153 throw new FormatException($"Invalid Query: {query.RawUserQuery}"); 154 } 155 156 request = new HexEscapeRequest(content); 157 } 158 else 159 { 160 throw new FormatException($"Invalid Query: {query.RawUserQuery}"); 161 } 162 } 163 else if (command.StartsWith("uesc:", StringComparison.OrdinalIgnoreCase)) 164 { 165 // Unescape things 166 if (command.Equals("uesc:data", StringComparison.OrdinalIgnoreCase)) 167 { 168 int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase); 169 string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim(); 170 request = new DataUnescapeRequest(content); 171 } 172 else if (command.Equals("uesc:hex", StringComparison.OrdinalIgnoreCase)) 173 { 174 int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase); 175 string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim(); 176 request = new HexUnescapeRequest(content); 177 } 178 else 179 { 180 throw new FormatException($"Invalid Query: {query.RawUserQuery}"); 181 } 182 } 183 else if (command.Equals("url", StringComparison.OrdinalIgnoreCase)) 184 { 185 int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase); 186 string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim(); 187 request = new UrlEncodeRequest(content); 188 } 189 else if (command.Equals("urld", StringComparison.OrdinalIgnoreCase)) 190 { 191 int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase); 192 string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim(); 193 request = new UrlDecodeRequest(content); 194 } 195 else 196 { 197 throw new FormatException($"Invalid Query: {query.RawUserQuery}"); 198 } 199 200 return request; 201 } 202 } 203 }