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 4925c140965..e73037f1def 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 @@ -208,10 +208,15 @@ public class StompDecoder { private void readHeaders(ByteBuffer buffer, StompHeaderAccessor headerAccessor) { while (true) { ByteArrayOutputStream headerStream = new ByteArrayOutputStream(256); - while (buffer.remaining() > 0 && !tryConsumeEndOfLine(buffer)) { + boolean headerComplete = false; + while (buffer.hasRemaining()) { + if (tryConsumeEndOfLine(buffer)) { + headerComplete = true; + break; + } headerStream.write(buffer.get()); } - if (headerStream.size() > 0) { + if (headerStream.size() > 0 && headerComplete) { String header = new String(headerStream.toByteArray(), UTF8_CHARSET); int colonIndex = header.indexOf(':'); if (colonIndex <= 0 || colonIndex == header.length() - 1) { diff --git a/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/BufferingStompDecoderTests.java b/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/BufferingStompDecoderTests.java index 40efd2aec72..6f6e4272bfe 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/BufferingStompDecoderTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/BufferingStompDecoderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -25,7 +25,9 @@ import org.junit.Test; import org.springframework.messaging.Message; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; /** * Unit tests for {@link BufferingStompDecoder}. @@ -177,13 +179,30 @@ public class BufferingStompDecoderTests { assertEquals(0, messages.size()); } - @Test(expected = StompConversionException.class) // SPR-12418 - public void endingBackslashHeaderValueCheck() { + // SPR-13416 + + @Test + public void incompleteHeaderWithPartialEscapeSequence() throws Exception { BufferingStompDecoder stompDecoder = new BufferingStompDecoder(STOMP_DECODER, 128); - String payload = "SEND\na:alpha\\\n\nMessage body\0"; + String chunk = "SEND\na:long\\"; + + List> messages = stompDecoder.decode(toByteBuffer(chunk)); + assertEquals(0, messages.size()); + } + + @Test(expected = StompConversionException.class) + public void invalidEscapeSequence() { + BufferingStompDecoder stompDecoder = new BufferingStompDecoder(STOMP_DECODER, 128); + String payload = "SEND\na:alpha\\x\\n\nMessage body\0"; stompDecoder.decode(toByteBuffer(payload)); } + @Test(expected = StompConversionException.class) + public void invalidEscapeSequenceWithSingleSlashAtEndOfHeaderValue() { + BufferingStompDecoder stompDecoder = new BufferingStompDecoder(STOMP_DECODER, 128); + String payload = "SEND\na:alpha\\\n\nMessage body\0"; + stompDecoder.decode(toByteBuffer(payload)); + } private ByteBuffer toByteBuffer(String chunk) { return ByteBuffer.wrap(chunk.getBytes(Charset.forName("UTF-8")));