Skip to content

Commit

Permalink
Fix #40. Option to trigger an exception for an unknown EL identifier
Browse files Browse the repository at this point in the history
  • Loading branch information
markt-asf committed Oct 1, 2021
1 parent 46e9a9b commit 77eed2e
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 2 deletions.
17 changes: 17 additions & 0 deletions api/src/main/java/jakarta/servlet/jsp/LocalStrings.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#
# Copyright (c) 2021 Contributors to the Eclipse Foundation.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License v. 2.0, which is available at
# http://www.eclipse.org/legal/epl-2.0.
#
# This Source Code may also be made available under the following Secondary
# Licenses when the conditions for such availability set forth in the
# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
# version 2 with the GNU Classpath Exception, which is available at
# https://www.gnu.org/software/classpath/license.html.
#
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
#

el.unknown.identifier=Unknown identifier
16 changes: 16 additions & 0 deletions api/src/main/java/jakarta/servlet/jsp/el/NotFoundELResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@

import java.beans.FeatureDescriptor;
import java.util.Iterator;
import java.util.ResourceBundle;
import java.util.Collections;

import jakarta.el.ELContext;
import jakarta.el.ELResolver;
import jakarta.el.ELException;
import jakarta.el.PropertyNotFoundException;

/**
* Defines variable resolution when all other resolvers fail.
Expand All @@ -30,6 +32,9 @@
*/
public class NotFoundELResolver extends ELResolver {

private static final String LSTRING_FILE = "jakarta.servlet.jsp.LocalStrings";
private static final ResourceBundle lStrings = ResourceBundle.getBundle(LSTRING_FILE);

/**
* If the base object is <code>null</code>, searches the Class and static imports for an import with the given name
* and returns it if an import exists with the given name.
Expand All @@ -44,6 +49,11 @@ public class NotFoundELResolver extends ELResolver {
* @param property Ignored
* @return Always {@code null}
* @throws NullPointerException if context is <code>null</code>
* @throws PropertyNotFoundException
* If the provided context contains a Boolean object with value {@code Boolean.TRUE} as
* the value associated with the key
* {@code jakarta.servlet.jsp.el.NotFoundELResolver.class}. This is to support
* implementation of the {@code errorOnELNotFound} page/tag directive.
* @throws ELException if an exception was thrown while performing the property or variable resolution. The
* thrown exception must be included as the cause property of this exception, if
* available.
Expand All @@ -55,6 +65,12 @@ public Object getValue(ELContext context, Object base, Object property) {
throw new NullPointerException();
}

Object obj = context.getContext(this.getClass());
if (obj instanceof Boolean && ((Boolean) obj).booleanValue()) {
throw new PropertyNotFoundException(
lStrings.getString("el.unknown.identifier") + " [" + property.toString() + "]");
}

context.setPropertyResolved(true);

return null;
Expand Down
117 changes: 115 additions & 2 deletions spec/src/main/asciidoc/ServerPages.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1265,7 +1265,7 @@ XMLTagDefDirectiveBody ::= ( ( 'tag' S TagDirectiveAttrList S?
PageDirectiveAttrList ::= ATTR[ language, extends, import, session, buffer,
autoFlush, isThreadSafe, info, errorPage,
isErrorPage, contentType, pageEncoding,
isELIgnored ]
isELIgnored, errorOnELNotFound ]
[ vc: PageDirectiveUniqueAttr ]
TagLibDirectiveAttrList ::= ATTR[ !uri, !prefix ]
Expand All @@ -1276,7 +1276,8 @@ IncludeDirectiveAttrList ::= ATTR[ !file ]
TagDirectiveAttrList ::= ATTR[ display-name, body-content, dynamic-attributes,
small-icon, large-icon, description, example,
language, import, pageEncoding, isELIgnored ]
language, import, pageEncoding, isELIgnored,
errorOnELNotFound ]
[ vc: TagDirectiveUniqueAttr ]
AttributeDirectiveAttrList ::= ATTR[ !name, required, fragment, rtexprvalue,
Expand Down Expand Up @@ -2513,6 +2514,7 @@ page_directive_attr_list ::= { language="scriptingLanguage" }
{ contentType="ctinfo" }
{ pageEncoding="peinfo" }
{ isELIgnored="true|false" }
{ errorOnELNotFound="true|false" }
{ deferredSyntaxAllowedAsLiteral="true|false" }
{ trimDirectiveWhitespaces="true|false" }
----
Expand Down Expand Up @@ -2736,6 +2738,12 @@ attributes. The corresponding JSP configuration element is `el-ignored`
varies depending on the `web.xml` version - see
<<Deactivating EL Evaluation>>.

|`errorOnELNotFound`
|Defines whether a `PropertyNotFoundException` is thrown when an EL expression
contains an identifier that the EL machinery cannot resolve. The corresponding
JSP configuration element is `error-on-el-not-found`
(see <<_Unknown_EL_Identifiers>>)

|`deferredSyntax-` +
`AllowedAsLiteral`
|Indicates if the character sequence #{ is
Expand Down Expand Up @@ -3758,6 +3766,14 @@ authors, or page authoring groups, may want to follow a methodology
where scripting elements are not allowed. See
<<_Disabling_Scripting_Elements>> for more details.

=== Unknown EL Identifiers

The default behaviour of the `NotFoundELResolver` is to return null when
attempting to resolve an unknown identifier. This can mask bugs and therefore
may not always be the desired behaviour. To address this, the default behaviour
can be changed as indicated in
<<_Unknown_EL_Identifiers>>

=== Invalid EL Expressions

JSP containers are required to produce a
Expand Down Expand Up @@ -4240,6 +4256,93 @@ delivered using the `.jsp` extension:

|===

[[_Unknown_EL_Identifiers]]
==== Unknown EL Identifiers

The default behaviour of the `NotFoundELResolver` is to return `null` when
attempting to resolve an unknown identifier. This can mask bugs and therefore
may not always be the desired behaviour. To address this, the default behaviour
can be changed as indicated in this section.

The default behaviour can be explicitly changed by setting the value of the
`error-on-el-not-found` element. The `error-on-el-not-found` element is a
subelement of `jsp-property-group` (see <<_JSP_Property_Groups>>)
It has no subelements. Its valid values are `true` and `false`.

For example, the following `web.xml` fragment defines a group that configures
all JSP pages delivered using the `.jsp` extension to throw a
`PropertyNotFoundException` if an EL expression contains an unknown identifier.:

[source,xml]
----
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<error-on-el-not-found>true</error-on-el-not-found>
</jsp-property-group>
----

Page authors can override the default mode through the `errorOnELNotFound`
attribute of the page directive and the `errorOnELNotFound` attribute of the tag
directive can.

<<_EL_Unknown_Identifier_Settings_for_JSP_Pages>> summarizes the EL unknown
identifier settings for JSP pages, and their meanings:

[caption='*Table JSP.{jsp-chapter}-{counter:table-number}* ']
[[_EL_Unknown_Identifier_Settings_for_JSP_Pages]]
.EL Evaluation Unknown Identifier for JSP Pages
[cols="30,30,40",options="header"]
|===

|JSP Configuration <error-on-el-not-found>
|Page Directive errorOnELNotFound
|Unknown Identifier Encountered

|unspecified
|unspecified
|`null` is returned by `ELResolver`

|false
|unspecified
|`null` is returned by `ELResolver`

|true
|unspecified
|`PropertyNotFoundException` thrown by `ELResolver`

|don’t care
|false
|`null` is returned by `ELResolver`

|don’t care
|true
|`PropertyNotFoundException` thrown by `ELResolver`

|===

<<_EL_Unknown_Identifier_Settings_for_Tag_Files>> summarizes the EL unknown
identifier settings for tag files, and their meanings:

[caption='*Table JSP.{jsp-chapter}-{counter:table-number}* ']
[[_EL_Unknown_Identifier_Settings_for_Tag_Files]]
.EL Unknown Identifier Settings for Tag Files
[cols="50,50",options="header"]
|===

|Tag Directive errorOnELNotFound
|Unknown Identifier Encountered

|unspecified
|`null` is returned by `ELResolver`

|false
|`null` is returned by `ELResolver`

|true
|`PropertyNotFoundException` thrown by `ELResolver`

|===

==== Declaring Page Encodings

The JSP configuration element `page-encoding`
Expand Down Expand Up @@ -8927,6 +9030,7 @@ tag_directive_attr_list ::= { display-name="display-name" }
{ import="importList" }
{ pageEncoding="peinfo" }
{ isELIgnored="true|false" }
{ errorOnELNotFound="true|false" }
{ deferredSyntaxAllowedAsLiteral="true|false" }
{ trimDirectiveWhitespaces="true|false" }
....
Expand Down Expand Up @@ -9010,6 +9114,12 @@ semantics of the `isELIgnored` attribute of the `page` directive.
However, there is no corresponding global configuration element in
`web.xml`.

|`errorOnELNotFound`
|(optional) Carries the same syntax and
semantics of the `errorOnELNotFound` attribute of the `page` directive.
However, there is no corresponding global configuration element in
`web.xml`.

|`deferredSyntax-` +
`AllowedAsLiteral`
|(optional) Carries the same syntax and
Expand Down Expand Up @@ -11548,6 +11658,9 @@ Jakarta Server Pages specification. This appendix is non-normative.

* Deprecate methods that override `ELResolver.getFeatureDescriptors()` as that
method has been deprecated as of EL 5.0.
* https://github.com/eclipse-ee4j/jsp-api/issues/40[#40]
Add an option to raise a `PropertyNotFoundException` when an EL expression
contains an unknown identifier.
* https://github.com/eclipse-ee4j/jsp-api/issues/44[#44]
Clarify that the EL environment within a JSP has a set of default imports
consistent with the default imports for the scripting environment. Refactor
Expand Down

0 comments on commit 77eed2e

Please sign in to comment.