From d8e4818c5e35991e9eafe270ebbe4a75930c0d2e Mon Sep 17 00:00:00 2001 From: Gavin Gray Date: Fri, 7 Feb 2014 12:46:16 -0500 Subject: [PATCH] INT-3290 Fix TCP Deserializer for 0 Length Message ByteArraySingleTerminatorSerializer does not support multiple subsequent terminators (zero length messages). JIRA: https://jira.springsource.org/browse/INT-3290 * Add unit test to verify bug. * Fix bug. Polishing: * Remove test for `n >= 0`; n cannot be < 0 here * Move test case to `DeserializationTests` --- .../ByteArraySingleTerminatorSerializer.java | 7 +++--- .../tcp/serializer/DeserializationTests.java | 22 ++++++++++++++++++- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/serializer/ByteArraySingleTerminatorSerializer.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/serializer/ByteArraySingleTerminatorSerializer.java index de20688a80..39bee41df3 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/serializer/ByteArraySingleTerminatorSerializer.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/serializer/ByteArraySingleTerminatorSerializer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 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. @@ -42,6 +42,7 @@ public class ByteArraySingleTerminatorSerializer extends AbstractByteArraySerial * is closed immediately after the terminator (i.e. no data is in the process of * being read). */ + @Override public byte[] deserialize(InputStream inputStream) throws IOException { byte[] buffer = new byte[this.maxMessageSize]; int n = 0; @@ -51,12 +52,11 @@ public class ByteArraySingleTerminatorSerializer extends AbstractByteArraySerial } while (true) { bite = inputStream.read(); -// logger.debug("Read:" + (char) bite); if (bite < 0 && n == 0) { throw new SoftEndOfStreamException("Stream closed between payloads"); } checkClosure(bite); - if (n > 0 && bite == terminator) { + if (bite == terminator) { break; } buffer[n++] = (byte) bite; @@ -73,6 +73,7 @@ public class ByteArraySingleTerminatorSerializer extends AbstractByteArraySerial /** * Writes the byte[] to the stream and appends the terminator. */ + @Override public void serialize(byte[] bytes, OutputStream outputStream) throws IOException { outputStream.write(bytes); outputStream.write(terminator); diff --git a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/serializer/DeserializationTests.java b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/serializer/DeserializationTests.java index edcbfd4af9..a713cc9534 100644 --- a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/serializer/DeserializationTests.java +++ b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/serializer/DeserializationTests.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. @@ -19,6 +19,7 @@ package org.springframework.integration.ip.tcp.serializer; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; @@ -34,6 +35,7 @@ import org.springframework.integration.test.util.SocketUtils; /** * @author Gary Russell + * @author Gavin Gray * @since 2.0 */ public class DeserializationTests { @@ -240,4 +242,22 @@ public class DeserializationTests { latch.countDown(); } + @Test + public void canDeserializeMultipleSubsequentTerminators() throws IOException { + byte terminator = (byte) '\n'; + ByteArraySingleTerminatorSerializer serializer = new ByteArraySingleTerminatorSerializer(terminator); + ByteArrayInputStream inputStream = new ByteArrayInputStream("s\n\n".getBytes()); + + try { + byte[] bytes = serializer.deserialize(inputStream); + assertEquals(1, bytes.length); + assertEquals("s".getBytes()[0], bytes[0]); + bytes = serializer.deserialize(inputStream); + assertEquals(0, bytes.length); + } + finally { + inputStream.close(); + } + } + }