From 16db46f43e005e133c994ef1f74a391d44537640 Mon Sep 17 00:00:00 2001 From: Sergei Date: Thu, 7 Jun 2018 20:33:46 +0300 Subject: [PATCH 1/3] ECR-1624 Messages payload length fix --- .../messages/BinaryMessageBuilder.java | 4 +-- .../com/exonum/binding/messages/Message.java | 2 +- .../binding/messages/MessageReader.java | 2 +- .../binding/messages/MessageReaderTest.java | 27 +++++++++++++------ 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/exonum-java-binding-core/src/main/java/com/exonum/binding/messages/BinaryMessageBuilder.java b/exonum-java-binding-core/src/main/java/com/exonum/binding/messages/BinaryMessageBuilder.java index 54e0b2a2e9..74375962c8 100644 --- a/exonum-java-binding-core/src/main/java/com/exonum/binding/messages/BinaryMessageBuilder.java +++ b/exonum-java-binding-core/src/main/java/com/exonum/binding/messages/BinaryMessageBuilder.java @@ -1,6 +1,6 @@ package com.exonum.binding.messages; -import static com.exonum.binding.messages.Message.BODY_LENGTH_OFFSET; +import static com.exonum.binding.messages.Message.PAYLOAD_LENGTH_OFFSET; import static com.exonum.binding.messages.Message.BODY_OFFSET; import static com.exonum.binding.messages.Message.MESSAGE_TYPE_OFFSET; import static com.exonum.binding.messages.Message.NET_ID_OFFSET; @@ -62,7 +62,7 @@ private void putHeader(ByteBuffer buffer) { .put(VERSION_OFFSET, message.getVersion()) .putShort(SERVICE_ID_OFFSET, message.getServiceId()) .putShort(MESSAGE_TYPE_OFFSET, message.getMessageType()) - .putInt(BODY_LENGTH_OFFSET, message.getBody().remaining()); + .putInt(PAYLOAD_LENGTH_OFFSET, message.size()); } private void putBody(ByteBuffer buffer) { diff --git a/exonum-java-binding-core/src/main/java/com/exonum/binding/messages/Message.java b/exonum-java-binding-core/src/main/java/com/exonum/binding/messages/Message.java index fa708c0eb1..6186582d22 100644 --- a/exonum-java-binding-core/src/main/java/com/exonum/binding/messages/Message.java +++ b/exonum-java-binding-core/src/main/java/com/exonum/binding/messages/Message.java @@ -13,7 +13,7 @@ public interface Message { int VERSION_OFFSET = 1; int MESSAGE_TYPE_OFFSET = 2; int SERVICE_ID_OFFSET = 4; - int BODY_LENGTH_OFFSET = 6; + int PAYLOAD_LENGTH_OFFSET = 6; int HEADER_SIZE = 10; int BODY_OFFSET = HEADER_SIZE; int SIGNATURE_SIZE = 64; diff --git a/exonum-java-binding-core/src/main/java/com/exonum/binding/messages/MessageReader.java b/exonum-java-binding-core/src/main/java/com/exonum/binding/messages/MessageReader.java index 78f5e60548..953a78393b 100644 --- a/exonum-java-binding-core/src/main/java/com/exonum/binding/messages/MessageReader.java +++ b/exonum-java-binding-core/src/main/java/com/exonum/binding/messages/MessageReader.java @@ -84,7 +84,7 @@ public ByteBuffer getBody() { } private int bodySize() { - return message.getInt(BODY_LENGTH_OFFSET); + return message.getInt(PAYLOAD_LENGTH_OFFSET) - HEADER_SIZE - SIGNATURE_SIZE; } /** diff --git a/exonum-java-binding-core/src/test/java/com/exonum/binding/messages/MessageReaderTest.java b/exonum-java-binding-core/src/test/java/com/exonum/binding/messages/MessageReaderTest.java index 29231a1596..9ad554838f 100644 --- a/exonum-java-binding-core/src/test/java/com/exonum/binding/messages/MessageReaderTest.java +++ b/exonum-java-binding-core/src/test/java/com/exonum/binding/messages/MessageReaderTest.java @@ -1,10 +1,11 @@ package com.exonum.binding.messages; import static com.exonum.binding.messages.ByteBufferAllocator.allocateBuffer; -import static com.exonum.binding.messages.Message.BODY_LENGTH_OFFSET; import static com.exonum.binding.messages.Message.BODY_OFFSET; +import static com.exonum.binding.messages.Message.HEADER_SIZE; import static com.exonum.binding.messages.Message.MESSAGE_TYPE_OFFSET; import static com.exonum.binding.messages.Message.NET_ID_OFFSET; +import static com.exonum.binding.messages.Message.PAYLOAD_LENGTH_OFFSET; import static com.exonum.binding.messages.Message.SERVICE_ID_OFFSET; import static com.exonum.binding.messages.Message.SIGNATURE_SIZE; import static com.exonum.binding.messages.Message.VERSION_OFFSET; @@ -45,7 +46,8 @@ public void wrapThrowsIfTooSmall2() throws Exception { @Test public void wrapsMinimalMessage() throws Exception { - ByteBuffer buf = allocateBuffer(MIN_MESSAGE_BUFFER_SIZE); + ByteBuffer buf = allocateBuffer(MIN_MESSAGE_BUFFER_SIZE) + .putInt(PAYLOAD_LENGTH_OFFSET, MIN_MESSAGE_BUFFER_SIZE); MessageReader m = MessageReader.wrap(buf); @@ -54,7 +56,8 @@ public void wrapsMinimalMessage() throws Exception { @Test public void wrapsWhenLimitNotEqualCapacity() throws Exception { - ByteBuffer buf = allocateBuffer(2 * MIN_MESSAGE_BUFFER_SIZE); + ByteBuffer buf = allocateBuffer(2 * MIN_MESSAGE_BUFFER_SIZE) + .putInt(PAYLOAD_LENGTH_OFFSET, MIN_MESSAGE_BUFFER_SIZE); buf.limit(MIN_MESSAGE_BUFFER_SIZE); MessageReader m = MessageReader.wrap(buf); @@ -67,7 +70,7 @@ public void wrapThrowsIfBodySizeFieldDoesNotMatchActual() throws Exception { int bufferSize = MIN_MESSAGE_BUFFER_SIZE; ByteBuffer buf = allocateBuffer(bufferSize); int bodySize = 2048; - buf.putInt(BODY_LENGTH_OFFSET, bodySize); + buf.putInt(PAYLOAD_LENGTH_OFFSET, bodySize + HEADER_SIZE + SIGNATURE_SIZE); int expectedBufferSize = Message.messageSize(bodySize); expectedException.expectMessage("The size of the buffer (" + bufferSize @@ -80,6 +83,7 @@ public void wrapThrowsIfBodySizeFieldDoesNotMatchActual() throws Exception { public void getNetworkId() throws Exception { byte netId = 0x01; ByteBuffer buf = allocateBuffer(MIN_MESSAGE_BUFFER_SIZE) + .putInt(PAYLOAD_LENGTH_OFFSET, MIN_MESSAGE_BUFFER_SIZE) .put(NET_ID_OFFSET, netId); MessageReader m = MessageReader.wrap(buf); @@ -91,6 +95,7 @@ public void getNetworkId() throws Exception { public void getVersion() throws Exception { byte version = 0x02; ByteBuffer buf = allocateBuffer(MIN_MESSAGE_BUFFER_SIZE) + .putInt(PAYLOAD_LENGTH_OFFSET, MIN_MESSAGE_BUFFER_SIZE) .put(VERSION_OFFSET, version); MessageReader m = MessageReader.wrap(buf); @@ -102,6 +107,7 @@ public void getVersion() throws Exception { public void getServiceId() throws Exception { short serviceId = 0x0BCD; ByteBuffer buf = allocateBuffer(MIN_MESSAGE_BUFFER_SIZE) + .putInt(PAYLOAD_LENGTH_OFFSET, MIN_MESSAGE_BUFFER_SIZE) .putShort(SERVICE_ID_OFFSET, serviceId); MessageReader m = MessageReader.wrap(buf); @@ -113,6 +119,7 @@ public void getServiceId() throws Exception { public void getMessageType() throws Exception { short messageType = 0x0BCD; ByteBuffer buf = allocateBuffer(MIN_MESSAGE_BUFFER_SIZE) + .putInt(PAYLOAD_LENGTH_OFFSET, MIN_MESSAGE_BUFFER_SIZE) .putShort(MESSAGE_TYPE_OFFSET, messageType); MessageReader m = MessageReader.wrap(buf); @@ -122,7 +129,8 @@ public void getMessageType() throws Exception { @Test public void getBody_Empty() throws Exception { - ByteBuffer buf = allocateBuffer(MIN_MESSAGE_BUFFER_SIZE); + ByteBuffer buf = allocateBuffer(MIN_MESSAGE_BUFFER_SIZE) + .putInt(PAYLOAD_LENGTH_OFFSET, MIN_MESSAGE_BUFFER_SIZE); boolean directBuffer = buf.isDirect(); MessageReader m = MessageReader.wrap(buf); @@ -137,7 +145,7 @@ public void getBody_4Bytes() throws Exception { int bodySize = Integer.BYTES; int bodyValue = 0x12345678; ByteBuffer buf = allocateBuffer(MIN_MESSAGE_BUFFER_SIZE + bodySize) - .putInt(BODY_LENGTH_OFFSET, bodySize) + .putInt(PAYLOAD_LENGTH_OFFSET, MIN_MESSAGE_BUFFER_SIZE + bodySize) .putInt(BODY_OFFSET, bodyValue); MessageReader m = MessageReader.wrap(buf); @@ -151,7 +159,8 @@ public void getBody_4Bytes() throws Exception { @Test public void getSignature() throws Exception { byte[] signature = createPrefixed(bytes("Signature bytes"), SIGNATURE_SIZE); - ByteBuffer buf = allocateBuffer(MIN_MESSAGE_BUFFER_SIZE); + ByteBuffer buf = allocateBuffer(MIN_MESSAGE_BUFFER_SIZE) + .putInt(PAYLOAD_LENGTH_OFFSET, MIN_MESSAGE_BUFFER_SIZE); buf.position(MIN_MESSAGE_BUFFER_SIZE - SIGNATURE_SIZE); buf.put(signature); buf.flip(); @@ -164,6 +173,7 @@ public void getSignature() throws Exception { @Test public void getMessage() throws Exception { ByteBuffer buf = allocateBuffer(MIN_MESSAGE_BUFFER_SIZE) + .putInt(PAYLOAD_LENGTH_OFFSET, MIN_MESSAGE_BUFFER_SIZE) .put(NET_ID_OFFSET, (byte) 0x02) .put(VERSION_OFFSET, (byte) 0x01) .putShort(MESSAGE_TYPE_OFFSET, (short) 0x0ABC); @@ -177,7 +187,8 @@ public void getMessage() throws Exception { @Test public void size() throws Exception { int bufferSize = MIN_MESSAGE_BUFFER_SIZE; - ByteBuffer buf = allocateBuffer(bufferSize); + ByteBuffer buf = allocateBuffer(bufferSize) + .putInt(PAYLOAD_LENGTH_OFFSET, bufferSize); MessageReader m = MessageReader.wrap(buf); From 492fbbf63c6003f97265f92075acc1ff85629cc9 Mon Sep 17 00:00:00 2001 From: Sergei Date: Fri, 8 Jun 2018 10:24:53 +0300 Subject: [PATCH 2/3] ECR-1624 Checkstyle fix --- .../java/com/exonum/binding/messages/BinaryMessageBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exonum-java-binding-core/src/main/java/com/exonum/binding/messages/BinaryMessageBuilder.java b/exonum-java-binding-core/src/main/java/com/exonum/binding/messages/BinaryMessageBuilder.java index 74375962c8..c398a21600 100644 --- a/exonum-java-binding-core/src/main/java/com/exonum/binding/messages/BinaryMessageBuilder.java +++ b/exonum-java-binding-core/src/main/java/com/exonum/binding/messages/BinaryMessageBuilder.java @@ -1,9 +1,9 @@ package com.exonum.binding.messages; -import static com.exonum.binding.messages.Message.PAYLOAD_LENGTH_OFFSET; import static com.exonum.binding.messages.Message.BODY_OFFSET; import static com.exonum.binding.messages.Message.MESSAGE_TYPE_OFFSET; import static com.exonum.binding.messages.Message.NET_ID_OFFSET; +import static com.exonum.binding.messages.Message.PAYLOAD_LENGTH_OFFSET; import static com.exonum.binding.messages.Message.SERVICE_ID_OFFSET; import static com.exonum.binding.messages.Message.VERSION_OFFSET; import static com.google.common.base.Preconditions.checkNotNull; From 5bf2e5f351a7dc58b06fb5c5cb5ec8d3154dfe1c Mon Sep 17 00:00:00 2001 From: Dmitry Timofeev Date: Fri, 8 Jun 2018 18:22:44 +0300 Subject: [PATCH 3/3] Some improvements to MessageReader: - Clarify the exception messages - Make size() return the value from the header (also check it matches the buffer size). - Add more tests - Extract allocateMessageBuffer --- .../binding/messages/MessageReader.java | 12 +-- .../binding/messages/MessageReaderTest.java | 79 ++++++++++++------- 2 files changed, 58 insertions(+), 33 deletions(-) diff --git a/exonum-java-binding-core/src/main/java/com/exonum/binding/messages/MessageReader.java b/exonum-java-binding-core/src/main/java/com/exonum/binding/messages/MessageReader.java index 953a78393b..308de0d74c 100644 --- a/exonum-java-binding-core/src/main/java/com/exonum/binding/messages/MessageReader.java +++ b/exonum-java-binding-core/src/main/java/com/exonum/binding/messages/MessageReader.java @@ -30,11 +30,13 @@ public static MessageReader wrap(ByteBuffer buffer) { int bufferSize = buffer.limit(); checkArgument(MIN_MESSAGE_BUFFER_SIZE <= bufferSize, - "The buffer size (%s) is less than the minimal possible (%s)", + "The buffer size (%s) is less than the minimal possible message size (%s)", bufferSize, MIN_MESSAGE_BUFFER_SIZE); - int expectedSize = Message.messageSize(reader.bodySize()); + // Check the 'payload_length' field of the message matches the actual buffer size. + int expectedSize = reader.size(); checkArgument(bufferSize == expectedSize, - "The size of the buffer (%s) does not match expected (%s)", bufferSize, expectedSize); + "The size of the buffer (%s) does not match the expected size " + + "specified in the message header (%s)", bufferSize, expectedSize); return reader; } @@ -84,7 +86,7 @@ public ByteBuffer getBody() { } private int bodySize() { - return message.getInt(PAYLOAD_LENGTH_OFFSET) - HEADER_SIZE - SIGNATURE_SIZE; + return size() - HEADER_SIZE - SIGNATURE_SIZE; } /** @@ -101,7 +103,7 @@ public ByteBuffer getSignature() { @Override public int size() { - return message.limit(); + return message.getInt(PAYLOAD_LENGTH_OFFSET); } /** diff --git a/exonum-java-binding-core/src/test/java/com/exonum/binding/messages/MessageReaderTest.java b/exonum-java-binding-core/src/test/java/com/exonum/binding/messages/MessageReaderTest.java index 9ad554838f..36145999d3 100644 --- a/exonum-java-binding-core/src/test/java/com/exonum/binding/messages/MessageReaderTest.java +++ b/exonum-java-binding-core/src/test/java/com/exonum/binding/messages/MessageReaderTest.java @@ -2,7 +2,6 @@ import static com.exonum.binding.messages.ByteBufferAllocator.allocateBuffer; import static com.exonum.binding.messages.Message.BODY_OFFSET; -import static com.exonum.binding.messages.Message.HEADER_SIZE; import static com.exonum.binding.messages.Message.MESSAGE_TYPE_OFFSET; import static com.exonum.binding.messages.Message.NET_ID_OFFSET; import static com.exonum.binding.messages.Message.PAYLOAD_LENGTH_OFFSET; @@ -30,7 +29,8 @@ public class MessageReaderTest { public void wrapThrowsIfTooSmall() throws Exception { ByteBuffer buf = allocateBuffer(2); - expectedException.expectMessage("The buffer size (2) is less than the minimal possible (74)"); + expectedException.expectMessage("The buffer size (2) is less than the minimal possible " + + "message size (74)"); expectedException.expect(IllegalArgumentException.class); MessageReader.wrap(buf); } @@ -39,15 +39,25 @@ public void wrapThrowsIfTooSmall() throws Exception { public void wrapThrowsIfTooSmall2() throws Exception { ByteBuffer buf = allocateBuffer(MIN_MESSAGE_BUFFER_SIZE - 1); - expectedException.expectMessage("The buffer size (73) is less than the minimal possible (74)"); + expectedException.expectMessage("The buffer size (73) is less than the minimal possible " + + "message size (74)"); + expectedException.expect(IllegalArgumentException.class); + MessageReader.wrap(buf); + } + + @Test + public void wrapThrowsIfTooSmallWithSetMessageSize() throws Exception { + ByteBuffer buf = allocateMessageBuffer(MIN_MESSAGE_BUFFER_SIZE - 1); + + expectedException.expectMessage("The buffer size (73) is less than the minimal possible " + + "message size (74)"); expectedException.expect(IllegalArgumentException.class); MessageReader.wrap(buf); } @Test public void wrapsMinimalMessage() throws Exception { - ByteBuffer buf = allocateBuffer(MIN_MESSAGE_BUFFER_SIZE) - .putInt(PAYLOAD_LENGTH_OFFSET, MIN_MESSAGE_BUFFER_SIZE); + ByteBuffer buf = allocateMessageBuffer(MIN_MESSAGE_BUFFER_SIZE); MessageReader m = MessageReader.wrap(buf); @@ -66,15 +76,29 @@ public void wrapsWhenLimitNotEqualCapacity() throws Exception { } @Test - public void wrapThrowsIfBodySizeFieldDoesNotMatchActual() throws Exception { + public void wrapThrowsIfMessageSizeFieldGreaterThanActual() throws Exception { int bufferSize = MIN_MESSAGE_BUFFER_SIZE; ByteBuffer buf = allocateBuffer(bufferSize); - int bodySize = 2048; - buf.putInt(PAYLOAD_LENGTH_OFFSET, bodySize + HEADER_SIZE + SIGNATURE_SIZE); + int messageSize = 2048; + buf.putInt(PAYLOAD_LENGTH_OFFSET, messageSize); - int expectedBufferSize = Message.messageSize(bodySize); expectedException.expectMessage("The size of the buffer (" + bufferSize - + ") does not match expected (" + expectedBufferSize + ")"); + + ") does not match the expected size specified in the message header (" + messageSize + + ")"); + expectedException.expect(IllegalArgumentException.class); + MessageReader.wrap(buf); + } + + @Test + public void wrapThrowsIfMessageSizeFieldLessThanActual() throws Exception { + int bufferSize = 2 * MIN_MESSAGE_BUFFER_SIZE; + ByteBuffer buf = allocateBuffer(bufferSize); + int messageSize = bufferSize - 1; + buf.putInt(PAYLOAD_LENGTH_OFFSET, messageSize); + + expectedException.expectMessage("The size of the buffer (" + bufferSize + + ") does not match the expected size specified in the message header (" + messageSize + + ")"); expectedException.expect(IllegalArgumentException.class); MessageReader.wrap(buf); } @@ -82,8 +106,7 @@ public void wrapThrowsIfBodySizeFieldDoesNotMatchActual() throws Exception { @Test public void getNetworkId() throws Exception { byte netId = 0x01; - ByteBuffer buf = allocateBuffer(MIN_MESSAGE_BUFFER_SIZE) - .putInt(PAYLOAD_LENGTH_OFFSET, MIN_MESSAGE_BUFFER_SIZE) + ByteBuffer buf = allocateMessageBuffer(MIN_MESSAGE_BUFFER_SIZE) .put(NET_ID_OFFSET, netId); MessageReader m = MessageReader.wrap(buf); @@ -94,8 +117,7 @@ public void getNetworkId() throws Exception { @Test public void getVersion() throws Exception { byte version = 0x02; - ByteBuffer buf = allocateBuffer(MIN_MESSAGE_BUFFER_SIZE) - .putInt(PAYLOAD_LENGTH_OFFSET, MIN_MESSAGE_BUFFER_SIZE) + ByteBuffer buf = allocateMessageBuffer(MIN_MESSAGE_BUFFER_SIZE) .put(VERSION_OFFSET, version); MessageReader m = MessageReader.wrap(buf); @@ -106,8 +128,7 @@ public void getVersion() throws Exception { @Test public void getServiceId() throws Exception { short serviceId = 0x0BCD; - ByteBuffer buf = allocateBuffer(MIN_MESSAGE_BUFFER_SIZE) - .putInt(PAYLOAD_LENGTH_OFFSET, MIN_MESSAGE_BUFFER_SIZE) + ByteBuffer buf = allocateMessageBuffer(MIN_MESSAGE_BUFFER_SIZE) .putShort(SERVICE_ID_OFFSET, serviceId); MessageReader m = MessageReader.wrap(buf); @@ -118,8 +139,7 @@ public void getServiceId() throws Exception { @Test public void getMessageType() throws Exception { short messageType = 0x0BCD; - ByteBuffer buf = allocateBuffer(MIN_MESSAGE_BUFFER_SIZE) - .putInt(PAYLOAD_LENGTH_OFFSET, MIN_MESSAGE_BUFFER_SIZE) + ByteBuffer buf = allocateMessageBuffer(MIN_MESSAGE_BUFFER_SIZE) .putShort(MESSAGE_TYPE_OFFSET, messageType); MessageReader m = MessageReader.wrap(buf); @@ -129,8 +149,7 @@ public void getMessageType() throws Exception { @Test public void getBody_Empty() throws Exception { - ByteBuffer buf = allocateBuffer(MIN_MESSAGE_BUFFER_SIZE) - .putInt(PAYLOAD_LENGTH_OFFSET, MIN_MESSAGE_BUFFER_SIZE); + ByteBuffer buf = allocateMessageBuffer(MIN_MESSAGE_BUFFER_SIZE); boolean directBuffer = buf.isDirect(); MessageReader m = MessageReader.wrap(buf); @@ -144,8 +163,7 @@ public void getBody_Empty() throws Exception { public void getBody_4Bytes() throws Exception { int bodySize = Integer.BYTES; int bodyValue = 0x12345678; - ByteBuffer buf = allocateBuffer(MIN_MESSAGE_BUFFER_SIZE + bodySize) - .putInt(PAYLOAD_LENGTH_OFFSET, MIN_MESSAGE_BUFFER_SIZE + bodySize) + ByteBuffer buf = allocateMessageBuffer(MIN_MESSAGE_BUFFER_SIZE + bodySize) .putInt(BODY_OFFSET, bodyValue); MessageReader m = MessageReader.wrap(buf); @@ -159,8 +177,7 @@ public void getBody_4Bytes() throws Exception { @Test public void getSignature() throws Exception { byte[] signature = createPrefixed(bytes("Signature bytes"), SIGNATURE_SIZE); - ByteBuffer buf = allocateBuffer(MIN_MESSAGE_BUFFER_SIZE) - .putInt(PAYLOAD_LENGTH_OFFSET, MIN_MESSAGE_BUFFER_SIZE); + ByteBuffer buf = allocateMessageBuffer(MIN_MESSAGE_BUFFER_SIZE); buf.position(MIN_MESSAGE_BUFFER_SIZE - SIGNATURE_SIZE); buf.put(signature); buf.flip(); @@ -172,8 +189,7 @@ public void getSignature() throws Exception { @Test public void getMessage() throws Exception { - ByteBuffer buf = allocateBuffer(MIN_MESSAGE_BUFFER_SIZE) - .putInt(PAYLOAD_LENGTH_OFFSET, MIN_MESSAGE_BUFFER_SIZE) + ByteBuffer buf = allocateMessageBuffer(MIN_MESSAGE_BUFFER_SIZE) .put(NET_ID_OFFSET, (byte) 0x02) .put(VERSION_OFFSET, (byte) 0x01) .putShort(MESSAGE_TYPE_OFFSET, (short) 0x0ABC); @@ -187,11 +203,18 @@ public void getMessage() throws Exception { @Test public void size() throws Exception { int bufferSize = MIN_MESSAGE_BUFFER_SIZE; - ByteBuffer buf = allocateBuffer(bufferSize) - .putInt(PAYLOAD_LENGTH_OFFSET, bufferSize); + ByteBuffer buf = allocateMessageBuffer(bufferSize); MessageReader m = MessageReader.wrap(buf); assertThat(m.size(), equalTo(bufferSize)); } + + /** + * Allocates a byte buffer of the given size and sets its "payload_length" field. + */ + private static ByteBuffer allocateMessageBuffer(int bufferSize) { + return allocateBuffer(bufferSize) + .putInt(PAYLOAD_LENGTH_OFFSET, bufferSize); + } }