Skip to content

Commit 57d127b

Browse files
committed
Validate if STOMP frame is allowed to have a body
Issue: SPR-10890
1 parent 7c37497 commit 57d127b

File tree

5 files changed

+40
-24
lines changed

5 files changed

+40
-24
lines changed

spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompCommand.java

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,9 @@
1717
package org.springframework.messaging.simp.stomp;
1818

1919
import java.util.Arrays;
20+
import java.util.Collection;
2021
import java.util.HashMap;
21-
import java.util.HashSet;
2222
import java.util.Map;
23-
import java.util.Set;
2423

2524
import org.springframework.messaging.simp.SimpMessageType;
2625

@@ -51,36 +50,38 @@ public enum StompCommand {
5150
RECEIPT,
5251
ERROR;
5352

53+
private static Map<StompCommand, SimpMessageType> messageTypes = new HashMap<StompCommand, SimpMessageType>();
5454

55-
private static Map<StompCommand, SimpMessageType> messageTypeLookup = new HashMap<StompCommand, SimpMessageType>();
56-
57-
private static Set<StompCommand> destinationRequiredLookup =
58-
new HashSet<StompCommand>(Arrays.asList(SEND, SUBSCRIBE, MESSAGE));
59-
60-
private static Set<StompCommand> subscriptionIdRequiredLookup =
61-
new HashSet<StompCommand>(Arrays.asList(SUBSCRIBE, UNSUBSCRIBE, MESSAGE));
55+
private static Collection<StompCommand> destinationRequired = Arrays.asList(SEND, SUBSCRIBE, MESSAGE);
56+
private static Collection<StompCommand> subscriptionIdRequired = Arrays.asList(SUBSCRIBE, UNSUBSCRIBE, MESSAGE);
57+
private static Collection<StompCommand> bodyAllowed = Arrays.asList(SEND, MESSAGE, ERROR);
6258

6359
static {
64-
messageTypeLookup.put(StompCommand.CONNECT, SimpMessageType.CONNECT);
65-
messageTypeLookup.put(StompCommand.STOMP, SimpMessageType.CONNECT);
66-
messageTypeLookup.put(StompCommand.SEND, SimpMessageType.MESSAGE);
67-
messageTypeLookup.put(StompCommand.MESSAGE, SimpMessageType.MESSAGE);
68-
messageTypeLookup.put(StompCommand.SUBSCRIBE, SimpMessageType.SUBSCRIBE);
69-
messageTypeLookup.put(StompCommand.UNSUBSCRIBE, SimpMessageType.UNSUBSCRIBE);
70-
messageTypeLookup.put(StompCommand.DISCONNECT, SimpMessageType.DISCONNECT);
60+
messageTypes.put(StompCommand.CONNECT, SimpMessageType.CONNECT);
61+
messageTypes.put(StompCommand.STOMP, SimpMessageType.CONNECT);
62+
messageTypes.put(StompCommand.SEND, SimpMessageType.MESSAGE);
63+
messageTypes.put(StompCommand.MESSAGE, SimpMessageType.MESSAGE);
64+
messageTypes.put(StompCommand.SUBSCRIBE, SimpMessageType.SUBSCRIBE);
65+
messageTypes.put(StompCommand.UNSUBSCRIBE, SimpMessageType.UNSUBSCRIBE);
66+
messageTypes.put(StompCommand.DISCONNECT, SimpMessageType.DISCONNECT);
7167
}
7268

7369
public SimpMessageType getMessageType() {
74-
SimpMessageType type = messageTypeLookup.get(this);
70+
SimpMessageType type = messageTypes.get(this);
7571
return (type != null) ? type : SimpMessageType.OTHER;
7672
}
7773

7874
public boolean requiresDestination() {
79-
return destinationRequiredLookup.contains(this);
75+
return destinationRequired.contains(this);
8076
}
8177

8278
public boolean requiresSubscriptionId() {
83-
return subscriptionIdRequiredLookup.contains(this);
79+
return subscriptionIdRequired.contains(this);
80+
}
81+
82+
public boolean isBodyAllowed() {
83+
return bodyAllowed.contains(this);
8484
}
8585

8686
}
87+

spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompDecoder.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@
2929
import org.springframework.util.MultiValueMap;
3030

3131
/**
32-
* A decoder for STOMP frames
32+
* A decoder for STOMP frames.
3333
*
34-
* @author awilkinson
34+
* @author Andy Wilkinson
3535
* @since 4.0
3636
*/
3737
public class StompDecoder {
@@ -60,8 +60,15 @@ public Message<byte[]> decode(ByteBuffer buffer) {
6060
MultiValueMap<String, String> headers = readHeaders(buffer);
6161
byte[] payload = readPayload(buffer, headers);
6262

63-
decodedMessage = MessageBuilder.withPayload(payload).setHeaders(
64-
StompHeaderAccessor.create(StompCommand.valueOf(command), headers)).build();
63+
StompCommand stompCommand = StompCommand.valueOf(command);
64+
if ((payload.length > 0) && (!stompCommand.isBodyAllowed())) {
65+
throw new StompConversionException(stompCommand +
66+
" isn't allowed to have a body but has payload length=" + payload.length +
67+
", headers=" + headers);
68+
}
69+
70+
decodedMessage = MessageBuilder.withPayload(payload)
71+
.setHeaders(StompHeaderAccessor.create(stompCommand, headers)).build();
6572
}
6673
else {
6774
decodedMessage = MessageBuilder.withPayload(HEARTBEAT_PAYLOAD).setHeaders(

spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompEncoder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
import org.springframework.messaging.simp.SimpMessageType;
3030

3131
/**
32-
* An encoder for STOMP frames
32+
* An encoder for STOMP frames.
3333
*
3434
* @author Andy Wilkinson
3535
* @since 4.0

spring-messaging/src/main/java/org/springframework/messaging/support/converter/MessageConversionException.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,15 @@
2020
import org.springframework.messaging.MessagingException;
2121

2222
/**
23+
* An exception raised by {@link MessageConverter} implementations.
24+
*
2325
* @author Mark Fisher
2426
* @since 4.0
2527
*/
2628
@SuppressWarnings("serial")
2729
public class MessageConversionException extends MessagingException {
2830

31+
2932
public MessageConversionException(String description, Throwable cause) {
3033
super(description, cause);
3134
}

spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompCodecTests.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,11 @@ public void decodeFrameWithEscapedHeaders() {
133133
assertEquals("alpha:bravo\r\n\\", headers.getFirstNativeHeader("a:\r\n\\b"));
134134
}
135135

136+
@Test(expected=StompConversionException.class)
137+
public void decodeFrameBodyNotAllowed() {
138+
decode("CONNECT\naccept-version:1.2\n\nThe body of the message\0");
139+
}
140+
136141
@Test
137142
public void decodeMultipleFramesFromSameBuffer() {
138143
String frame1 = "SEND\ndestination:test\n\nThe body of the message\0";

0 commit comments

Comments
 (0)