Skip to content

Commit 45b3d16

Browse files
committed
Issue ESAPI#300 -- Fixed most unit tests. chars are NOT autoboxed to Characters, make sure we update documentation!
1 parent 660054d commit 45b3d16

18 files changed

+228
-133
lines changed

src/main/java/org/owasp/esapi/PreparedString.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.owasp.esapi;
1717

1818
import java.util.ArrayList;
19+
1920
import org.owasp.esapi.codecs.Codec;
2021
import org.owasp.esapi.codecs.HTMLEntityCodec;
2122

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
/**
2+
* OWASP Enterprise Security API (ESAPI)
3+
*
4+
* This file is part of the Open Web Application Security Project (OWASP)
5+
* Enterprise Security API (ESAPI) project. For details, please see
6+
* <a href="http://www.owasp.org/index.php/ESAPI">http://www.owasp.org/index.php/ESAPI</a>.
7+
*
8+
* Copyright (c) 2007 - The OWASP Foundation
9+
*
10+
* The ESAPI is published by OWASP under the BSD license. You should read and accept the
11+
* LICENSE before you use, modify, and/or redistribute this software.
12+
*
13+
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
14+
* @created 2007
15+
*/
16+
package org.owasp.esapi.codecs;
17+
18+
19+
/**
20+
* The Codec interface defines a set of methods for encoding and decoding application level encoding schemes,
21+
* such as HTML entity encoding and percent encoding (aka URL encoding). Codecs are used in output encoding
22+
* and canonicalization. The design of these codecs allows for character-by-character decoding, which is
23+
* necessary to detect double-encoding and the use of multiple encoding schemes, both of which are techniques
24+
* used by attackers to bypass validation and bury encoded attacks in data.
25+
*
26+
* @author Jeff Williams (jeff.williams .at. aspectsecurity.com) <a
27+
* href="http://www.aspectsecurity.com">Aspect Security</a>
28+
* @since June 1, 2007
29+
* @see org.owasp.esapi.Encoder
30+
*/
31+
public abstract class AbstractCodec implements Codec {
32+
33+
/**
34+
* Initialize an array to mark which characters are to be encoded. Store the hex
35+
* string for that character to save time later. If the character shouldn't be
36+
* encoded, then store null.
37+
*/
38+
private final String[] hex = new String[256];
39+
40+
/**
41+
* Default constructor
42+
*/
43+
public AbstractCodec() {
44+
for ( char c = 0; c < 0xFF; c++ ) {
45+
if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x5A || c >= 0x61 && c <= 0x7A ) {
46+
hex[c] = null;
47+
} else {
48+
hex[c] = toHex(c).intern();
49+
}
50+
}
51+
}
52+
53+
/* (non-Javadoc)
54+
* @see org.owasp.esapi.codecs.Codec#encode(char[], java.lang.String)
55+
*/
56+
@Override
57+
public String encode(char[] immune, String input) {
58+
StringBuilder sb = new StringBuilder();
59+
for(int offset = 0; offset < input.length(); ){
60+
final int point = input.codePointAt(offset);
61+
if(Character.isBmpCodePoint(point)){
62+
//We can then safely cast this to char and maintain legacy behavior.
63+
sb.append(encodeCharacter(immune, new Character((char) point)));
64+
}else{
65+
sb.append(encodeCharacter(immune, point));
66+
}
67+
offset += Character.charCount(point);
68+
}
69+
return sb.toString();
70+
}
71+
72+
/**
73+
* WARNING!!!! Passing a standard char to this method will resolve to the
74+
* @{code public String encodeCharacter( char[] immune, int codePoint )} method
75+
* instead of this one!!! YOU HAVE BEEN WARNED!!!!
76+
*
77+
* @{Inherit}
78+
*/
79+
@Override
80+
public String encodeCharacter( char[] immune, Character c ) {
81+
return ""+c;
82+
}
83+
84+
/* (non-Javadoc)
85+
* @see org.owasp.esapi.codecs.Codec#encodeCharacter(char[], int)
86+
*/
87+
@Override
88+
public String encodeCharacter( char[] immune, int codePoint ) {
89+
return new StringBuilder().appendCodePoint(codePoint).toString();
90+
}
91+
92+
/* (non-Javadoc)
93+
* @see org.owasp.esapi.codecs.Codec#decode(java.lang.String)
94+
*/
95+
@Override
96+
public String decode(String input) {
97+
StringBuilder sb = new StringBuilder();
98+
PushbackString pbs = new PushbackString(input);
99+
while (pbs.hasNext()) {
100+
Character c = decodeCharacter(pbs);
101+
if (c != null) {
102+
sb.append(c);
103+
} else {
104+
sb.append(pbs.next());
105+
}
106+
}
107+
return sb.toString();
108+
}
109+
110+
/* (non-Javadoc)
111+
* @see org.owasp.esapi.codecs.Codec#decodeCharacter(org.owasp.esapi.codecs.PushbackString)
112+
*/
113+
@Override
114+
public Character decodeCharacter( PushbackString input ) {
115+
return input.next();
116+
}
117+
118+
/**
119+
* Lookup the hex value of any character that is not alphanumeric.
120+
* @param c The character to lookup.
121+
* @return, return null if alphanumeric or the character code
122+
* in hex.
123+
*/
124+
public String getHexForNonAlphanumeric(char c)
125+
{
126+
if(c<0xFF)
127+
return hex[c];
128+
return toHex(c);
129+
}
130+
131+
/**
132+
* Lookup the hex value of any character that is not alphanumeric.
133+
* @param c The character to lookup.
134+
* @return, return null if alphanumeric or the character code
135+
* in hex.
136+
*/
137+
public String getHexForNonAlphanumeric(int c)
138+
{
139+
if(c<0xFF)
140+
return hex[c];
141+
return toHex(c);
142+
}
143+
144+
public String toOctal(char c)
145+
{
146+
return Integer.toOctalString(c);
147+
}
148+
149+
public String toHex(char c)
150+
{
151+
return Integer.toHexString(c);
152+
}
153+
154+
public String toHex(int c)
155+
{
156+
return Integer.toHexString(c);
157+
}
158+
159+
/**
160+
* Utility to search a char[] for a specific char.
161+
*
162+
* @param c
163+
* @param array
164+
* @return
165+
*/
166+
public boolean containsCharacter( char c, char[] array ) {
167+
for (char ch : array) {
168+
if (c == ch) return true;
169+
}
170+
return false;
171+
}
172+
173+
}

