Skip to content
Browse files

Handle invalid STOMP content-length header value

After this change if a content-length header is provided but is less
than 0 or cannot be parsed as a number, it is ignored and the body
is read sequentially, i.e. until we reach a null byte terminator.

This provides better protection against clients that may set the
content-length header in error.

Issue: SPR-11528
  • Loading branch information...
1 parent cff23b8 commit 13af188bdc55aba99f0c02dbcbce59ee6ace5351 @rstoyanchev rstoyanchev committed Mar 10, 2014
View
17 spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,6 +28,7 @@
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
+import org.springframework.util.StringUtils;
/**
* Decodes STOMP frames from a {@link ByteBuffer}. If the buffer does not contain
@@ -151,9 +152,17 @@ private String unescape(String input) {
}
private byte[] readPayload(ByteBuffer buffer, MultiValueMap<String, String> headers) {
- String contentLengthString = headers.getFirst("content-length");
- if (contentLengthString != null) {
- int contentLength = Integer.valueOf(contentLengthString);
+ Integer contentLength = null;
+ if (headers.containsKey("content-length")) {
+ String rawContentLength = headers.getFirst("content-length");
+ try {
+ contentLength = Integer.valueOf(rawContentLength);
+ }
+ catch (NumberFormatException ex) {
+ logger.warn("Ignoring invalid content-length header value: '" + rawContentLength + "'");
+ }
+ }
+ if (contentLength != null && contentLength >= 0) {
if (buffer.remaining() > contentLength) {
byte[] payload = new byte[contentLength];
buffer.get(payload);
View
32 spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompCodecTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -107,6 +107,36 @@ public void decodeFrameWithContentLength() {
assertEquals("The body of the message", bodyText);
}
+ // SPR-11528
+
+ @Test
+ public void decodeFrameWithInvalidContentLength() {
+ Message<byte[]> frame = decode("SEND\ncontent-length:-1\n\nThe body of the message\0");
+ StompHeaderAccessor headers = StompHeaderAccessor.wrap(frame);
+
+ assertEquals(StompCommand.SEND, headers.getCommand());
+
+ assertEquals(1, headers.toStompHeaderMap().size());
+ assertEquals(Integer.valueOf(-1), headers.getContentLength());
+
+ String bodyText = new String(frame.getPayload());
+ assertEquals("The body of the message", bodyText);
+ }
+
+ @Test
+ public void decodeFrameWithContentLengthZero() {
+ Message<byte[]> frame = decode("SEND\ncontent-length:0\n\n\0");
+ StompHeaderAccessor headers = StompHeaderAccessor.wrap(frame);
+
+ assertEquals(StompCommand.SEND, headers.getCommand());
+
+ assertEquals(1, headers.toStompHeaderMap().size());
+ assertEquals(Integer.valueOf(0), headers.getContentLength());
+
+ String bodyText = new String(frame.getPayload());
+ assertEquals("", bodyText);
+ }
+
@Test
public void decodeFrameWithNullOctectsInTheBody() {
Message<byte[]> frame = decode("SEND\ncontent-length:23\n\nThe b\0dy \0f the message\0");

0 comments on commit 13af188

Please sign in to comment.
Something went wrong with that request. Please try again.