private boolean escapeBS; // is '\' an escape char in text outside EL?
+ private final boolean isDeferredSyntaxAllowedAsLiteral;
+
private static final String reservedWords[] = { "and", "div", "empty",
"eq", "false", "ge", "gt", "instanceof", "le", "lt", "mod", "ne",
"not", "null", "or", "true" };
- public ELParser(String expression) {
+ public ELParser(String expression, boolean isDeferredSyntaxAllowedAsLiteral) {
index = 0;
this.expression = expression;
+ this.isDeferredSyntaxAllowedAsLiteral = isDeferredSyntaxAllowedAsLiteral;
expr = new ELNode.Nodes();
}
* @param expression
* The input expression string of the form Char* ('${' Char*
* '}')* Char*
+ * @param isDeferredSyntaxAllowedAsLiteral
+ * Are deferred expressions treated as literals?
* @return Parsed EL expression in ELNode.Nodes
*/
- public static ELNode.Nodes parse(String expression) {
- ELParser parser = new ELParser(expression);
+ public static ELNode.Nodes parse(String expression,
+ boolean isDeferredSyntaxAllowedAsLiteral) {
+ ELParser parser = new ELParser(expression,
+ isDeferredSyntaxAllowedAsLiteral);
while (parser.hasNextChar()) {
String text = parser.skipUntilEL();
if (text.length() > 0) {
buf.append('\\');
if (!escapeBS)
prev = '\\';
- } else if (ch == '$' || ch == '#') {
+ } else if (ch == '$'
+ || (!isDeferredSyntaxAllowedAsLiteral && ch == '#')) {
buf.append(ch);
}
// else error!
- } else if (prev == '$' || prev == '#') {
+ } else if (prev == '$'
+ || (!isDeferredSyntaxAllowedAsLiteral && prev == '#')) {
if (ch == '{') {
this.type = prev;
prev = 0;
buf.append(prev);
prev = 0;
}
- if (ch == '\\' || ch == '$' || ch == '#') {
+ if (ch == '\\' || ch == '$'
+ || (!isDeferredSyntaxAllowedAsLiteral && ch == '#')) {
prev = ch;
} else {
buf.append(ch);
private ErrorDispatcher err;
- private TagInfo tagInfo;
-
private ClassLoader loader;
private final StringBuilder buf = new StringBuilder(32);
ValidateVisitor(Compiler compiler) {
this.pageInfo = compiler.getPageInfo();
this.err = compiler.getErrorDispatcher();
- this.tagInfo = compiler.getCompilationContext().getTagInfo();
this.loader = compiler.getCompilationContext().getClassLoader();
}
// JSP.2.2 - '#{' not allowed in template text
if (n.getType() == '#') {
- if (!pageInfo.isDeferredSyntaxAllowedAsLiteral()
- && (tagInfo == null
- || ((tagInfo != null) && !(tagInfo.getTagLibrary().getRequiredVersion().equals("2.0")
- || tagInfo.getTagLibrary().getRequiredVersion().equals("1.2"))))) {
+ if (!pageInfo.isDeferredSyntaxAllowedAsLiteral()) {
err.jspError(n, "jsp.error.el.template.deferred");
} else {
return;
StringBuilder expr = this.getBuffer();
expr.append(n.getType()).append('{').append(n.getText())
.append('}');
- ELNode.Nodes el = ELParser.parse(expr.toString());
+ ELNode.Nodes el = ELParser.parse(expr.toString(), pageInfo
+ .isDeferredSyntaxAllowedAsLiteral());
// validate/prepare expression
prepareExpression(el, n, expr.toString());
TagAttributeInfo[] tldAttrs = tagInfo.getAttributes();
Attributes attrs = n.getAttributes();
- boolean checkDeferred = !pageInfo.isDeferredSyntaxAllowedAsLiteral()
- && !(tagInfo.getTagLibrary().getRequiredVersion().equals("2.0")
- || tagInfo.getTagLibrary().getRequiredVersion().equals("1.2"));
-
for (int i = 0; attrs != null && i < attrs.getLength(); i++) {
boolean found = false;
|| (!n.getRoot().isXmlSyntax() && attrs.getValue(i).startsWith("<%=")));
boolean elExpression = false;
boolean deferred = false;
- boolean deferredValueIsLiteral = false;
ELNode.Nodes el = null;
- if (!runtimeExpression) {
- el = ELParser.parse(attrs.getValue(i));
+ if (!runtimeExpression && !pageInfo.isELIgnored()) {
+ el = ELParser.parse(attrs.getValue(i), pageInfo
+ .isDeferredSyntaxAllowedAsLiteral());
Iterator<ELNode> nodes = el.iterator();
while (nodes.hasNext()) {
ELNode node = nodes.next();
if (node instanceof ELNode.Root) {
if (((ELNode.Root) node).getType() == '$') {
+ if (elExpression && deferred) {
+ err.jspError(n,
+ "jsp.error.attribute.deferredmix");
+ }
elExpression = true;
- } else if (checkDeferred && ((ELNode.Root) node).getType() == '#') {
+ } else if (((ELNode.Root) node).getType() == '#') {
+ if (elExpression && !deferred) {
+ err.jspError(n,
+ "jsp.error.attribute.deferredmix");
+ }
elExpression = true;
deferred = true;
- if (pageInfo.isELIgnored()) {
- deferredValueIsLiteral = true;
- }
}
}
}
}
- boolean expression = runtimeExpression
- || (elExpression && (!pageInfo.isELIgnored() || (!"true".equalsIgnoreCase(pageInfo.getIsELIgnored()) && checkDeferred && deferred)));
-
+ boolean expression = runtimeExpression || elExpression;
+
for (int j = 0; tldAttrs != null && j < tldAttrs.length; j++) {
if (attrs.getLocalName(i).equals(tldAttrs[j].getName())
&& (attrs.getURI(i) == null
|| attrs.getURI(i).length() == 0 || attrs
.getURI(i).equals(n.getURI()))) {
-
- if (tldAttrs[j].canBeRequestTime()
- || tldAttrs[j].isDeferredMethod() || tldAttrs[j].isDeferredValue()) { // JSP 2.1
+
+ TagAttributeInfo tldAttr = tldAttrs[j];
+ if (tldAttr.canBeRequestTime()
+ || tldAttr.isDeferredMethod() || tldAttr.isDeferredValue()) { // JSP 2.1
if (!expression) {
-
- if (deferredValueIsLiteral && !pageInfo.isDeferredSyntaxAllowedAsLiteral()) {
- err.jspError(n, "jsp.error.attribute.custom.non_rt_with_expr",
- tldAttrs[j].getName());
- }
-
+
String expectedType = null;
- if (tldAttrs[j].isDeferredMethod()) {
+ if (tldAttr.isDeferredMethod()) {
// The String literal must be castable to what is declared as type
// for the attribute
- String m = tldAttrs[j].getMethodSignature();
+ String m = tldAttr.getMethodSignature();
if (m != null) {
- int rti = m.trim().indexOf(' ');
+ m = m.trim();
+ int rti = m.indexOf(' ');
if (rti > 0) {
expectedType = m.substring(0, rti).trim();
}
// of void - JSP.2.3.4
err.jspError(n,
"jsp.error.literal_with_void",
- tldAttrs[j].getName());
+ tldAttr.getName());
}
}
- if (tldAttrs[j].isDeferredValue()) {
+ if (tldAttr.isDeferredValue()) {
// The String literal must be castable to what is declared as type
// for the attribute
- expectedType = tldAttrs[j].getExpectedTypeName();
+ expectedType = tldAttr.getExpectedTypeName();
}
if (expectedType != null) {
Class<?> expectedClass = String.class;
} catch (ClassNotFoundException e) {
err.jspError
(n, "jsp.error.unknown_attribute_type",
- tldAttrs[j].getName(), expectedType);
+ tldAttr.getName(), expectedType);
}
// Check casting
try {
} catch (Exception e) {
err.jspError
(n, "jsp.error.coerce_to_type",
- tldAttrs[j].getName(), expectedType, attrs.getValue(i));
+ tldAttr.getName(), expectedType, attrs.getValue(i));
}
}
- jspAttrs[i] = new Node.JspAttribute(tldAttrs[j],
+ jspAttrs[i] = new Node.JspAttribute(tldAttr,
attrs.getQName(i), attrs.getURI(i), attrs
.getLocalName(i),
attrs.getValue(i), false, null, false);
} else {
-
- if (deferred && !tldAttrs[j].isDeferredMethod() && !tldAttrs[j].isDeferredValue()) {
+
+ if (deferred && !tldAttr.isDeferredMethod() && !tldAttr.isDeferredValue()) {
// No deferred expressions allowed for this attribute
err.jspError(n, "jsp.error.attribute.custom.non_rt_with_expr",
- tldAttrs[j].getName());
+ tldAttr.getName());
}
- if (!deferred && !tldAttrs[j].canBeRequestTime()) {
+ if (!deferred && !tldAttr.canBeRequestTime()) {
// Only deferred expressions are allowed for this attribute
err.jspError(n, "jsp.error.attribute.custom.non_rt_with_expr",
- tldAttrs[j].getName());
+ tldAttr.getName());
}
if (elExpression) {
// El expression
validateFunctions(el, n);
- jspAttrs[i] = new Node.JspAttribute(tldAttrs[j],
+ jspAttrs[i] = new Node.JspAttribute(tldAttr,
attrs.getQName(i), attrs.getURI(i),
attrs.getLocalName(i),
attrs.getValue(i), false, el, false);
}
} else {
// Runtime expression
- jspAttrs[i] = getJspAttribute(tldAttrs[j],
+ jspAttrs[i] = getJspAttribute(tldAttr,
attrs.getQName(i), attrs.getURI(i),
attrs.getLocalName(i), attrs
.getValue(i), n, false);
// Make sure its value does not contain any.
if (expression) {
err.jspError(n, "jsp.error.attribute.custom.non_rt_with_expr",
- tldAttrs[j].getName());
+ tldAttr.getName());
}
- jspAttrs[i] = new Node.JspAttribute(tldAttrs[j],
+ jspAttrs[i] = new Node.JspAttribute(tldAttr,
attrs.getQName(i), attrs.getURI(i), attrs
.getLocalName(i),
attrs.getValue(i), false, null, false);
result = new Node.JspAttribute(tai, qName, uri, localName,
value.substring(3, value.length() - 2), true, null,
dynamic);
+ } else if (pageInfo.isELIgnored()) {
+ result = new Node.JspAttribute(tai, qName, uri, localName,
+ value, false, null, dynamic);
} else {
// The attribute can contain expressions but is not a
// scriptlet expression; thus, we want to run it through
// validate expression syntax if string contains
// expression(s)
- ELNode.Nodes el = ELParser.parse(value);
-
- boolean deferred = false;
- Iterator<ELNode> nodes = el.iterator();
- while (nodes.hasNext()) {
- ELNode node = nodes.next();
- if (node instanceof ELNode.Root) {
- if (((ELNode.Root) node).getType() == '#') {
- deferred = true;
- }
- }
- }
+ ELNode.Nodes el = ELParser.parse(value, pageInfo
+ .isDeferredSyntaxAllowedAsLiteral());
- if (el.containsEL() && !pageInfo.isELIgnored()
- && ((!pageInfo.isDeferredSyntaxAllowedAsLiteral() && deferred)
- || !deferred)) {
+ if (el.containsEL()) {
validateFunctions(el, n);
boolean elExpression = false;
if (!runtimeExpression && !pageInfo.isELIgnored()) {
- Iterator<ELNode> nodes = ELParser.parse(value).iterator();
+ Iterator<ELNode> nodes = ELParser.parse(value,
+ pageInfo.isDeferredSyntaxAllowedAsLiteral()).iterator();
while (nodes.hasNext()) {
ELNode node = nodes.next();
if (node instanceof ELNode.Root) {