2014-04-24 12:35 GMT+04:00 <[email protected]>:
> Author: markt
> Date: Thu Apr 24 08:35:06 2014
> New Revision: 1589635
>
> URL: http://svn.apache.org/r1589635
> Log:
> Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=56334
> Correct double unescaping
>
> Modified:
> tomcat/tc6.0.x/trunk/STATUS.txt
> tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/ELParser.java
> tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/Validator.java
> tomcat/tc6.0.x/trunk/test/org/apache/jasper/compiler/TestELParser.java
> tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml
>
> Modified: tomcat/tc6.0.x/trunk/STATUS.txt
> URL:
> http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/STATUS.txt?rev=1589635&r1=1589634&r2=1589635&view=diff
> ==============================================================================
> --- tomcat/tc6.0.x/trunk/STATUS.txt (original)
> +++ tomcat/tc6.0.x/trunk/STATUS.txt Thu Apr 24 08:35:06 2014
> @@ -28,12 +28,6 @@ None
> PATCHES PROPOSED TO BACKPORT:
> [ New proposals should be added at the end of the list ]
>
> -* Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=56334
> - Correct double unescaping
> -
> http://people.apache.org/~markt/patches/2014-04-17-attribute-escaping-tc6-v2.patch
> - +1: markt, remm, fhanik
> - -1:
> -
> * Enabling building with Java 8
>
> http://people.apache.org/~markt/patches/2014-04-12-build-with-java8-tc6-v1.patch
> (Note: It is easier to verify the AbstractReplicatedMap changes by diffing
>
> Modified: tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/ELParser.java
> URL:
> http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/ELParser.java?rev=1589635&r1=1589634&r2=1589635&view=diff
> ==============================================================================
> --- tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/ELParser.java
> (original)
> +++ tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/ELParser.java Thu
> Apr 24 08:35:06 2014
> @@ -203,15 +203,22 @@ public class ELParser {
> while (hasNextChar()) {
> char ch = nextChar();
> if (prev == '\\') {
> + if (ch == '$' || (!isDeferredSyntaxAllowedAsLiteral && ch ==
> '#')) {
> prev = 0;
> - if (ch == '\\') {
> + buf.append(ch);
> + continue;
> + } else if (ch == '\\') {
> + // Not an escape (this time).
> + // Optimisation - no need to set prev as it is unchanged
> + buf.append('\\');
> + continue;
> + } else {
> + // Not an escape
> + prev = 0;
> buf.append('\\');
> - prev = '\\';
> - } else if (ch == '$'
> - || (!isDeferredSyntaxAllowedAsLiteral && ch == '#'))
> {
> buf.append(ch);
> + continue;
> }
> - // else error!
> } else if (prev == '$'
> || (!isDeferredSyntaxAllowedAsLiteral && prev == '#')) {
> if (ch == '{') {
> @@ -235,6 +242,98 @@ public class ELParser {
> return buf.toString();
> }
>
> +
> + /**
> + * Escape '\\', '$' and '#', inverting the unescaping performed in
> + * {@link #skipUntilEL()}.
> + *
> + * @param input Non-EL input to be escaped
> + * @param isDeferredSyntaxAllowedAsLiteral
> + *
> + * @return The escaped version of the input
> + */
> + private static String escapeLiteralExpression(String input,
> + boolean isDeferredSyntaxAllowedAsLiteral) {
> + int len = input.length();
> + int lastAppend = 0;
> + StringBuilder output = null;
> + for (int i = 0; i < len; i++) {
> + char ch = input.charAt(i);
> + if (ch =='$' || (!isDeferredSyntaxAllowedAsLiteral && ch ==
> '#')) {
> + if (output == null) {
> + output = new StringBuilder(len + 20);
> + }
String.subSequence() = String.substring(),
but StringBuilder.append uses array copy with string but iteration
with a sequence
> + output.append(input.subSequence(lastAppend, i));
> + lastAppend = i + 1;
> + output.append('\\');
> + output.append(ch);
> + }
> + }
> + if (output == null) {
> + return input;
> + } else {
substring() is already used here.
> + output.append(input.substring(lastAppend, len));
> + return output.toString();
> + }
> + }
> +
> +
> + /**
> + * Escape '\\', '\'' and '\"', inverting the unescaping performed in
> + * {@link #skipUntilEL()}.
> + *
> + * @param input Non-EL input to be escaped
> + * @param isDeferredSyntaxAllowedAsLiteral
> + *
> + * @return The escaped version of the input
> + */
> + private static String escapeELText(String input) {
> + int len = input.length();
> + char quote = 0;
> + int lastAppend = 0;
> +
> + if (len > 1) {
> + // Might be quoted
> + quote = input.charAt(0);
> + if (quote == '\'' || quote == '\"') {
> + if (input.charAt(len - 1) != quote) {
> + throw new IllegalArgumentException(Localizer.getMessage(
> +
> "org.apache.jasper.compiler.ELParser.invalidQuotesForStringLiteral",
The LocalString.properties change is missing from backport. See r1587887
BTW, maybe
s /must be contained with/must be contained within/
in message text.
> + input));
> + }
> + lastAppend = 1;
> + len--;
> + } else {
> + quote = 0;
> + }
> + }
> +
> + StringBuilder output = null;
> + for (int i = lastAppend; i < len; i++) {
> + char ch = input.charAt(i);
> + if (ch == '\\' || ch == quote) {
> + if (output == null) {
> + output = new StringBuilder(len + 20);
> + output.append(quote);
> + }
> + output.append(input.subSequence(lastAppend, i));
Ditto, s/subSequence/substring/.
> + lastAppend = i + 1;
> + output.append('\\');
> + output.append(ch);
> + }
> + }
> + if (output == null) {
> + return input;
> + } else {
> + output.append(input.substring(lastAppend, len));
> + if (quote != 0) {
> + output.append(quote);
> + }
> + return output.toString();
> + }
> + }
> +
> +
> /*
> * @return true if there is something left in EL expression buffer other
> * than white spaces.
> @@ -281,7 +380,7 @@ public class ELParser {
>
> /*
> * Parse a string in single or double quotes, allowing for escape
> sequences
> - * '\\', and ('\"', or "\'")
> + * '\\', '\"' and "\'"
> */
> private Token parseQuotedChars(char quote) {
> StringBuilder buf = new StringBuilder();
> @@ -290,10 +389,13 @@ public class ELParser {
> char ch = nextChar();
> if (ch == '\\') {
> ch = nextChar();
> - if (ch == '\\' || ch == quote) {
> + if (ch == '\\' || ch == '\'' || ch == '\"') {
> buf.append(ch);
> + } else {
> + throw new IllegalArgumentException(Localizer.getMessage(
> +
> "org.apache.jasper.compiler.ELParser.invalidQuoting",
> + expression));
> }
> - // else error!
> } else if (ch == quote) {
> buf.append(ch);
> break;
> @@ -448,8 +550,13 @@ public class ELParser {
>
> protected static class TextBuilder extends ELNode.Visitor {
>
> + private final boolean isDeferredSyntaxAllowedAsLiteral;
> protected StringBuilder output = new StringBuilder();
>
> + protected TextBuilder(boolean isDeferredSyntaxAllowedAsLiteral) {
> + this.isDeferredSyntaxAllowedAsLiteral =
> isDeferredSyntaxAllowedAsLiteral;
> + }
> +
> public String getText() {
> return output.toString();
> }
> @@ -464,18 +571,18 @@ public class ELParser {
>
> @Override
> public void visit(Function n) throws JasperException {
> - output.append(n.getOriginalText());
> + output.append(escapeLiteralExpression(n.getOriginalText(),
> isDeferredSyntaxAllowedAsLiteral));
> output.append('(');
> }
>
> @Override
> public void visit(Text n) throws JasperException {
> - output.append(n.getText());
> +
> output.append(escapeLiteralExpression(n.getText(),isDeferredSyntaxAllowedAsLiteral));
> }
>
> @Override
> public void visit(ELText n) throws JasperException {
> - output.append(n.getText());
> + output.append(escapeELText(n.getText()));
> }
> }
> }
>
(...)
Best regards,
Konstantin Kolinko
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]