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

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

commit 4f196926a55663f248b8aa3b0cca80041c812168
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 f8fc9e6b69..76700afddc 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 javax.el.ELContext;
 import javax.el.ELException;
@@ -115,7 +116,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 89ed10195e..58ae940c0d 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 javax.el.ELContext;
 import javax.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