From 5d91560f9230a1673036ee0a9b5e4aa75c4f148c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8C=E1=85=A9=E1=84=92=E1=85=A7=E1=86=AB=E1=84=89?= =?UTF-8?q?=E1=85=AE=28Hyunsoo=20Cho=29/Platform=20Engineering=E1=84=90?= =?UTF-8?q?=E1=85=B5=E1=86=B7/11ST?= Date: Wed, 24 Nov 2021 15:20:51 +0900 Subject: [PATCH] Avoid unescape for CONNECT and CONNECTED frames See gh-27722 --- .../messaging/simp/stomp/StompDecoder.java | 10 ++++++---- .../messaging/simp/stomp/StompDecoderTests.java | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompDecoder.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompDecoder.java index 70b2c0b2e5..66206f6679 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompDecoder.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompDecoder.java @@ -143,7 +143,7 @@ public class StompDecoder { StompCommand stompCommand = StompCommand.valueOf(command); headerAccessor = StompHeaderAccessor.create(stompCommand); initHeaders(headerAccessor); - readHeaders(byteBuffer, headerAccessor); + readHeaders(stompCommand, byteBuffer, headerAccessor); payload = readPayload(byteBuffer, headerAccessor); } if (payload != null) { @@ -215,7 +215,9 @@ public class StompDecoder { return StreamUtils.copyToString(command, StandardCharsets.UTF_8); } - private void readHeaders(ByteBuffer byteBuffer, StompHeaderAccessor headerAccessor) { + private void readHeaders(StompCommand stompCommand, ByteBuffer byteBuffer, StompHeaderAccessor headerAccessor) { + boolean shouldUnescape = (stompCommand != StompCommand.CONNECT && stompCommand != StompCommand.STOMP + && stompCommand != StompCommand.CONNECTED); while (true) { ByteArrayOutputStream headerStream = new ByteArrayOutputStream(256); boolean headerComplete = false; @@ -236,8 +238,8 @@ public class StompDecoder { } } else { - String headerName = unescape(header.substring(0, colonIndex)); - String headerValue = unescape(header.substring(colonIndex + 1)); + String headerName = shouldUnescape ? unescape(header.substring(0, colonIndex)) : header.substring(0, colonIndex); + String headerValue = shouldUnescape ? unescape(header.substring(colonIndex + 1)) : header.substring(colonIndex + 1); try { headerAccessor.addNativeHeader(headerName, headerValue); } diff --git a/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompDecoderTests.java b/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompDecoderTests.java index 439b157d2d..b0797dc6c1 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompDecoderTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompDecoderTests.java @@ -159,6 +159,23 @@ public class StompDecoderTests { assertThat(headers.getFirstNativeHeader("a:\r\n\\b")).isEqualTo("alpha:bravo\r\n\\"); } + @Test + public void decodeFrameWithHeaderWithBackslashValue() { + String accept = "accept-version:1.1\n"; + String keyAndValueWithBackslash = "key:\\value\n"; + + Message frame = decode("CONNECT\n" + accept + keyAndValueWithBackslash + "\n\0"); + StompHeaderAccessor headers = StompHeaderAccessor.wrap(frame); + + assertThat(headers.getCommand()).isEqualTo(StompCommand.CONNECT); + + assertThat(headers.toNativeHeaderMap().size()).isEqualTo(2); + assertThat(headers.getFirstNativeHeader("accept-version")).isEqualTo("1.1"); + assertThat(headers.getFirstNativeHeader("key")).isEqualTo("\\value"); + + assertThat(frame.getPayload().length).isEqualTo(0); + } + @Test public void decodeFrameBodyNotAllowed() { assertThatExceptionOfType(StompConversionException.class).isThrownBy(() ->