Skip to content

Commit b8e0197

Browse files
committed
Merge contributor C1 control update into JavaScript PR
2 parents b8f0c52 + 30c0fa7 commit b8e0197

2 files changed

Lines changed: 12 additions & 7 deletions

File tree

‎core/src/main/java/org/owasp/encoder/JavaScriptEncoder.java‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ enum Mode {
123123
// '`', '$', and '{' are encoded in every mode for ordinary template
124124
// literal text. An unescaped '`' ends the literal; "${" starts an
125125
// expression even when '$' is trusted text before the encoded input.
126+
// DEL is hex-encoded in every mode, like the C1 controls.
126127
_validMasks = new int[]{
127128
0,
128129
-1 & ~((1 << '\'') | (1 << '\"') | (1 << '$')),
@@ -164,7 +165,7 @@ int firstEncodedOffset(String input, int off, int len) {
164165
if ((validMasks[ch >>> 5] & (1 << ch)) == 0) {
165166
return i;
166167
}
167-
} else if (_asciiOnly || ch <= 0x9f
168+
} else if (_asciiOnly || ch <= Unicode.MAX_C1_CTRL_CHAR
168169
|| ch == Unicode.LINE_SEPARATOR || ch == Unicode.PARAGRAPH_SEPARATOR) {
169170
return i;
170171
} else if (Character.isHighSurrogate(ch)) {
@@ -202,7 +203,7 @@ protected CoderResult encodeArrays(CharBuffer input, CharBuffer output, boolean
202203
break encoded;
203204
}
204205
} else {
205-
if (ch <= 0x9f || (_asciiOnly && ch <= 0xff)) {
206+
if (ch <= Unicode.MAX_C1_CTRL_CHAR || (_asciiOnly && ch <= 0xff)) {
206207
break hexEncoded;
207208
}
208209
if (!_asciiOnly && Character.isHighSurrogate(ch)) {

‎core/src/test/java/org/owasp/encoder/JavaScriptEncoderTest.java‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,6 @@ public static Test suite() {
101101
.encode("NUL", "\\x00", "\0")
102102
.encode("Line Separator", "\\u2028", "\u2028")
103103
.encode("Paragraph Separator", "\\u2029", "\u2029")
104-
.encode("DEL", "\\x7f", "\u007f")
105-
.encode("NEL", "\\x85", "\u0085")
106-
.encode("last C1 control", "\\x9f", "\u009f")
107104
.encode("lone high surrogate", "\\ud800", "\ud800")
108105
.encode("lone low surrogate", "\\udfff", "\udfff")
109106
.encode("reversed pair", "\\udc00\\ud800", "\udc00\ud800")
@@ -118,7 +115,14 @@ public static Test suite() {
118115
.encode("template expression", "\\x24\\x7balert(1)}", "${alert(1)}")
119116
.encode("template breakout", "hell\\x60;alert(1);\\x60o", "hell`;alert(1);`o")
120117
.encode("abc", "abc")
121-
.encode("ABC", "ABC");
118+
.encode("ABC", "ABC")
119+
// DEL and the C1 controls are hex encoded in every mode
120+
.encode("DEL", "\\x7f", "\u007f")
121+
.encode("U+0080", "\\x80", "\u0080")
122+
.encode("NEL", "\\x85", "\u0085")
123+
.encode("CSI", "\\x9b", "\u009b")
124+
.encode("U+009F", "\\x9f", "\u009f")
125+
.encode("NEL in text", "a\\x85b", "a\u0085b");
122126

123127
if (asciiOnly == 0) {
124128
builder
@@ -127,7 +131,7 @@ public static Test suite() {
127131
.encode("non-breaking space", "\u00a0", "\u00a0")
128132
.encode("surrogate pair", "\ud83d\ude00", "\ud83d\ude00")
129133
.valid(0xa0, Character.MAX_CODE_POINT)
130-
.encoded(0x7f, 0x9f)
134+
.encoded(0x7f, Unicode.MAX_C1_CTRL_CHAR)
131135
.encoded(Character.MIN_SURROGATE, Character.MAX_SURROGATE)
132136
.encoded("\u2028\u2029");
133137
} else {

0 commit comments

Comments
 (0)