Summary: | ELSupport.coerceToType won't handle null for java.lang.Number | ||
---|---|---|---|
Product: | Tomcat 6 | Reporter: | Nils Eckert <mail> |
Component: | Servlet & JSP API | Assignee: | Tomcat Developers Mailing List <dev> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | adam.hardy, bublavas, oeztaskin |
Priority: | P2 | ||
Version: | 6.0.14 | ||
Target Milestone: | default | ||
Hardware: | Other | ||
OS: | other | ||
Attachments: |
Testcase against ELSupport.coerceToNumber
Testcase and fix for the Integer to Number issue Removed unnecessary Object-creation in coerceToNumber() TLD for tag JSP and Tag source zip containing JSP, TLD and java file |
Description
Nils Eckert
2007-10-18 18:02:47 UTC
This has been fixed in trunk and proposed for 6.0.x. Well, the patch (as proposed in rev. 649639) fixes ELSupport.coerceToType(Object, Class), but the bug itself is in ELSupport.coerceToNumber(Number, Class). There do exist other ways how coerceToNumber() is called from public methods of ELSupport. For example, ELSupport.compare(Object, Object) calls it. I suppose, that those methods may suffer until coerceToNumber() itself is fixed. The fix is OK for coerceToType() though. Created attachment 21831 [details]
Testcase against ELSupport.coerceToNumber
It is a test case against ELSupport.coerceToNumber().
The tests with BigDecimal and BigInteger classes are failing.
Thanks for the test case. I have added the unit test and the necessary fixes to trunk. They have also been proposed for 6.0.x This has now been committed to 6.0.x and will be in 6.0.17 onwards. I think that this fix may have introduced a regression error, since after upgrading from 6.0.16 to 6.0.18 I am getting this error: Cannot convert 4,390,241 of type class java.lang.Integer to class java.lang.Number java.lang.IllegalArgumentException org.apache.el.lang.ELSupport.coerceToNumber(ELSupport.java:252) org.apache.el.lang.ELSupport.coerceToNumber(ELSupport.java:265) org.apache.el.lang.ELSupport.coerceToType(ELSupport.java:353) org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:188) org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:925) org.deltava.jsp.main.home_jsp._jspx_meth_fmt_005fint_005f0(home_jsp.java) Created attachment 22354 [details]
Testcase and fix for the Integer to Number issue
This fix returns the input-value if it is assignable to the given type.
Created attachment 22355 [details]
Removed unnecessary Object-creation in coerceToNumber()
The method protected final static Number coerceToNumber(final Number number, final Class type) created new BigInteger or BigDecimal Objects if the input-value was of the given type. As far as BigInteger and BigDecimal are immutable we can return the input value.
Another possible risk is the number.doubleValue() in the BigDecimal if clause. This behaves different to the coerceToType Method and was replaced with number.toString().
Thanks for the patch. I have committed it to trunk and proposed it for 6.0.x *** Bug 45953 has been marked as a duplicate of this bug. *** (In reply to comment #8) > Another possible risk is the number.doubleValue() in the BigDecimal if clause. > This behaves different to the coerceToType Method and was replaced with > number.toString(). This breaks the spec. I have reverted this part of the patch. public final static Object coerceToType(final Object obj, final Class type) throws IllegalArgumentException { if (type == null || Object.class.equals(type) || (obj != null && type.isAssignableFrom(obj.getClass()))) { return obj; } .... } behaves in the same way and returns the object if the Type matches. I only reverted the change to number.doubleValue() Thanks for the fix. It has been applied to 6.0.x and will be included in 6.0.19 onwards. *** Bug 46325 has been marked as a duplicate of this bug. *** This does not appear to be fixed, but I'm not sure if the problem rests with the code here or JSPC. I get the following error when executing a JSP: Cannot convert 0 of type class java.lang.Long to class java.lang.Number java.lang.IllegalArgumentException org.apache.el.lang.ELSupport.coerceToNumber(ELSupport.java:250) org.apache.el.lang.ELSupport.coerceToNumber(ELSupport.java:257) org.apache.el.lang.ELSupport.coerceToType(ELSupport.java:351) org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:188) org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:935) org.deltava.jsp.admin.diagnostics_jsp._jspx_meth_fmt_005fint_005f8(diagnostics_jsp.java) org.deltava.jsp.admin.diagnostics_jsp._jspx_meth_el_005ftable_005f0(diagnostics_jsp.java) Looking at the the method call, I see this in the JSP source: _jspx_th_fmt_005fint_005f8.setValue((java.lang.Number) org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate("${mapsAPIUsage}", java.lang.Number.class, (PageContext)_jspx_page_context, null, false)); The ELSupport.coerceToNumber(Number, Class) method appears to fail if the Class specified is java.lang.Number; there's no way it can execute without throwing an exception. Can you attach the simplest JSP that exhibits this error? Mark as needing info I don't think I can do this with just a JSP. My best guess is that it gets triggered when JSP includes a tag that has a parameter which is defined in the TLD as being of type java.lang.Number; then when JSPC compiles the page it takes the type defined in the TLD and passes it to coerceToNumber. Can I send you a JSP, TLD and a JAR with the tag? It is easier if we have access to the source. Can you provide source files for the simplest possible jsp, tld and tag combination that demonstrates the issue? Created attachment 24144 [details]
TLD for tag
This is the TLD for the JSP where we pass in Number.class to coerceToNumber.
Created attachment 24145 [details]
JSP and Tag source
This is the JSP and Tag sources for the JSP where we pass in Number.class to coerceToNumber.
This is a simple JSP I have created that should exhibit the behavior, along with a stripped-down TLD and tag sources. The key I believe is to look at the compiled JSP's source and see what is getting passed in the setValue() method call. The test case isn't clean (it references a class that doe snot exist) but once I clean it up this works for me with 6.0.20, 6.0.x and trunk. If you still see this issue with the 6.0.x or later, please provide a working test case that demonstrates the issue. Could you send me the compiled JSP source code? Created attachment 24692 [details]
zip containing JSP, TLD and java file
I came across this bug today - at least it looks a lot like it.
If I try to pass in a null to the function, it falls over giving me the following:
java.lang.IllegalArgumentException: Cannot convert 0 of type class java.lang.Long to class java.lang.Number
org.apache.el.lang.ELSupport.coerceToNumber(ELSupport.java:250)
Which is at best misleading and at worst, just the wrong way to handle nulls. Hopefully this is reproducible everywhere.
The attached zip causes the stack trace in 6.0.20 Thanks for the test case. This has been fixed in trunk and proposed for 6.0.x Fixed in 6.0.x and will be included in 6.0.21 onwards. |