Details
Description
When BeginString=FIXT.1.1 messages can be skipped if the buffer ends before the last '=' of "8=FIXT.1.1\0019=". That will happen if the buffer contains a correct message before that.
Example:
in messages:
8=FIXT.1.1\0019=12\00135=X\001108=30\00110=036\0018=FIXT.1.1\0019=12\00135=X\001108=30\00110=036\001
the second message will fail to be decoded if the buffer contents presented to the FixMessageDecoder in two subsequent decode() invocations are:
"8=FIXT.1.1\0019=12\00135=X\001108=30\00110=036\0018=FIXT.1.1\0019"
and
"=12\00135=X\001108=30\00110=036\001"
I have created tests to replicate this issue (and also issue QFJ-505) and included fixes (for this and the fix proposed in QFJ-505).
Here is the diff:
Index: core/src/test/java/quickfix/mina/message/FIXMessageDecoderTest.java
===================================================================
— core/src/test/java/quickfix/mina/message/FIXMessageDecoderTest.java (revision 46)
+++ core/src/test/java/quickfix/mina/message/FIXMessageDecoderTest.java (revision 49)
@@ -348,7 +348,22 @@
@Test
public void testMinaDemux() throws Exception
+
+ @Test
+ public void testMinaDemuxFixt() throws Exception
+
+ private void doTestMinaDemux(String message) throws Exception, UnsupportedEncodingException {
+ DemuxingProtocolCodecFactory codecFactory = new DemuxingProtocolCodecFactory();
codecFactory.register(FIXMessageDecoder.class);
ProtocolDecoder decoder = codecFactory.getDecoder();
@@ -359,7 +374,7 @@
int count = 5;
String data = "";
for (int i = 0; i < count; i++)
for (int i = 1; i < data.length(); i++)
{ @@ -379,9 +394,8 @@ output.reset(); buffer.clear(); }-
- }
-
+ }
+
private void assertMessageFound(String data) throws ProtocolCodecException { assertMessageFound(data, 1); }Index: core/src/main/java/quickfix/mina/message/FIXMessageDecoder.java
===================================================================-
- core/src/main/java/quickfix/mina/message/FIXMessageDecoder.java (revision 46)
+++ core/src/main/java/quickfix/mina/message/FIXMessageDecoder.java (revision 49)
@@ -123,7 +123,7 @@
}
if (messageCount > 0) {
// Mina will compact the buffer because we can't detect a header
- core/src/main/java/quickfix/mina/message/FIXMessageDecoder.java (revision 46)
-
- if (in.remaining() < minMaskLength(HEADER_PATTERN))
Unknown macro: {+ if (state == SEEKING_HEADER) { position = 0; } return MessageDecoderResult.OK;@@ -297,7 +297,8 @@ }
private static BufPos indexOf(ByteBuffer buffer, int position, byte[] data) {
- for (int offset = position, limit = buffer.limit() - minMaskLength(data) + 1; offset < limit; offset++) {
+ int limit = buffer.limit() - minMaskLength(data) + 1;
+ for (int offset = position ; offset < limit; offset++)Unknown macro: { int length; if (buffer.get(offset) == data[0] && (length = startsWith(buffer, offset, data)) > 0) { return new BufPos(offset, length); @@ -337,6 +338,10 @@ return -1; } }+ if(dataOffset != data.length)
{ + // when minMaskLength(data) != data.length we might run out of buffer before we run out of data + return -1; + }return bufferOffset - initOffset;
}