Browse Source

Update customId template generator to escape regex metachars used in … (#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 6eab5878a7.

* fix oopsie
pull/2585/head
Cenk Ergen GitHub 2 years ago
parent
commit
1602437c31
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 71 additions and 6 deletions
  1. +3
    -0
      src/Discord.Net.Interactions/Attributes/Commands/ComponentInteractionAttribute.cs
  2. +3
    -0
      src/Discord.Net.Interactions/Attributes/Commands/ModalInteractionAttribute.cs
  3. +65
    -6
      src/Discord.Net.Interactions/Utilities/RegexUtils.cs

+ 3
- 0
src/Discord.Net.Interactions/Attributes/Commands/ComponentInteractionAttribute.cs View File

@@ -32,6 +32,9 @@ namespace Discord.Interactions
/// <summary> /// <summary>
/// Gets or sets whether the <see cref="CustomId"/> should be treated as a raw Regex pattern. /// Gets or sets whether the <see cref="CustomId"/> should be treated as a raw Regex pattern.
/// </summary> /// </summary>
/// <remarks>
/// <see langword="false"/> defaults to the pattern used before 3.9.0.
/// </remarks>
public bool TreatAsRegex { get; set; } = false; public bool TreatAsRegex { get; set; } = false;


/// <summary> /// <summary>


+ 3
- 0
src/Discord.Net.Interactions/Attributes/Commands/ModalInteractionAttribute.cs View File

@@ -31,6 +31,9 @@ namespace Discord.Interactions
/// <summary> /// <summary>
/// Gets or sets whether the <see cref="CustomId"/> should be treated as a raw Regex pattern. /// Gets or sets whether the <see cref="CustomId"/> should be treated as a raw Regex pattern.
/// </summary> /// </summary>
/// <remarks>
/// <see langword="false"/> defaults to the pattern used before 3.9.0.
/// </remarks>
public bool TreatAsRegex { get; set; } = false; public bool TreatAsRegex { get; set; } = false;


/// <summary> /// <summary>


+ 65
- 6
src/Discord.Net.Interactions/Utilities/RegexUtils.cs View File

@@ -1,5 +1,6 @@
using Discord.Interactions; using Discord.Interactions;
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;


namespace System.Text.RegularExpressions namespace System.Text.RegularExpressions
@@ -90,7 +91,7 @@ namespace System.Text.RegularExpressions
return match.Count; 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) if (commandInfo.TreatNameAsRegex)
{ {
@@ -105,14 +106,72 @@ namespace System.Text.RegularExpressions
} }


var escapedWildCard = Regex.Escape(wildCardStr); 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; 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;
}
}
} }
} }

Loading…
Cancel
Save