Skip to content

Commit 7204263

Browse files
committed
Fixed MarkdownSanitizer altering URL symbols
-Suggested by EclipsedSolari in issue discord-jda#2378 -The algorithm implemented searches and replaces all URLs by a placeholder, and replaces them back after the majority of the compute method finishes. -Also added a test method in the MarkdownTest class.
1 parent ec41b86 commit 7204263

File tree

2 files changed

+80
-1
lines changed

2 files changed

+80
-1
lines changed

src/main/java/net/dv8tion/jda/api/utils/MarkdownSanitizer.java

+64-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import javax.annotation.Nonnull;
2424
import javax.annotation.Nullable;
25+
import java.util.regex.Matcher;
2526
import java.util.regex.Pattern;
2627

2728
/**
@@ -92,6 +93,8 @@ public class MarkdownSanitizer
9293
tokens.put(STRIKE, "~~");
9394
}
9495

96+
private Matcher urlMatcher;
97+
private int urlReplacementIteration;
9598
private int ignored;
9699
private SanitizationStrategy strategy;
97100

@@ -553,6 +556,11 @@ private boolean isIgnored(int nextRegion)
553556
public String compute(@Nonnull String sequence)
554557
{
555558
Checks.notNull(sequence, "Input");
559+
560+
setUrlMatcher(sequence);
561+
String[][] urlSubBox = getURLSubBox(sequence);
562+
sequence = replaceURLs(sequence, urlSubBox, true);
563+
556564
StringBuilder builder = new StringBuilder();
557565
String end = handleQuote(sequence);
558566
if (end != null) return end;
@@ -590,7 +598,10 @@ public String compute(@Nonnull String sequence)
590598
applyStrategy(nextRegion, handleRegion(i + delta, endRegion, sequence, nextRegion), builder);
591599
i = endRegion + delta;
592600
}
593-
return builder.toString();
601+
602+
sequence = replaceURLs(builder.toString(), urlSubBox, false);
603+
604+
return sequence;
594605
}
595606

596607
private String handleQuote(@Nonnull String sequence)
@@ -630,4 +641,56 @@ public enum SanitizationStrategy
630641
*/
631642
ESCAPE,
632643
}
644+
645+
//URL Handling Methods
646+
647+
private String[][] getURLSubBox(@Nonnull String sequence){
648+
int urlCount = countURLs();
649+
String[][] urlSubBox = new String[2][urlCount];
650+
urlReplacementIteration = 10000000;
651+
urlMatcher.reset();
652+
for(int i = 0; i <= urlCount - 1; i++){
653+
//System.out.println(i);
654+
urlSubBox[1][i] = generateURLReplacement(sequence);
655+
urlMatcher.find();
656+
urlSubBox[0][i] = urlMatcher.group();
657+
}
658+
return urlSubBox;
659+
}
660+
661+
private String replaceURLs(@Nonnull String sequence, String[][] subBox, boolean start){
662+
StringBuilder builder = new StringBuilder(sequence);
663+
String url;
664+
for(int i = 0; i <= subBox[1].length - 1; i++){
665+
url = subBox[start ? 0 : 1][i];
666+
builder.replace(builder.indexOf(url), builder.indexOf(url) + url.length(), subBox[start ? 1 : 0][i]);
667+
}
668+
return builder.toString();
669+
}
670+
671+
private int countURLs(){ //Returns true if there is a URL in the sequence
672+
try {
673+
int i = 0;
674+
while(urlMatcher.find()){
675+
i++;
676+
}
677+
return i;
678+
} catch (RuntimeException e) {
679+
return 0;
680+
}
681+
}
682+
683+
private void setUrlMatcher(@Nonnull String sequence){
684+
String urlPattern = "(http|https)://[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,3}(/\\S*)?";
685+
urlMatcher = Pattern.compile(urlPattern).matcher(sequence);
686+
}
687+
688+
private String generateURLReplacement(@Nonnull String sequence){
689+
String urlReplacement = "URL-" + (urlReplacementIteration);
690+
if(sequence.contains(urlReplacement)){
691+
urlReplacementIteration++;
692+
return generateURLReplacement(sequence);
693+
}
694+
else return urlReplacement;
695+
}
633696
}

src/test/java/MarkdownTest.java

+16
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,22 @@ class EscapeMarkdownTest
270270
{
271271
private MarkdownSanitizer markdown;
272272

273+
@Test
274+
public void testUrl()
275+
{
276+
//Tests Markdown sanitizer's reaction to URLs symbols
277+
Assertions.assertEquals("https://www.google.com/", markdown.compute("https://www.google.com/"));
278+
Assertions.assertEquals("https://www.google.com/search?q=_test_", markdown.compute("https://www.google.com/search?q=_test_"));
279+
Assertions.assertEquals("https://www.google.com/search?q=__test__", markdown.compute("https://www.google.com/search?q=__test__"));
280+
Assertions.assertEquals("https://www.google.com/search?q=*test*", markdown.compute("https://www.google.com/search?q=*test*"));
281+
Assertions.assertEquals("https://www.google.com/search?q=**test**", markdown.compute("https://www.google.com/search?q=**test**"));
282+
Assertions.assertEquals("https://www.google.com/search?q=***test***", markdown.compute("https://www.google.com/search?q=***test***"));
283+
Assertions.assertEquals("https://www.google.com/search?q=~test~", markdown.compute("https://www.google.com/search?q=~test~"));
284+
Assertions.assertEquals("\\*\\*Hello\\*\\* \\_\\_Hello\\_\\_ https://www.google.com/search?q=__test__", markdown.compute("**Hello** __Hello__ https://www.google.com/search?q=__test__"));
285+
Assertions.assertEquals("\\*\\*Hello\\*\\* https://github.com/__discord-jda__/JDA/**issues**/2378_ Quick brown fox https://www.google.com/search?q=__test__ \\*Test\\* \\_\\_Test\\_\\_ https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork", markdown.compute("**Hello** https://github.com/__discord-jda__/JDA/**issues**/2378_ Quick brown fox https://www.google.com/search?q=__test__ *Test* __Test__ https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork"));
286+
Assertions.assertEquals("URL-10000000 \\*\\*Hello\\*\\* https://www.google.com/search?q=**test**", markdown.compute("URL-10000000 **Hello** https://www.google.com/search?q=**test**"));
287+
}
288+
273289
@BeforeEach
274290
public void setup()
275291
{

0 commit comments

Comments
 (0)