jakartaee / expression-language

Jakarta Expression Language
https://eclipse.org/ee4j/el
Other
68 stars 49 forks source link

ListELResolver.getValue() NumberFormatException #20

Closed glassfishrobot closed 13 years ago

glassfishrobot commented 13 years ago

ListELResolver.getValue() is too greedy - it assumes if object implements List it can be indexed by supplied property. For example: #

{employeeBean.clTestingAreas.map[employee.teaTeaId].name}

clTestingAreas imlements List, but also contains field "map".

The result of evaluation is:

java.lang.NumberFormatException: For input string: "map" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48) at java.lang.Integer.parseInt(Integer.java:449) at java.lang.Integer.parseInt(Integer.java:499) at javax.el.ListELResolver.toInteger(ListELResolver.java:407) at javax.el.ListELResolver.getValue(ListELResolver.java:199) at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:175)

Environment

Operating System: All Platform: All

Affected Versions

[current]

glassfishrobot commented 6 years ago
glassfishrobot commented 13 years ago

@glassfishrobot Commented Reported by arkadi

glassfishrobot commented 13 years ago

@glassfishrobot Commented kchung said: The JSP spec defines the order that the ELResolvers must be applied. In particular, ListELResolver must be applied before BeanELResolver. See JSP.2.9. Therefore when encountering the expression "clTestingAreas.map", ListELResolver is applied.

Once in ListELResolver, the property parameter is coerced to a number. The javadocs for it says:

It might makes more sense that BeanELResolver should be used to resolve this, but unfortunately this not what the spec says today.

You can probably get around this issue by calling the access method directly:

#

{employeeBean.clTestingAreas.getMap()[employee.teaTeaId].name}

glassfishrobot commented 13 years ago

@glassfishrobot Commented arkadi said: Such interpretation of spec is: 1. Too narrow: the specification defines resolvers order, but not how list resolver must behave when property is not a number.

2. Wrong: from CompositeELResolver "If it could not handle the given pair, it must leave this property alone". EL coercion rules does not force list resolver to throw an exception, but defines such situation as coercion "error". "Error" means "cannot handle", IMO. Taking this further: 1.18.3 Coerce A to Number type N of Expression Language Speci�cation Version 2.1 defines coercion rules, but ListELResolver.toInteger() is not compliant, for example "If A is Boolean, then error".

3. Doesn't help in real world situation: it is possible to unambiguously resolve the "map" but you choose not to, instead bailing out with number format exception (bad diagnostics, BTW).

Can you handle #

{list.234}

? No? Why not? But why you're trying to handle #

{list.attr}

then? Amending list resolver to check if passed property consists of digits only (or whatever 1.18.3 prescribes) and only then raising an error (if index is out of bounds) would not be a titan's work.

glassfishrobot commented 13 years ago

@glassfishrobot Commented kchung said: The spec is clear that the parameter "property" of ListELResolve.getValue() should be taken as an index, and should be converted to a integer. It is proper to raise an error if it not an number, since doing anything else would hide the source of error from the user.

The ELResolvers were designed to resolve expressions based on the type of the base object. ListELResolver is meant to handle only indexed List object.

The only way to do what you want is to place ListELResolver after the BeanELResolver in the search list. This is however, disallowed by the JSP spec.

glassfishrobot commented 13 years ago

@glassfishrobot Commented Was assigned to uel-issues

glassfishrobot commented 7 years ago

@glassfishrobot Commented This issue was imported from java.net JIRA UEL-20

glassfishrobot commented 13 years ago

@glassfishrobot Commented Marked as won't fix on Monday, September 27th 2010, 8:06:43 am