This is an automated email from the ASF dual-hosted git repository.

rmaucher pushed a commit to branch 11.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 2c6ab36a35ba23ab6bbd90798989db8d0353936f
Author: opencode <[email protected]>
AuthorDate: Mon Oct 19 10:41:42 2026 +0200

    Correct the expression wrapper equals implementation
    
    JspValueExpression and JspMethodExpression delegated equals() to the
    target expression. The engine's ValueExpressionImpl and
    MethodExpressionImpl only consider their own type equal, so a wrapper
    was never equal to itself or to another wrapper around the same target,
    violating the reflexivity requirement of the contract while hashCode(),
    also delegated to the target, reported such wrappers as equal.
    
    Check for the same instance, then compare the JSP location mark and the
    target expression of two wrappers. A wrapper is not equal to anything
    else, which is symmetric with the target implementations rejecting the
    wrapper type. The delegated hash stays consistent because equal
    wrappers always wrap equal targets.
    
    Found by code review.
---
 java/org/apache/jasper/el/JspMethodExpression.java | 9 ++++++++-
 java/org/apache/jasper/el/JspValueExpression.java  | 9 ++++++++-
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/java/org/apache/jasper/el/JspMethodExpression.java 
b/java/org/apache/jasper/el/JspMethodExpression.java
index d34be872c6..fddf3b8727 100644
--- a/java/org/apache/jasper/el/JspMethodExpression.java
+++ b/java/org/apache/jasper/el/JspMethodExpression.java
@@ -20,6 +20,7 @@ import java.io.Externalizable;
 import java.io.IOException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
+import java.util.Objects;
 
 import jakarta.el.ELContext;
 import jakarta.el.ELException;
@@ -141,7 +142,13 @@ public final class JspMethodExpression extends 
MethodExpression implements Exter
 
     @Override
     public boolean equals(Object obj) {
-        return this.target.equals(obj);
+        if (obj == this) {
+            return true;
+        }
+        if (!(obj instanceof JspMethodExpression other)) {
+            return false;
+        }
+        return Objects.equals(this.mark, other.mark) && 
this.target.equals(other.target);
     }
 
     @Override
diff --git a/java/org/apache/jasper/el/JspValueExpression.java 
b/java/org/apache/jasper/el/JspValueExpression.java
index 889ec675f2..25858ca70d 100644
--- a/java/org/apache/jasper/el/JspValueExpression.java
+++ b/java/org/apache/jasper/el/JspValueExpression.java
@@ -20,6 +20,7 @@ import java.io.Externalizable;
 import java.io.IOException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
+import java.util.Objects;
 
 import jakarta.el.ELContext;
 import jakarta.el.ELException;
@@ -146,7 +147,13 @@ public final class JspValueExpression extends 
ValueExpression implements Externa
 
     @Override
     public boolean equals(Object obj) {
-        return this.target.equals(obj);
+        if (obj == this) {
+            return true;
+        }
+        if (!(obj instanceof JspValueExpression other)) {
+            return false;
+        }
+        return Objects.equals(this.mark, other.mark) && 
this.target.equals(other.target);
     }
 
     @Override


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to