Chrome native messaging doesn't accept messages of certain sizes (Windows)
Asked Answered
Q

1

2

I'm developing a Chrome extension working with native messaging host. It works in most cases, but I have found a strange behavior when I send messages of certain sizes. It seems that message is dropped, when the size is between 2560 and 2815 bytes (A00 and AFF in hex). All subsequent messages are also not arriving, which suggests that the stream is corrupted for some reason.

Here is a stripped down Python native messaging app, which can be used to test it:

import sys
import struct

def output(message):
    encoded_message = message.encode('utf-8')

    # Write message size.
    sys.stdout.write(struct.pack('I', len(encoded_message)))
    # Write the message itself.
    sys.stdout.write(encoded_message)
    sys.stdout.flush()

if __name__ == "__main__":
    output('{"type": "%s"}' % ('x'*2820))
    output('{"type": "%s"}' % ('x'*2560))

I'm getting the first message and not the second one.

I have took a look at the code in Chrome repository. Function, which seems to be responsible for that functionality, doesn't have anything special:

void NativeMessageProcessHost::ProcessIncomingData(
    const char* data, int data_size) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);

  incoming_data_.append(data, data_size);

  while (true) {
    if (incoming_data_.size() < kMessageHeaderSize)
      return;

    size_t message_size =
        *reinterpret_cast<const uint32*>(incoming_data_.data());

    if (message_size > kMaximumMessageSize) {
      LOG(ERROR) << "Native Messaging host tried sending a message that is "
                 << message_size << " bytes long.";
      Close(kHostInputOuputError);
      return;
    }

    if (incoming_data_.size() < message_size + kMessageHeaderSize)
      return;

    content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
        base::Bind(&Client::PostMessageFromNativeProcess, weak_client_ui_,
            destination_port_,
            incoming_data_.substr(kMessageHeaderSize, message_size)));

    incoming_data_.erase(0, kMessageHeaderSize + message_size);
  }
}

Does anybody have any idea what may be happening here?

Update

I have experienced this problem on 64 bit versions of Windows 7 and Windows 8.1.

I tried Chrome 64-bit on Stable, Beta and Dev channels - versions 37, 38 and 39. I have also tried stable Chrome 32-bit

I use 32 bit version of Python 2.7.7 and PyInstaller 2.1 to create an executable for native messaging host.

Quasar answered 2/10, 2014 at 14:28 Comment(2)
Works fine for me (Linux). Which OS are you using? And your byte calculations are a bit off. In your question, you're mentioning the number of 'x's, while the output also contains other characters ({"type": ... }).Ezekiel
I use Windows 7 64 bit. My byte examples are approximate in a way that one message should be in a good range, and the second in a bad range. Thanks for checking that the problem doesn't appear in LinuxQuasar
E
2

Since you're using Windows, I suspect that Windows is adding carriage returns (\x0D) to newline characters (\x0A).

According to Python 2.x - Write binary output to stdout?, a way to prevent modification of the output stream on Windows is to use the following snippet before writing anything to stdout.

if sys.platform == "win32":
    import os, msvcrt
    msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
Ezekiel answered 3/10, 2014 at 8:57 Comment(1)
May not make a difference in some implementations, but in general you should make sure stdin is binary as well.Steatopygia

© 2022 - 2024 — McMap. All rights reserved.