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 11548888b76edac782c70d18bd9c8f42da71a587 Author: opencode <[email protected]> AuthorDate: Wed Oct 14 14:22:20 2026 +0200 Return false rather than throw for SecurityRoleRef.equals(null) SecurityRoleRef.equals(Object) compared getClass() on the argument without a null check, so equals(null) dereferenced null and threw NullPointerException, violating the Object.equals contract which requires false for a null argument. Replace the getClass() comparison with an instanceof pattern match, consistent with LoginConfig in the same package, which handles both the null argument and foreign types by returning false. There are no subclasses of SecurityRoleRef in the tree, so behaviour is unchanged for all non-null inputs; hashCode is untouched and remains consistent with equals. No internal call site passes null (HashSet operations null-guard the query key), so this is a latent robustness fix. Adds TestSecurityRoleRef covering the null argument, the field comparison matrix and equality of instances with null fields. --- .../util/descriptor/web/SecurityRoleRef.java | 3 +- .../util/descriptor/web/TestSecurityRoleRef.java | 68 ++++++++++++++++++++++ 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/java/org/apache/tomcat/util/descriptor/web/SecurityRoleRef.java b/java/org/apache/tomcat/util/descriptor/web/SecurityRoleRef.java index d5dda48605..fd8164cab5 100644 --- a/java/org/apache/tomcat/util/descriptor/web/SecurityRoleRef.java +++ b/java/org/apache/tomcat/util/descriptor/web/SecurityRoleRef.java @@ -124,10 +124,9 @@ public class SecurityRoleRef implements Serializable { if (this == obj) { return true; } - if (getClass() != obj.getClass()) { + if (!(obj instanceof SecurityRoleRef other)) { return false; } - SecurityRoleRef other = (SecurityRoleRef) obj; if (!Objects.equals(link, other.link)) { return false; } diff --git a/test/org/apache/tomcat/util/descriptor/web/TestSecurityRoleRef.java b/test/org/apache/tomcat/util/descriptor/web/TestSecurityRoleRef.java new file mode 100644 index 0000000000..7aed6126bb --- /dev/null +++ b/test/org/apache/tomcat/util/descriptor/web/TestSecurityRoleRef.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tomcat.util.descriptor.web; + +import org.junit.Assert; +import org.junit.Test; + +public class TestSecurityRoleRef { + + @Test + public void testEqualsWithNull() { + // Contract: equals(null) must return false, not throw + SecurityRoleRef ref = new SecurityRoleRef(); + ref.setName("roleName"); + ref.setLink("roleLink"); + Assert.assertFalse(ref.equals(null)); + } + + @Test + public void testEquals() { + SecurityRoleRef ref1 = new SecurityRoleRef(); + ref1.setName("roleName"); + ref1.setLink("roleLink"); + + SecurityRoleRef ref2 = new SecurityRoleRef(); + ref2.setName("roleName"); + ref2.setLink("roleLink"); + + Assert.assertEquals(ref1, ref1); + Assert.assertEquals(ref1, ref2); + Assert.assertEquals(ref1.hashCode(), ref2.hashCode()); + + ref2.setLink("otherLink"); + Assert.assertNotEquals(ref1, ref2); + + ref2.setLink("roleLink"); + ref2.setName("otherName"); + Assert.assertNotEquals(ref1, ref2); + + Assert.assertNotEquals(ref1, new Object()); + } + + @Test + public void testEqualsNullFields() { + SecurityRoleRef ref1 = new SecurityRoleRef(); + SecurityRoleRef ref2 = new SecurityRoleRef(); + + Assert.assertEquals(ref1, ref2); + Assert.assertEquals(ref1.hashCode(), ref2.hashCode()); + + ref2.setName("roleName"); + Assert.assertNotEquals(ref1, ref2); + } +} --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
