Ensure Session#getAttributeNames implementations return a copy

Currently, Session#getAttributeNames implementations, by delegating to MapSession, all return a session attribute map's key set. This causes ConcurrentModificationException when an attempt to modify session attributes is made while iterating over the returned attribute names.

Closes gh-1120
This commit is contained in:
Vedran Pavic
2018-07-17 15:05:03 +02:00
parent dba475c48f
commit 936fc853df
8 changed files with 94 additions and 3 deletions

View File

@@ -367,6 +367,19 @@ public class ReactiveRedisOperationsSessionRepositoryTests {
verifyZeroInteractions(this.hashOperations);
}
@Test // gh-1120
public void getAttributeNamesAndRemove() {
RedisSession session = this.repository.new RedisSession(this.cached);
session.setAttribute("attribute1", "value1");
session.setAttribute("attribute2", "value2");
for (String attributeName : session.getAttributeNames()) {
session.removeAttribute(attributeName);
}
assertThat(session.getAttributeNames()).isEmpty();
}
private Map<String, Object> map(Object... objects) {
Map<String, Object> result = new HashMap<>();
if (objects == null) {

View File

@@ -868,6 +868,19 @@ public class RedisOperationsSessionRepositoryTests {
.hasMessage("namespace cannot be null or empty");
}
@Test // gh-1120
public void getAttributeNamesAndRemove() {
RedisSession session = this.redisRepository.new RedisSession(this.cached);
session.setAttribute("attribute1", "value1");
session.setAttribute("attribute2", "value2");
for (String attributeName : session.getAttributeNames()) {
session.removeAttribute(attributeName);
}
assertThat(session.getAttributeNames()).isEmpty();
}
private String getKey(String id) {
return "spring:session:sessions:" + id;
}