QuickFIX/J

FIXMessageEncoder#encode() may throws java.nio.BufferOverflowException if message contains Chinese characters

Details

  • Type: Bug Bug
  • Status: Open Open
  • Priority: Default Default
  • Resolution: Unresolved
  • Affects Version/s: 1.2.1
  • Fix Version/s: Future Releases
  • Component/s: Engine
  • Labels:
    None

Description

FIXMessageEncoder#encode() may throws protocol handler exception: java.nio.BufferOverflowException, if message contains Chinese characters.

we use "UTF-8" as default charset instead of "ISO-8859-1". So charsetEncoding = "UTF-8".

FIXMessageEncoder#encode() :
   ByteBuffer buffer = ByteBuffer.allocate(fixMessageString.length());
   try {
      buffer.put(fixMessageString.getBytes(charsetEncoding));
   } catch (UnsupportedEncodingException e) {
      throw new ProtocolCodecException(e);
   }

if message contains Chinese characters, fixMessageString.length() will not equal to fixMessageString.getBytes(charsetEncoding).length. Because A Chinese character will use "three" Bytes in "UTF-8". But in String, it's length is still "1".

we let: byte[] src = fixMessageString.getBytes(charsetEncoding);
when a message contains "one" Chinese character,
if fixMessageString.length() = 190, then src.length = 192, buffer.capacity() = 256. So buffer.put(src) will not throw java.nio.BufferOverflowException;
if fixMessageString.length() = 255, then src.length = 257, buffer.capacity() = 256. At this time, buffer.put(src) will throw java.nio.BufferOverflowException;

solution:
   use "fixMessageString.getBytes(charsetEncoding).length" to allocate buffer space instead of "fixMessageString.length()".

    ByteBuffer buffer;
    try {
        byte[] src = fixMessageString.getBytes(charsetEncoding);
        buffer = ByteBuffer.allocate(src.length);
        buffer.put(src);
    } catch (UnsupportedEncodingException e) {
        throw new ProtocolCodecException(e);
    }

Activity

Hide
Jan Amoyo added a comment - 29/Apr/08 2:22 PM

One can also use the CharsetEncoder in java.nio.charset:

Charset charset = Charset.forName("UTF-8");
CharsetEncoder encoder = charset.newEncoder();

CharBuffer cb = CharBuffer.wrap("fixMessageString");
ByteBuffer buffer = encoder.encode(cb);

Show
Jan Amoyo added a comment - 29/Apr/08 2:22 PM One can also use the CharsetEncoder in java.nio.charset: Charset charset = Charset.forName("UTF-8"); CharsetEncoder encoder = charset.newEncoder(); CharBuffer cb = CharBuffer.wrap("fixMessageString"); ByteBuffer buffer = encoder.encode(cb);
Hide
Jay Walters added a comment - 03/Feb/09 10:22 PM

See QFJ-382 for the patches to resolve this issue.

Show
Jay Walters added a comment - 03/Feb/09 10:22 PM See QFJ-382 for the patches to resolve this issue.

People

  • Assignee:
    Unassigned
    Reporter:
    CaiQi
Vote (0)
Watch (0)

Dates

  • Created:
    27/Dec/07 9:05 AM
    Updated:
    03/Feb/09 10:22 PM