From 1602437c319a66fa95f252355e128615c482210d Mon Sep 17 00:00:00 2001 From: Cenk Ergen <57065323+Cenngo@users.noreply.github.com> Date: Mon, 6 Feb 2023 15:27:42 +0300 Subject: [PATCH] =?UTF-8?q?Update=20customId=20template=20generator=20to?= =?UTF-8?q?=20escape=20regex=20metachars=20used=20in=20=E2=80=A6=20(#2557)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * update customId template generator to escape regex metachars used in template literals * add clarification to TreatAsRegex prop documentation. * Implement channel ApplicationCommandPermissionTarge * implement channel target in ApplicationCommandPermission and add static methods for targeting @everyone and all channels * Revert "add clarification to TreatAsRegex prop documentation." This reverts commit 6eab5878a7ddff4e949a90d446f2e3dfe2e9c506. * fix oopsie --- .../Commands/ComponentInteractionAttribute.cs | 3 + .../Commands/ModalInteractionAttribute.cs | 3 + .../Utilities/RegexUtils.cs | 71 +++++++++++++++++-- 3 files changed, 71 insertions(+), 6 deletions(-) diff --git a/src/Discord.Net.Interactions/Attributes/Commands/ComponentInteractionAttribute.cs b/src/Discord.Net.Interactions/Attributes/Commands/ComponentInteractionAttribute.cs index 823410cdf..a6b8d2c2b 100644 --- a/src/Discord.Net.Interactions/Attributes/Commands/ComponentInteractionAttribute.cs +++ b/src/Discord.Net.Interactions/Attributes/Commands/ComponentInteractionAttribute.cs @@ -32,6 +32,9 @@ namespace Discord.Interactions /// /// Gets or sets whether the should be treated as a raw Regex pattern. /// + /// + /// defaults to the pattern used before 3.9.0. + /// public bool TreatAsRegex { get; set; } = false; /// diff --git a/src/Discord.Net.Interactions/Attributes/Commands/ModalInteractionAttribute.cs b/src/Discord.Net.Interactions/Attributes/Commands/ModalInteractionAttribute.cs index f5df950bd..0e79952f3 100644 --- a/src/Discord.Net.Interactions/Attributes/Commands/ModalInteractionAttribute.cs +++ b/src/Discord.Net.Interactions/Attributes/Commands/ModalInteractionAttribute.cs @@ -31,6 +31,9 @@ namespace Discord.Interactions /// /// Gets or sets whether the should be treated as a raw Regex pattern. /// + /// + /// defaults to the pattern used before 3.9.0. + /// public bool TreatAsRegex { get; set; } = false; /// diff --git a/src/Discord.Net.Interactions/Utilities/RegexUtils.cs b/src/Discord.Net.Interactions/Utilities/RegexUtils.cs index b3316106c..8f07be66a 100644 --- a/src/Discord.Net.Interactions/Utilities/RegexUtils.cs +++ b/src/Discord.Net.Interactions/Utilities/RegexUtils.cs @@ -1,5 +1,6 @@ using Discord.Interactions; using System; +using System.Collections.Generic; using System.Linq; namespace System.Text.RegularExpressions @@ -90,7 +91,7 @@ namespace System.Text.RegularExpressions return match.Count; } - internal static bool TryBuildRegexPattern(T commandInfo, string wildCardStr, out string pattern) where T: class, ICommandInfo + internal static bool TryBuildRegexPattern(T commandInfo, string wildCardStr, out string pattern) where T : class, ICommandInfo { if (commandInfo.TreatNameAsRegex) { @@ -105,14 +106,72 @@ namespace System.Text.RegularExpressions } var escapedWildCard = Regex.Escape(wildCardStr); - var unquantified = Regex.Replace(commandInfo.Name, $@"(?[^{escapedWildCard}]?)", - @"([^\n\t${delimiter}]+)${delimiter}"); + var unquantifiedPattern = $@"(?[^{escapedWildCard}]?)"; + var quantifiedPattern = $@"(?[0-9]+)(?,[0-9]*)?(?[^{escapedWildCard}]?)"; - var quantified = Regex.Replace(unquantified, $@"(?[0-9]+)(?,[0-9]*)?(?[^{escapedWildCard}]?)", - @"([^\n\t${delimiter}]{${start}${end}})${delimiter}"); + string name = commandInfo.Name; + + var matchPairs = new SortedDictionary(); + + foreach (Match match in Regex.Matches(name, unquantifiedPattern)) + matchPairs.Add(match.Index, new(MatchType.Unquantified, match)); + + foreach (Match match in Regex.Matches(name, quantifiedPattern)) + matchPairs.Add(match.Index, new(MatchType.Quantified, match)); + + var sb = new StringBuilder(); + + var previousMatch = 0; + + foreach (var matchPair in matchPairs) + { + sb.Append(Regex.Escape(name.Substring(previousMatch, matchPair.Key - previousMatch))); + Match match = matchPair.Value.Match; + MatchType type = matchPair.Value.Type; + + previousMatch = matchPair.Key + match.Length; + + var delimiter = match.Groups["delimiter"].Value; + + switch (type) + { + case MatchType.Unquantified: + { + sb.Append(@$"([^\n\t{Regex.Escape(delimiter)}]+){Regex.Escape(delimiter)}"); + } + break; + case MatchType.Quantified: + { + var start = match.Groups["start"].Value; + var end = match.Groups["end"].Value; + + sb.Append($@"([^\n\t{Regex.Escape(delimiter)}]{{{start}{end}}}){Regex.Escape(delimiter)}"); + } + break; + } + } + + pattern = "\\A" + sb.ToString() + "\\Z"; - pattern = "\\A" + quantified + "\\Z"; return true; } + + private enum MatchType + { + Quantified, + Unquantified + } + + private record MatchPair + { + public MatchType Type { get; } + public Match Match { get; } + + public MatchPair(MatchType type, Match match) + { + Type = type; + Match = match; + } + } } }