'Exception 'illegal buffer' thrown in protobufjs
I am using protobufjs to manage my data over an API. It works perfectly most of the time but in one instance of a message I get an 'illegal buffer' exception. This is thrown by some internal code in the library. I am pasting here the Chrome debugger visual while stopped at a breakpoint se to the throw statement. Chromer debugger output
As you can see, Chrome tells me that the buffer is indeed an Uint8Array (of 755 bytes). Why the if statement resolved into false and cause the throw statement to be executed? Both "buffer instanceof Uint8Array" and "Array.isArray(buffer)" are true.
UPDATE
I wrote some code (eseentailly copied it from protobufjs and simplified it):
function test() {
var data = new Uint8Array([10, 9, 18, 7, 99, 111, 110, 110, 101, 99, 116, 16, 1]);
testProtobuf(data);
}
function Reader(buffer) {
this.buf = buffer;
this.pos = 0;
this.len = buffer.length;
}
var create_array = function (buffer) {
console.log(buffer);
if (buffer instanceof Uint8Array || Array.isArray(buffer))
return new Reader(buffer);
throw Error("illegal buffer");
}
function testProtobuf (data) {
try {
create_array(data);
}
catch (e) { console.log('Exception')};
}
When I call test(), which calls testProtobuf, which in turn calls create_array no exception is thrown. I also call testProtobuf from my onmessage method in the real code. In this case, an exception is still thrown. As you can see, I log the buffer on the console. Both logs are identical (I made sure the test data was the same).
Here is the Chrome console: Console output in Chrome
Solution 1:[1]
I found a solution for this problem here:
Sample.deserializeBinary(Array.from(buffer));
And there is an example from my typescript code:
const arrayBuffer = await res.arrayBuffer();
const array = new Uint8Array(arrayBuffer);
const response: Uint8Array = (Array.from(array) as unknown) as Uint8Array;
rpcImplCallback(null, response);
Solution 2:[2]
You need to massage the response a little bit before it's ready to be tested/decoded ..
const lResponse = await res.arrayBuffer();
const lResponseData = ProtoModel.decode(new Uint8Array(lResponse));
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Andre Thompson |