* implement a fix for tags being found in code blocks still needs polish, consider this a rough draft * refactor to reuse a local function uses CheckWrappedInCode to check that there are no code blocks that surround the tag being parsed * Add more test coverage of MessageHelper.ParseTags * reset indexes for @ here mention * add a test case to catch error fixed from prev commit * wip commit of most test cases working * fix the Enclosed in block util method * code cleanup * lint whitespace * lint brackets for single line if blocks * move messagehelpertests to the new unit test dir * expose internals to the unit test project this seems to have been breaking the build, since CI would build the merged branch, where rest wasn't exposed to the unit tests
This commit is contained in:
committed by
Christopher F
parent
e8cb031704
commit
c977f2ec9c
@@ -1,3 +1,4 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("Discord.Net.Tests")]
|
||||
[assembly: InternalsVisibleTo("Discord.Net.Tests")]
|
||||
[assembly: InternalsVisibleTo("Discord.Net.Tests.Unit")]
|
||||
|
||||
@@ -6,4 +6,5 @@ using System.Runtime.CompilerServices;
|
||||
[assembly: InternalsVisibleTo("Discord.Net.WebSocket")]
|
||||
[assembly: InternalsVisibleTo("Discord.Net.Webhook")]
|
||||
[assembly: InternalsVisibleTo("Discord.Net.Commands")]
|
||||
[assembly: InternalsVisibleTo("Discord.Net.Tests")]
|
||||
[assembly: InternalsVisibleTo("Discord.Net.Tests.Unit")]
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Runtime.CompilerServices;
|
||||
[assembly: InternalsVisibleTo("Discord.Net.Webhook")]
|
||||
[assembly: InternalsVisibleTo("Discord.Net.Commands")]
|
||||
[assembly: InternalsVisibleTo("Discord.Net.Tests")]
|
||||
[assembly: InternalsVisibleTo("Discord.Net.Tests.Unit")]
|
||||
|
||||
[assembly: TypeForwardedTo(typeof(Discord.Embed))]
|
||||
[assembly: TypeForwardedTo(typeof(Discord.EmbedBuilder))]
|
||||
|
||||
@@ -3,6 +3,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Model = Discord.API.Message;
|
||||
|
||||
@@ -108,14 +109,56 @@ namespace Discord.Rest
|
||||
public static ImmutableArray<ITag> ParseTags(string text, IMessageChannel channel, IGuild guild, IReadOnlyCollection<IUser> userMentions)
|
||||
{
|
||||
var tags = ImmutableArray.CreateBuilder<ITag>();
|
||||
|
||||
int index = 0;
|
||||
var codeIndex = 0;
|
||||
|
||||
var inlineRegex = new Regex(@"[^\\]?(`).+?[^\\](`)", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
|
||||
var blockRegex = new Regex(@"[^\\]?(```).+?[^\\](```)", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
|
||||
|
||||
// checks if the tag being parsed is wrapped in code blocks
|
||||
bool CheckWrappedCode()
|
||||
{
|
||||
// util to check if the index of a tag is within the bounds of the codeblock
|
||||
bool EnclosedInBlock(Match m)
|
||||
=> m.Groups[1].Index < index && index < m.Groups[2].Index;
|
||||
|
||||
// loop through all code blocks that are before the start of the tag
|
||||
while (codeIndex < index)
|
||||
{
|
||||
var blockMatch = blockRegex.Match(text, codeIndex);
|
||||
if (blockMatch.Success)
|
||||
{
|
||||
if (EnclosedInBlock(blockMatch))
|
||||
return true;
|
||||
// continue if the end of the current code was before the start of the tag
|
||||
codeIndex += blockMatch.Groups[2].Index + blockMatch.Groups[2].Length;
|
||||
if (codeIndex < index)
|
||||
continue;
|
||||
return false;
|
||||
}
|
||||
var inlineMatch = inlineRegex.Match(text, codeIndex);
|
||||
if (inlineMatch.Success)
|
||||
{
|
||||
if (EnclosedInBlock(inlineMatch))
|
||||
return true;
|
||||
// continue if the end of the current code was before the start of the tag
|
||||
codeIndex += inlineMatch.Groups[2].Index + inlineMatch.Groups[2].Length;
|
||||
if (codeIndex < index)
|
||||
continue;
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
index = text.IndexOf('<', index);
|
||||
if (index == -1) break;
|
||||
int endIndex = text.IndexOf('>', index + 1);
|
||||
if (endIndex == -1) break;
|
||||
if (CheckWrappedCode()) break;
|
||||
string content = text.Substring(index, endIndex - index + 1);
|
||||
|
||||
if (MentionUtils.TryParseUser(content, out ulong id))
|
||||
@@ -158,10 +201,12 @@ namespace Discord.Rest
|
||||
}
|
||||
|
||||
index = 0;
|
||||
codeIndex = 0;
|
||||
while (true)
|
||||
{
|
||||
index = text.IndexOf("@everyone", index);
|
||||
if (index == -1) break;
|
||||
if (CheckWrappedCode()) break;
|
||||
var tagIndex = FindIndex(tags, index);
|
||||
if (tagIndex.HasValue)
|
||||
tags.Insert(tagIndex.Value, new Tag<IRole>(TagType.EveryoneMention, index, "@everyone".Length, 0, guild?.EveryoneRole));
|
||||
@@ -169,10 +214,12 @@ namespace Discord.Rest
|
||||
}
|
||||
|
||||
index = 0;
|
||||
codeIndex = 0;
|
||||
while (true)
|
||||
{
|
||||
index = text.IndexOf("@here", index);
|
||||
if (index == -1) break;
|
||||
if (CheckWrappedCode()) break;
|
||||
var tagIndex = FindIndex(tags, index);
|
||||
if (tagIndex.HasValue)
|
||||
tags.Insert(tagIndex.Value, new Tag<IRole>(TagType.HereMention, index, "@here".Length, 0, guild?.EveryoneRole));
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("Discord.Net.Relay")]
|
||||
[assembly: InternalsVisibleTo("Discord.Net.Tests")]
|
||||
[assembly: InternalsVisibleTo("Discord.Net.Tests")]
|
||||
[assembly: InternalsVisibleTo("Discord.Net.Tests.Unit")]
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("Discord.Net.Tests")]
|
||||
[assembly: InternalsVisibleTo("Discord.Net.Tests")]
|
||||
[assembly: InternalsVisibleTo("Discord.Net.Tests.Unit")]
|
||||
|
||||
Reference in New Issue
Block a user