src/main/java/org/owasp/esapi/codecs/CSSCodec.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
* @since June 1, 2007
2424
* @see org.owasp.esapi.Encoder
2525
*/
26-
public class CSSCodec extends Codec
26+
public class CSSCodec extends AbstractCodec
2727
{
2828
private static final Character REPLACEMENT = '\ufffd';
2929

@@ -42,7 +42,7 @@ public String encodeCharacter(char[] immune, Character c) {
4242
}
4343

4444
// check for alphanumeric characters
45-
String hex = Codec.getHexForNonAlphanumeric(c);
45+
String hex = super.getHexForNonAlphanumeric(c);
4646
if ( hex == null ) {
4747
return ""+c;
4848
}

src/main/java/org/owasp/esapi/codecs/Codec.java

Lines changed: 12 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -28,32 +28,7 @@
2828
* @since June 1, 2007
2929
* @see org.owasp.esapi.Encoder
3030
*/
31-
public abstract class Codec {
32-
33-
/**
34-
* Initialize an array to mark which characters are to be encoded. Store the hex
35-
* string for that character to save time later. If the character shouldn't be
36-
* encoded, then store null.
37-
*/
38-
private static final String[] hex = new String[256];
39-
40-
static {
41-
for ( char c = 0; c < 0xFF; c++ ) {
42-
if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x5A || c >= 0x61 && c <= 0x7A ) {
43-
hex[c] = null;
44-
} else {
45-
hex[c] = toHex(c).intern();
46-
}
47-
}
48-
}
49-
50-
51-
/**
52-
* Default constructor
53-
*/
54-
public Codec() {
55-
}
56-
31+
public interface Codec {
5732
/**
5833
* Encode a String so that it can be safely used in a specific context.
5934
*
@@ -62,20 +37,7 @@ public Codec() {
6237
* the String to encode
6338
* @return the encoded String
6439
*/
65-
public String encode(char[] immune, String input) {
66-
StringBuilder sb = new StringBuilder();
67-
for(int offset = 0; offset < input.length(); ){
68-
final int point = input.codePointAt(offset);
69-
if(Character.isBmpCodePoint(point)){
70-
//We can then safely cast this to char and maintain legacy behavior.
71-
sb.append(encodeCharacter(immune, (char) point));
72-
}else{
73-
sb.append(encodeCharacter(immune, point));
74-
}
75-
offset += Character.charCount(point);
76-
}
77-
return sb.toString();
78-
}
40+
public String encode(char[] immune, String input);
7941

8042
/**
8143
* Default implementation that should be overridden in specific codecs.
@@ -86,9 +48,7 @@ public String encode(char[] immune, String input) {
8648
* @return
8749
* the encoded Character
8850
*/
89-
public String encodeCharacter( char[] immune, Character c ) {
90-
return ""+c;
91-
}
51+
public String encodeCharacter( char[] immune, Character c );
9252

9353
/**
9454
* Default codepoint implementation that should be overridden in specific codecs.
@@ -99,9 +59,7 @@ public String encodeCharacter( char[] immune, Character c ) {
9959
* @return
10060
* the encoded Character
10161
*/
102-
public String encodeCharacter( char[] immune, int codePoint ) {
103-
return new StringBuilder().appendCodePoint(codePoint).toString();
104-
}
62+
public String encodeCharacter( char[] immune, int codePoint );
10563

10664
/**
10765
* Decode a String that was encoded using the encode method in this Class
@@ -111,19 +69,7 @@ public String encodeCharacter( char[] immune, int codePoint ) {
11169
* @return
11270
* the decoded String
11371
*/
114-
public String decode(String input) {
115-
StringBuilder sb = new StringBuilder();
116-
PushbackString pbs = new PushbackString(input);
117-
while (pbs.hasNext()) {
118-
Character c = decodeCharacter(pbs);
119-
if (c != null) {
120-
sb.append(c);
121-
} else {
122-
sb.append(pbs.next());
123-
}
124-
}
125-
return sb.toString();
126-
}
72+
public String decode(String input);
12773

12874
/**
12975
* Returns the decoded version of the next character from the input string and advances the
@@ -134,50 +80,29 @@ public String decode(String input) {
13480
*
13581
* @return the decoded Character
13682
*/
137-
public Character decodeCharacter( PushbackString input ) {
138-
return input.next();
139-
}
83+
public Character decodeCharacter( PushbackString input );
14084

14185
/**
14286
* Lookup the hex value of any character that is not alphanumeric.
14387
* @param c The character to lookup.
14488
* @return, return null if alphanumeric or the character code
14589
* in hex.
14690
*/
147-
public static String getHexForNonAlphanumeric(char c)
148-
{
149-
if(c<0xFF)
150-
return hex[c];
151-
return toHex(c);
152-
}
91+
public String getHexForNonAlphanumeric(char c);
15392

15493
/**
15594
* Lookup the hex value of any character that is not alphanumeric.
15695
* @param c The character to lookup.
15796
* @return, return null if alphanumeric or the character code
15897
* in hex.
15998
*/
160-
public static String getHexForNonAlphanumeric(int c)
161-
{
162-
if(c<0xFF)
163-
return hex[c];
164-
return toHex(c);
165-
}
99+
public String getHexForNonAlphanumeric(int c);
166100

167-
public static String toOctal(char c)
168-
{
169-
return Integer.toOctalString(c);
170-
}
101+
public String toOctal(char c);
171102

172-
public static String toHex(char c)
173-
{
174-
return Integer.toHexString(c);
175-
}
103+
public String toHex(char c);
176104

177-
public static String toHex(int c)
178-
{
179-
return Integer.toHexString(c);
180-
}
105+
public String toHex(int c);
181106

182107
/**
183108
* Utility to search a char[] for a specific char.
@@ -186,11 +111,6 @@ public static String toHex(int c)
186111
* @param array
187112
* @return
188113
*/
189-
public static boolean containsCharacter( char c, char[] array ) {
190-
for (char ch : array) {
191-
if (c == ch) return true;
192-
}
193-
return false;
194-
}
114+
public boolean containsCharacter( char c, char[] array );
195115

196116
}

src/main/java/org/owasp/esapi/codecs/DB2Codec.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* @since October 26, 2010
2121
* @see org.owasp.esapi.Encoder
2222
*/
23-
public class DB2Codec extends Codec {
23+
public class DB2Codec extends AbstractCodec {
2424

2525
public String encodeCharacter(char[] immune, Character c) {
2626

0 commit comments

Comments
 (0)