This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/main by this push: new 7c630a7 ElResolver.getType() must return null for read-only resolvers/properties 7c630a7 is described below commit 7c630a7fde51c858c899f5155c21f4462d971ec2 Author: Mark Thomas <ma...@apache.org> AuthorDate: Thu Sep 30 15:10:45 2021 +0100 ElResolver.getType() must return null for read-only resolvers/properties --- java/jakarta/el/ArrayELResolver.java | 7 +++++++ java/jakarta/el/BeanELResolver.java | 8 +++++++- java/jakarta/el/BeanNameELResolver.java | 11 +++++++++-- java/jakarta/el/ListELResolver.java | 9 +++++++++ java/jakarta/el/MapELResolver.java | 6 ++++++ java/jakarta/el/ResourceBundleELResolver.java | 4 ++++ java/jakarta/el/StaticFieldELResolver.java | 26 ++++++++------------------ webapps/docs/changelog.xml | 7 +++++++ 8 files changed, 57 insertions(+), 21 deletions(-) diff --git a/java/jakarta/el/ArrayELResolver.java b/java/jakarta/el/ArrayELResolver.java index 24e32d6..c9a0aff 100644 --- a/java/jakarta/el/ArrayELResolver.java +++ b/java/jakarta/el/ArrayELResolver.java @@ -45,6 +45,13 @@ public class ArrayELResolver extends ELResolver { } catch (IllegalArgumentException e) { // ignore } + /* + * The resolver may have been created in read-only mode but the + * array and its elements will always be read-write. + */ + if (readOnly) { + return null; + } return base.getClass().getComponentType(); } diff --git a/java/jakarta/el/BeanELResolver.java b/java/jakarta/el/BeanELResolver.java index 2b6f455..81a229b 100644 --- a/java/jakarta/el/BeanELResolver.java +++ b/java/jakarta/el/BeanELResolver.java @@ -69,7 +69,13 @@ public class BeanELResolver extends ELResolver { } context.setPropertyResolved(base, property); - return this.property(context, base, property).getPropertyType(); + BeanProperty beanProperty = property(context, base, property); + + if (readOnly || beanProperty.isReadOnly(base)) { + return null; + } + + return beanProperty.getPropertyType(); } @Override diff --git a/java/jakarta/el/BeanNameELResolver.java b/java/jakarta/el/BeanNameELResolver.java index 814c6f5..ad65ccf 100644 --- a/java/jakarta/el/BeanNameELResolver.java +++ b/java/jakarta/el/BeanNameELResolver.java @@ -104,9 +104,16 @@ public class BeanNameELResolver extends ELResolver { try { if (beanNameResolver.isNameResolved(beanName)) { - Class<?> result = beanNameResolver.getBean(beanName).getClass(); context.setPropertyResolved(base, property); - return result; + + /* + * No resolver level isReadOnly property for this resolver + */ + if (beanNameResolver.isReadOnly((String) property)) { + return null; + } + + return beanNameResolver.getBean(beanName).getClass(); } } catch (Throwable t) { Util.handleThrowable(t); diff --git a/java/jakarta/el/ListELResolver.java b/java/jakarta/el/ListELResolver.java index 73fcc39..de50fdf 100644 --- a/java/jakarta/el/ListELResolver.java +++ b/java/jakarta/el/ListELResolver.java @@ -51,6 +51,15 @@ public class ListELResolver extends ELResolver { throw new PropertyNotFoundException( new ArrayIndexOutOfBoundsException(idx).getMessage()); } + + /* + * Not perfect as a custom list implementation may be read-only but + * consistent with isReadOnly(). + */ + if (list.getClass() == UNMODIFIABLE || readOnly) { + return null; + } + return Object.class; } diff --git a/java/jakarta/el/MapELResolver.java b/java/jakarta/el/MapELResolver.java index 6ce3422..9526830 100644 --- a/java/jakarta/el/MapELResolver.java +++ b/java/jakarta/el/MapELResolver.java @@ -46,6 +46,12 @@ public class MapELResolver extends ELResolver { if (base instanceof Map<?,?>) { context.setPropertyResolved(base, property); + + Map<?, ?> map = (Map<?, ?>) base; + if (readOnly || map.getClass() == UNMODIFIABLE) { + return null; + } + return Object.class; } diff --git a/java/jakarta/el/ResourceBundleELResolver.java b/java/jakarta/el/ResourceBundleELResolver.java index 9f2563a..e9d0ceb 100644 --- a/java/jakarta/el/ResourceBundleELResolver.java +++ b/java/jakarta/el/ResourceBundleELResolver.java @@ -57,6 +57,10 @@ public class ResourceBundleELResolver extends ELResolver { if (base instanceof ResourceBundle) { context.setPropertyResolved(base, property); + /* + * ResourceBundles are always read-only so fall-through to return + * null + */ } return null; diff --git a/java/jakarta/el/StaticFieldELResolver.java b/java/jakarta/el/StaticFieldELResolver.java index 9083a5e..e164e9d 100644 --- a/java/jakarta/el/StaticFieldELResolver.java +++ b/java/jakarta/el/StaticFieldELResolver.java @@ -149,25 +149,15 @@ public class StaticFieldELResolver extends ELResolver { Class<?> clazz = ((ELClass) base).getKlass(); String name = (String) property; - Exception exception = null; try { - Field field = clazz.getField(name); - int modifiers = field.getModifiers(); - if (Modifier.isStatic(modifiers) && - Modifier.isPublic(modifiers) && - Util.canAccess(null, field)) { - return field.getType(); - } - } catch (IllegalArgumentException | NoSuchFieldException | - SecurityException e) { - exception = e; - } - String msg = Util.message(context, "staticFieldELResolver.notFound", - name, clazz.getName()); - if (exception == null) { - throw new PropertyNotFoundException(msg); - } else { - throw new PropertyNotFoundException(msg, exception); + clazz.getField(name); + /* + * This resolver is always read-only so fall-through to return + * null. + */ + } catch (IllegalArgumentException | NoSuchFieldException | SecurityException e) { + String msg = Util.message(context, "staticFieldELResolver.notFound", name, clazz.getName()); + throw new PropertyNotFoundException(msg, e); } } return null; diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index a31ce21..47e73b5 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -115,6 +115,13 @@ that used variables rather than literals for both keys and values. (markt) </fix> + <update> + Ensure that the <code>getType()</code> method of any + <code>ELResolver</code> implementation returns <code>null</code> if + either the <code>ELResolver</code> or the resolved property is read-only + to align Tomcat with recent updates in the Jakarta EL specification + project. (markt) + </update> </changelog> </subsection> </section> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org