Skip to content
This repository was archived by the owner on Aug 10, 2022. It is now read-only.

Commit 2313ebd

Browse files
committed
Fix bobbylight#205: Follow OWASP recommendations for HTML encoding
1 parent a59ddaa commit 2313ebd

File tree

4 files changed

+153
-0
lines changed

4 files changed

+153
-0
lines changed

src/main/java/org/fife/ui/rsyntaxtextarea/RSyntaxUtilities.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,18 @@ public static String escapeForHtml(String s,
206206
sb.append(">");
207207
lastWasSpace = false;
208208
break;
209+
case '\'':
210+
sb.append("'");
211+
lastWasSpace = false;
212+
break;
213+
case '"':
214+
sb.append(""");
215+
lastWasSpace = false;
216+
break;
217+
case '/': // OWASP-recommended even though unnecessary
218+
sb.append("/");
219+
lastWasSpace = false;
220+
break;
209221
default:
210222
sb.append(ch);
211223
lastWasSpace = false;

src/main/java/org/fife/ui/rsyntaxtextarea/TokenImpl.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,12 @@ private StringBuilder appendHtmlLexeme(RSyntaxTextArea textArea,
233233
sb.append(tabsToSpaces ? tabStr : "	");
234234
lastWasSpace = false;
235235
break;
236+
case '&':
237+
sb.append(text, lastI, i-lastI);
238+
lastI = i+1;
239+
sb.append("&");
240+
lastWasSpace = false;
241+
break;
236242
case '<':
237243
sb.append(text, lastI, i-lastI);
238244
lastI = i+1;
@@ -245,6 +251,24 @@ private StringBuilder appendHtmlLexeme(RSyntaxTextArea textArea,
245251
sb.append("&gt;");
246252
lastWasSpace = false;
247253
break;
254+
case '\'':
255+
sb.append(text, lastI, i-lastI);
256+
lastI = i+1;
257+
sb.append("&#39;");
258+
lastWasSpace = false;
259+
break;
260+
case '"':
261+
sb.append(text, lastI, i-lastI);
262+
lastI = i+1;
263+
sb.append("&#34;");
264+
lastWasSpace = false;
265+
break;
266+
case '/': // OWASP-recommended to escape even though unnecessary
267+
sb.append(text, lastI, i-lastI);
268+
lastI = i+1;
269+
sb.append("&#47;");
270+
lastWasSpace = false;
271+
break;
248272
default:
249273
lastWasSpace = false;
250274
break;
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* 12/10/2016
3+
*
4+
* This library is distributed under a modified BSD license. See the included
5+
* RSyntaxTextArea.License.txt file for details.
6+
*/
7+
package org.fife.ui.rsyntaxtextarea;
8+
9+
import org.junit.Assert;
10+
import org.junit.Test;
11+
12+
13+
/**
14+
* Unit tests for the {@link RSyntaxUtilities} class.
15+
*
16+
* @author Robert Futrell
17+
* @version 1.0
18+
*/
19+
public class RSyntaxUtilitiesTest {
20+
21+
22+
@Test
23+
public void testEscapeForHtml_nullInput() {
24+
Assert.assertNull(RSyntaxUtilities.escapeForHtml(null, "<br>", true));
25+
}
26+
27+
28+
@Test
29+
public void testEscapeForHtml_nullNewlineReplacement() {
30+
Assert.assertEquals("", RSyntaxUtilities.escapeForHtml("\n", null, true));
31+
}
32+
33+
34+
@Test
35+
public void testEscapeForHtml_happyPath() {
36+
Assert.assertEquals("hello", RSyntaxUtilities.escapeForHtml("hello", "<br>", true));
37+
Assert.assertEquals("2 &lt; 4", RSyntaxUtilities.escapeForHtml("2 < 4", "<br>", true));
38+
}
39+
40+
41+
@Test
42+
public void testEscapeForHtml_problemChars() {
43+
Assert.assertEquals(" <br>&amp; &lt;&gt;&#39;&#34;&#47;",
44+
RSyntaxUtilities.escapeForHtml(" \n&\t<>'\"/", "<br>", true));
45+
}
46+
47+
48+
@Test
49+
public void testEscapeForHtml_multipleSpaces_inPreBlock() {
50+
Assert.assertEquals(" ",
51+
RSyntaxUtilities.escapeForHtml(" ", "<br>", true));
52+
}
53+
54+
55+
@Test
56+
public void testEscapeForHtml_multipleSpaces_notInPreBlock() {
57+
Assert.assertEquals(" &nbsp;&nbsp;",
58+
RSyntaxUtilities.escapeForHtml(" ", "<br>", false));
59+
}
60+
61+
62+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* 12/10/2016
3+
*
4+
* This library is distributed under a modified BSD license. See the included
5+
* RSyntaxTextArea.License.txt file for details.
6+
*/
7+
package org.fife.ui.rsyntaxtextarea;
8+
9+
import org.junit.Assert;
10+
import org.junit.Test;
11+
12+
13+
/**
14+
* Unit tests for the {@link TokenImpl} class.
15+
*
16+
* @author Robert Futrell
17+
* @version 1.0
18+
*/
19+
public class TokenImplTest {
20+
21+
22+
@Test
23+
public void testGetHTMLRepresentation_happyPath() {
24+
25+
RSyntaxTextArea textArea = new RSyntaxTextArea();
26+
27+
char[] ch = "for".toCharArray();
28+
TokenImpl token = new TokenImpl(ch, 0, 2, 0, TokenTypes.IDENTIFIER, 0);
29+
30+
// Don't bother checking font and other styles since it may be host-specific
31+
String actual = token.getHTMLRepresentation(textArea);
32+
Assert.assertTrue(actual.startsWith("<font"));
33+
Assert.assertTrue(actual.endsWith(">for</font>"));
34+
35+
}
36+
37+
38+
@Test
39+
public void testGetHTMLRepresentation_problemChars() {
40+
41+
RSyntaxTextArea textArea = new RSyntaxTextArea();
42+
43+
char[] ch = " &\t<>'\"/".toCharArray();
44+
TokenImpl token = new TokenImpl(ch, 0, ch.length - 1, 0, TokenTypes.IDENTIFIER, 0);
45+
46+
// Don't bother checking font and other styles since it may be host-specific
47+
String actual = token.getHTMLRepresentation(textArea);
48+
System.out.println(actual);
49+
Assert.assertTrue(actual.startsWith("<font"));
50+
Assert.assertTrue(actual.endsWith("> &amp;&#09;&lt;&gt;&#39;&#34;&#47;</font>"));
51+
52+
}
53+
54+
55+
}

0 commit comments

Comments
 (0)