From d5664ba01ab94867964c93ce854805a50016a058 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Wed, 1 May 2024 12:23:04 +0200 Subject: [PATCH] Ensure old attributes are not removed by accident This commit ensures that a copy is made of old attributes before replacing it with new attributes. Because new attributes can be composed of old, clearing the old would also remove entries from the new. See gh-32245 --- .../web/reactive/function/server/RouterFunctions.java | 10 +++++++--- .../web/servlet/function/RouterFunctions.java | 9 +++++++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctions.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctions.java index 33e34568d0b..661d1e8e660 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctions.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctions.java @@ -1265,9 +1265,13 @@ public abstract class RouterFunctions { return this.routerFunction.route(nestedRequest) .doOnNext(match -> { if (nestedRequest != serverRequest) { - serverRequest.attributes().clear(); - serverRequest.attributes() - .putAll(nestedRequest.attributes()); + // new attributes map from nestedRequest.attributes() can be composed of the old attributes, + // which means that clearing the old attributes will remove those values from new attributes as well + // so let's make a copy + Map newAttributes = new LinkedHashMap<>(nestedRequest.attributes()); + Map oldAttributes = serverRequest.attributes(); + oldAttributes.clear(); + oldAttributes.putAll(newAttributes); } }); } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RouterFunctions.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RouterFunctions.java index 7e8a42004fa..4a10d726127 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RouterFunctions.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RouterFunctions.java @@ -1181,8 +1181,13 @@ public abstract class RouterFunctions { Optional> result = this.routerFunction.route(nestedRequest); if (result.isPresent() && nestedRequest != serverRequest) { - serverRequest.attributes().clear(); - serverRequest.attributes().putAll(nestedRequest.attributes()); + // new attributes map from nestedRequest.attributes() can be composed of the old attributes, + // which means that clearing the old attributes will remove those values from new attributes as well + // so let's make a copy + Map newAttributes = new LinkedHashMap<>(nestedRequest.attributes()); + Map oldAttributes = serverRequest.attributes(); + oldAttributes.clear(); + oldAttributes.putAll(newAttributes); } return result; }