CVE-2021-28170 Fix expression delimiter escaping (#160)
Co-authored-by: rmartinc rmartinc@redhat.com
diff --git a/impl/src/main/java/com/sun/el/parser/ELParser.jjt b/impl/src/main/java/com/sun/el/parser/ELParser.jjt
index 9411460..2757ebd 100644
--- a/impl/src/main/java/com/sun/el/parser/ELParser.jjt
+++ b/impl/src/main/java/com/sun/el/parser/ELParser.jjt
@@ -453,8 +453,8 @@
< LITERAL_EXPRESSION:
((~["\\", "$", "#"])
| ("\\" ("\\" | "$" | "#"))
- | ("$" ~["{", "$", "#"])
- | ("#" ~["{", "$", "#"])
+ | ("$" ~["{", "$", "#", "\\"])
+ | ("#" ~["{", "$", "#", "\\"])
)+
| "$"
| "#"
diff --git a/impl/src/main/java/com/sun/el/parser/ELParserTokenManager.java b/impl/src/main/java/com/sun/el/parser/ELParserTokenManager.java
index 7cafd4e..077425e 100644
--- a/impl/src/main/java/com/sun/el/parser/ELParserTokenManager.java
+++ b/impl/src/main/java/com/sun/el/parser/ELParserTokenManager.java
@@ -16,8 +16,6 @@
/* Generated By:JJTree&JavaCC: Do not edit this line. ELParserTokenManager.java */
package com.sun.el.parser;
-import java.io.StringReader;
-import jakarta.el.ELException;
/** Token Manager. */
public class ELParserTokenManager implements ELParserConstants
@@ -201,7 +199,7 @@
jjCheckNAddStates(0, 3);
break;
case 4:
- if ((0xf7ffffffffffffffL & l) == 0L)
+ if ((0xf7ffffffefffffffL & l) == 0L)
break;
if (kind > 1)
kind = 1;
diff --git a/src/test/java/org/glassfish/el/test/EscapingTest.java b/src/test/java/org/glassfish/el/test/EscapingTest.java
new file mode 100644
index 0000000..b21e72b
--- /dev/null
+++ b/src/test/java/org/glassfish/el/test/EscapingTest.java
@@ -0,0 +1,55 @@
+package org.glassfish.el.test;
+
+import jakarta.el.ELManager;
+import jakarta.el.ELProcessor;
+import jakarta.el.ValueExpression;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class EscapingTest {
+
+ static ELProcessor elp;
+ static ELManager elm;
+
+ public EscapingTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() throws Exception {
+ elp = new ELProcessor();
+ elm = elp.getELManager();
+ }
+
+ @Test
+ public void testEscape01() {
+ assertEquals("$2", evaluateExpression("$${1+1}"));
+ assertEquals("$${1+1}", evaluateExpression("$\\${1+1}"));
+ }
+
+ @Test
+ public void testEscape02() {
+ assertEquals("$2", evaluateExpression("$#{1+1}"));
+ assertEquals("$#{1+1}", evaluateExpression("$\\#{1+1}"));
+ }
+
+ @Test
+ public void testEscape03() {
+ assertEquals("#2", evaluateExpression("##{1+1}"));
+ assertEquals("##{1+1}", evaluateExpression("#\\#{1+1}"));
+ }
+
+ @Test
+ public void testEscape04() {
+ assertEquals("#2", evaluateExpression("#${1+1}"));
+ assertEquals("#${1+1}", evaluateExpression("#\\${1+1}"));
+ }
+
+ private String evaluateExpression(String expr) {
+ ValueExpression v = ELManager.getExpressionFactory().createValueExpression(
+ elm.getELContext(), expr, String.class);
+ return (String) v.getValue(elm.getELContext());
+ }
+}