I'm currently writing a Java program that communicates with a Chrome extension. I need to implement the Chrome native messaging protocol in order to communicate. The Google Chrome docs say:
... each message is serialized using JSON, UTF-8 encoded and is preceded with 32-bit message length in native byte order. (Source)
I tried to implement this in Java, but I have problems when my messages have a certain length, even though my implementation should be correct. Here is my current implementation, based on earlier SO-answers & questions(here for example):
// read the message size from Chrome. This part works correctly.
public static int getInt(char[] bytes) {
return (bytes[3]<<24) & 0xff000000|
(bytes[2]<<16) & 0x00ff0000|
(bytes[1]<< 8) & 0x0000ff00|
(bytes[0]<< 0) & 0x000000ff;
}
// transform the length into the 32-bit message length.
// This part works for small numbers, but does not work for length 2269 for example.
public static String getBytes(int length) {
return String.format("%c%c%c%c",
(char) ( length & 0xFF),
(char) ((length>>8) & 0xFF),
(char) ((length>>16) & 0xFF),
(char) ((length>>24) & 0xFF));
}
It seems the problem lies in the way java implements chars. I'd expect normal chars, like in C. In practice, it seems Java sometimes transforms these chars into unicode-chars (or at least, that's my suspicion so far). This is reflected in the following output (piped to xxd to show the actual bytes) from the java-program for length 2269:
0000000: c39d 0800 00 .....
The expected output however (with python):
import struct
struct.pack('I', 2269)
# outputs in interactive mode: '\xdd\x08\x00\x00'
What exactly is happening here? Why does Java convert my "0xDD" to "0xC39D" and how can I get my getBytes
function to represent the expected input for Chrome Native Messaging? Using another language is not an option.