Skip to content

Commit e9f5265

Browse files
committed
rework the bug/review page substitution
avoid using "$1" and use custom replacer function to make sure the matched pattern is properly escaped
1 parent b7db946 commit e9f5265

File tree

3 files changed

+47
-46
lines changed

3 files changed

+47
-46
lines changed

opengrok-indexer/src/main/java/org/opengrok/indexer/web/Util.java

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
import java.util.function.IntConsumer;
6060
import java.util.logging.Level;
6161
import java.util.logging.Logger;
62+
import java.util.regex.MatchResult;
6263
import java.util.regex.Matcher;
6364
import java.util.regex.Pattern;
6465
import java.util.stream.IntStream;
@@ -367,7 +368,7 @@ public static String breadcrumbPath(String urlPrefix, String path) {
367368
* @param path the full path from which the breadcrumb path is built
368369
* @param sep separator to use to crack the given path
369370
*
370-
* @return HTML markup fro the breadcrumb or the path itself.
371+
* @return HTML markup for the breadcrumb or the path itself.
371372
* @see #breadcrumbPath(String, String, char, String, boolean, boolean)
372373
*/
373374
public static String breadcrumbPath(String urlPrefix, String path, char sep) {
@@ -939,16 +940,14 @@ public static String uriEncode(String q) {
939940
* @param dest a defined target
940941
* @throws IOException I/O
941942
*/
942-
public static void uriEncode(String str, Appendable dest)
943-
throws IOException {
943+
public static void uriEncode(String str, Appendable dest) throws IOException {
944944
String uenc = uriEncode(str);
945945
dest.append(uenc);
946946
}
947947

948948
/**
949-
* Append '&name=value" to the given buffer. If the given
950-
* <var>value</var>
951-
* is {@code null}, this method does nothing.
949+
* Append "&amp;name=value" to the given buffer. If the given <var>value</var> is {@code null},
950+
* this method does nothing.
952951
*
953952
* @param buf where to append the query string
954953
* @param key the name of the parameter to add. Append as is!
@@ -957,8 +956,7 @@ public static void uriEncode(String str, Appendable dest)
957956
* @throws NullPointerException if the given buffer is {@code null}.
958957
* @see #uriEncode(String)
959958
*/
960-
public static void appendQuery(StringBuilder buf, String key,
961-
String value) {
959+
public static void appendQuery(StringBuilder buf, String key, String value) {
962960

963961
if (value != null) {
964962
buf.append(AMP).append(key).append('=').append(uriEncode(value));
@@ -1610,25 +1608,32 @@ public static String buildLink(String name, String url, boolean newTab)
16101608
return buildLink(name, attrs);
16111609
}
16121610

1611+
private static String buildLinkReplacer(MatchResult result, String text, String url) {
1612+
final String appendedUrl = url + result.group(1);
1613+
try {
1614+
StringBuilder stringBuilder = new StringBuilder();
1615+
stringBuilder.append(text.substring(result.start(0), result.start(1)));
1616+
stringBuilder.append(buildLink(appendedUrl, appendedUrl, true));
1617+
stringBuilder.append(text.substring(result.end(1), result.end(0)));
1618+
return stringBuilder.toString();
1619+
} catch (URISyntaxException|MalformedURLException e) {
1620+
LOGGER.log(Level.WARNING, "The given URL ''{0}'' is not valid", appendedUrl);
1621+
return result.group(0);
1622+
}
1623+
}
1624+
16131625
/**
16141626
* Replace all occurrences of pattern in the incoming text with the link
1615-
* named name pointing to an URL. It is possible to use the regexp pattern
1627+
* named name pointing to a URL. It is possible to use the regexp pattern
16161628
* groups in name and URL when they are specified in the pattern.
16171629
*
1618-
* @param text text to replace all patterns
1630+
* @param text text to replace all patterns
16191631
* @param pattern the pattern to match
1620-
* @param name link display name
1621-
* @param url link URL
1632+
* @param url link URL
16221633
* @return the text with replaced links
16231634
*/
1624-
public static String linkifyPattern(String text, Pattern pattern, String name, String url) {
1625-
try {
1626-
String buildLink = buildLink(name, url, true);
1627-
return pattern.matcher(text).replaceAll(buildLink);
1628-
} catch (URISyntaxException | MalformedURLException ex) {
1629-
LOGGER.log(Level.WARNING, "The given URL ''{0}'' is not valid", url);
1630-
return text;
1631-
}
1635+
public static String linkifyPattern(String text, Pattern pattern, String url) {
1636+
return pattern.matcher(text).replaceAll(match -> buildLinkReplacer(match, text, url));
16321637
}
16331638

16341639
/**

opengrok-indexer/src/test/java/org/opengrok/indexer/web/UtilTest.java

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,7 @@
5353

5454
import static org.hamcrest.MatcherAssert.assertThat;
5555
import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
56-
import static org.junit.jupiter.api.Assertions.assertEquals;
57-
import static org.junit.jupiter.api.Assertions.assertFalse;
58-
import static org.junit.jupiter.api.Assertions.assertNull;
59-
import static org.junit.jupiter.api.Assertions.assertThrows;
60-
import static org.junit.jupiter.api.Assertions.assertTrue;
56+
import static org.junit.jupiter.api.Assertions.*;
6157
import static org.opengrok.indexer.condition.RepositoryInstalled.Type.MERCURIAL;
6258

6359
/**
@@ -490,23 +486,21 @@ void testLinkifyPattern() {
490486
+ " fugiat nulla pariatur. Excepteur sint "
491487
+ "occaecat bug6478abc cupidatat non proident, sunt in culpa qui officia "
492488
+ "deserunt mollit anim id est laborum.";
493-
String expected2
494-
= "Lorem ipsum dolor sit amet, consectetur adipiscing elit, "
495-
+ "sed do eiusmod tempor incididunt as per 12345698 ut labore et dolore magna "
496-
+ "aliqua. "
497-
+ "<a href=\"http://www.other-example.com?bug=3333\" rel=\"noreferrer\" target=\"_blank\">bug3333fff</a>"
498-
+ " Ut enim ad minim veniam, quis nostrud exercitation "
499-
+ "ullamco laboris nisi ut aliquip ex ea introduced in 9791216541 commodo consequat. "
500-
+ "Duis aute irure dolor in reprehenderit in voluptate velit "
501-
+ "esse cillum dolore eu fixes 132469187 fugiat nulla pariatur. Excepteur sint "
502-
+ "occaecat "
503-
+ "<a href=\"http://www.other-example.com?bug=6478\" rel=\"noreferrer\" target=\"_blank\">bug6478abc</a>"
504-
+ " cupidatat non proident, sunt in culpa qui officia "
505-
+ "deserunt mollit anim id est laborum.";
506489

507-
assertEquals(expected, Util.linkifyPattern(text, Pattern.compile("\\b([0-9]{8,})\\b"), "$1", "http://www.example.com?bug=$1"));
508-
assertEquals(expected2, Util.linkifyPattern(text, Pattern.compile("\\b(bug([0-9]{4})\\w{3})\\b"), "$1",
509-
"http://www.other-example.com?bug=$2"));
490+
assertEquals(expected, Util.linkifyPattern(text, Pattern.compile("\\b([0-9]{8,})\\b"), "http://www.example.com?bug="));
491+
}
492+
493+
/**
494+
* Matched pattern should be properly encoded in the resulting HTML.
495+
*/
496+
@Test
497+
void testLinkifyPatternEscape() {
498+
final String text = "foo bug <123456> bar";
499+
final String expected = "foo bug <a href=\"http://www.example.com?bug=%3C123456%3E\" " +
500+
"rel=\"noreferrer\" target=\"_blank\">&lt;123456&gt;</a> bar";
501+
502+
assertEquals(expected,
503+
Util.linkifyPattern(text, Pattern.compile("[ \\t]+([0-9<>]{3,})[ \\t]+"), "http://www.example.com?bug="));
510504
}
511505

512506
@Test
@@ -652,7 +646,9 @@ void testWriteHADNonexistentFile() throws Exception {
652646
@Test
653647
void testWriteHAD() throws Exception {
654648
TestRepository repository = new TestRepository();
655-
repository.create(UtilTest.class.getResource("/repositories"));
649+
URL repositoryURL = UtilTest.class.getResource("/repositories");
650+
assertNotNull(repositoryURL);
651+
repository.create(repositoryURL);
656652

657653
RuntimeEnvironment env = RuntimeEnvironment.getInstance();
658654

opengrok-web/src/main/webapp/history.jsp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -369,10 +369,10 @@ document.domReady.push(function() {domReadyHistory();});
369369
String cout = Util.htmlize(entry.getMessage());
370370
371371
if (bugPage != null && !bugPage.isEmpty() && bugPattern != null) {
372-
cout = Util.linkifyPattern(cout, bugPattern, "$1", Util.completeUrl(bugPage + "$1", request));
372+
cout = Util.linkifyPattern(cout, bugPattern, Util.completeUrl(bugPage, request));
373373
}
374374
if (reviewPage != null && !reviewPage.isEmpty() && reviewPattern != null) {
375-
cout = Util.linkifyPattern(cout, reviewPattern, "$1", Util.completeUrl(reviewPage + "$1", request));
375+
cout = Util.linkifyPattern(cout, reviewPattern, Util.completeUrl(reviewPage, request));
376376
}
377377
378378
boolean showSummary = false;
@@ -382,10 +382,10 @@ document.domReady.push(function() {domReadyHistory();});
382382
coutSummary = coutSummary.substring(0, summaryLength - 1);
383383
coutSummary = Util.htmlize(coutSummary);
384384
if (bugPage != null && !bugPage.isEmpty() && bugPattern != null) {
385-
coutSummary = Util.linkifyPattern(coutSummary, bugPattern, "$1", Util.completeUrl(bugPage + "$1", request));
385+
coutSummary = Util.linkifyPattern(coutSummary, bugPattern, Util.completeUrl(bugPage, request));
386386
}
387387
if (reviewPage != null && !reviewPage.isEmpty() && reviewPattern != null) {
388-
coutSummary = Util.linkifyPattern(coutSummary, reviewPattern, "$1", Util.completeUrl(reviewPage + "$1", request));
388+
coutSummary = Util.linkifyPattern(coutSummary, reviewPattern, Util.completeUrl(reviewPage, request));
389389
}
390390
}
391391

0 commit comments

Comments
 (0)