Skip to content

Commit

Permalink
Update customId template generator to escape regex metachars used in … (
Browse files Browse the repository at this point in the history
#2557)

* 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 6eab587.

* fix oopsie
  • Loading branch information
Cenngo committed Feb 6, 2023
1 parent 23b2822 commit 1602437
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ public class ComponentInteractionAttribute : Attribute
/// <summary>
/// Gets or sets whether the <see cref="CustomId"/> should be treated as a raw Regex pattern.
/// </summary>
/// <remarks>
/// <see langword="false"/> defaults to the pattern used before 3.9.0.
/// </remarks>
public bool TreatAsRegex { get; set; } = false;

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ public sealed class ModalInteractionAttribute : Attribute
/// <summary>
/// Gets or sets whether the <see cref="CustomId"/> should be treated as a raw Regex pattern.
/// </summary>
/// <remarks>
/// <see langword="false"/> defaults to the pattern used before 3.9.0.
/// </remarks>
public bool TreatAsRegex { get; set; } = false;

/// <summary>
Expand Down
71 changes: 65 additions & 6 deletions src/Discord.Net.Interactions/Utilities/RegexUtils.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Discord.Interactions;
using System;
using System.Collections.Generic;
using System.Linq;

namespace System.Text.RegularExpressions
Expand Down Expand Up @@ -90,7 +91,7 @@ internal static int GetWildCardCount(string input, string wildCardExpression)
return match.Count;
}

internal static bool TryBuildRegexPattern<T>(T commandInfo, string wildCardStr, out string pattern) where T: class, ICommandInfo
internal static bool TryBuildRegexPattern<T>(T commandInfo, string wildCardStr, out string pattern) where T : class, ICommandInfo
{
if (commandInfo.TreatNameAsRegex)
{
Expand All @@ -105,14 +106,72 @@ internal static int GetWildCardCount(string input, string wildCardExpression)
}

var escapedWildCard = Regex.Escape(wildCardStr);
var unquantified = Regex.Replace(commandInfo.Name, $@"(?<!\\){escapedWildCard}(?<delimiter>[^{escapedWildCard}]?)",
@"([^\n\t${delimiter}]+)${delimiter}");
var unquantifiedPattern = $@"(?<!\\){escapedWildCard}(?<delimiter>[^{escapedWildCard}]?)";
var quantifiedPattern = $@"(?<!\\){{(?<start>[0-9]+)(?<end>,[0-9]*)?(?<!\\)}}(?<delimiter>[^{escapedWildCard}]?)";

var quantified = Regex.Replace(unquantified, $@"(?<!\\){{(?<start>[0-9]+)(?<end>,[0-9]*)?(?<!\\)}}(?<delimiter>[^{escapedWildCard}]?)",
@"([^\n\t${delimiter}]{${start}${end}})${delimiter}");
string name = commandInfo.Name;

var matchPairs = new SortedDictionary<int, MatchPair>();

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;
}
}
}
}

0 comments on commit 1602437

Please sign in to comment.