breken-ai opened a new pull request, #1075:
URL: https://github.com/apache/tomcat/pull/1075
## Fix `Map.Entry` contract for `CaseInsensitiveKeyMap` entries
`CaseInsensitiveKeyMap.entrySet()` returns `EntryImpl` instances.
`EntryImpl` is a record, so:
- `equals()` only returns true for another `EntryImpl`. An entry therefore
does not equal an equivalent entry from a `HashMap`, even though the reverse
comparison returns true (asymmetric `equals()`).
- `hashCode()` uses the record formula rather than the `Map.Entry`
definition (`key.hashCode() ^ value.hashCode()`). Because
`AbstractMap.hashCode()` sums the entry hash codes, a `CaseInsensitiveKeyMap`
that `equals()` a `HashMap` has a different `hashCode()`, which breaks the
`Map`/`Object` contract.
```java
Map<String,Object> ci = new CaseInsensitiveKeyMap<>();
ci.put("a", "b");
Map<String,Object> hm = new HashMap<>(ci);
hm.equals(ci); // true
hm.hashCode() == ci.hashCode(); // false
```
This map backs the header maps from the WebSocket
`HandshakeRequest.getHeaders()`, `HandshakeResponse.getHeaders()` and the
client `Configurator` callbacks, so applications can see these maps.
The fix returns `AbstractMap.SimpleImmutableEntry` instead of `EntryImpl`
and removes the record. `SimpleImmutableEntry` implements the `Map.Entry`
contract and still throws `UnsupportedOperationException` from `setValue()`, so
that behaviour is unchanged.
### Testing
- Added `TestCaseInsensitiveKeyMap.testEntryEqualsAndHashCode`. On `main`
(2a7e82c) it fails at `entry.equals(hashMapEntry)`, and it passes with the fix.
- `ant test -Dtest.name='org/apache/tomcat/util/collections/Test*.java'`:
all pass. `org.apache.tomcat.websocket.TestWsWebSocketContainer`: 24/24 pass
(NIO, JDK 21.0.12).
- `ant validate -Dexecute.validate=true` (Checkstyle) passes.
- Added a changelog entry under WebSocket.
I wrote this change with help from an AI coding assistant, then reviewed it
and ran the tests above myself.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]