in impl/src/main/java/org/apache/myfaces/renderkit/html/util/HTMLEncoder.java [1222:1340]
private static void encodeURIQuery(Writer writer, final String string, int offset, final String characterEncoding)
throws IOException
{
int start = offset;
int length = string.length();
int realLength = length-offset;
String app;
char c;
for (int i = offset; i < length; ++i)
{
app = null;
c = string.charAt(i);
// - From %00 to %20 (' ' %20 could encode as +, but %20 also works, so we keep %20)
// - <"> %22 (If there is encode of "%", there is a risk of duplicate encoding, so
// we make easier and omit this one)
// - "<" %3C, ">" %3E,
// - "\" %5C, "^" %5E, "`" %60
// - "{" %7B, "|" %7C, "}" %7D
// - From %7F ad infinitum (each character as many bytes as necessary but take into account
// that a single char should contain 2,3 or more bytes!. This data should be encoded
// translating from the document character encoding to percent encoding)
//
// "&" should be encoded as "&" because this link is inside an html page, and
// put & is invalid in this context
if ( (c <= (char)0x20) || (c >= (char)0x7F) ||
c == '"' || c == '<' ||
c == '>' || c == '\\' || c == '^' || c == '`' ||
c == '{' || c == '|' || c == '}')
{
// The percent encoding on this part should be done using UTF-8 charset
// as RFC 3986 Section 3.2.2 says
if (start < i)
{
writer.write(string, start, i-start);
}
start = i+1;
percentEncode(writer, c, characterEncoding);
}
else if (c == '%')
{
if (i + 2 < length)
{
char c1 = string.charAt(i+1);
char c2 = string.charAt(i+2);
if ((( c1 >= '0' && c1 <='9') || (c1 >='A' && c1 <='Z') || (c1 >='a' && c1 <='z')) &&
(( c2 >= '0' && c2 <='9') || (c2 >='A' && c2 <='Z') || (c2 >='a' && c2 <='z')))
{
// do not percent encode, because it could be already encoded
}
else
{
if (start < i)
{
writer.write(string, start, i-start);
}
start = i+1;
percentEncode(writer, c, characterEncoding);
}
}
else
{
//app = percentEncode(c, characterEncoding);
if (start < i)
{
writer.write(string, start, i-start);
}
start = i+1;
percentEncode(writer, c, characterEncoding);
}
}
else if (c == '&')
{
if (i+4 < length )
{
if ('a' == string.charAt(i+1) &&
'm' == string.charAt(i+2) &&
'p' == string.charAt(i+3) &&
';' == string.charAt(i+4))
{
//Skip
}
else
{
app = "&";
}
}
else
{
app = "&";
}
}
else
{
//No encoding, just do nothing, char will be added later.
}
if (app != null)
{
if (start < i)
{
writer.write(string, start, i-start);
}
start = i+1;
writer.write(app);
}
}
if (start == offset)
{
writer.write(string, offset, realLength);
}
else if (start < length)
{
writer.write(string,start,length-start);
}
}