hildjj / node-cbor

Encode and decode CBOR documents, with both easy mode, streaming mode, and SAX-style evented mode.
MIT License
362 stars 74 forks source link

Crazy Xerox-Like number flipping in CBOR-Decoder #78

Closed felixletkemann closed 6 years ago

felixletkemann commented 6 years ago

Hey there! I am using tinycbor (c lib) as CBOR encoder, CoAPthon to transmit it and this library to decode it. Unfortunately, I get some very weird number flipping. When I transmit [ 10, 10, 1111 ], all the data is transmitted correctly. When sending [ 10, 10, 1211 ], I will get [ 10, 10, 1277 ] instead! I can not explain how this can happen. I can not be any kind of overflow, since [ 10, 10, 1311 ] is transmitted correctly. And when transmitting [ 10, 10, 1234 ], I also get [ 10, 10, 1277 ]. When I inspect the traffic using wireshark, it tells me, that the problem has to do with node-cbor. Here is a quick lookup-table for some values:

Sent Received Correct
[ 10, 10, 111 ] [ 10, 10, 111 ] yes
[ 10, 10, 1111 ] [ 10, 10, 1111 ] yes
[ 10, 10, 1211 ] [ 10, 10, 1277 ] no
[ 10, 10, 1151 ] [ 10, 10, 1151 ] yes
[ 10, 10, 1152 ] [ 10, 10, 1277 ] no
[ 10, 10, 1200 ] [ 10, 10, 1277 ] no
[ 10, 10, 1279 ] [ 10, 10, 1277 ] no
[ 10, 10, 1280 ] [ 10, 10, 1280 ] yes
[ 10, 10, 1020 ] [ 10, 10, 1021 ] no
[ 10, 10, 1021 ] [ 10, 10, 1021 ] yes, probably by accident
[ 10, 10, 1022 ] [ 10, 10, 1021 ] no
[ 10, 10, 1023 ] [ 10, 10, 1021 ] no
[ 10, 10, 1024 ] [ 10, 10, 1024 ] yes
[ 10, 10, 1025 ] [ 10, 10, 1025 ] yes
[ 10, 10, 1026 ] [ 10, 10, 1026 ] yes
[ 10, 10, 1027 ] [ 10, 10, 1027 ] yes
[ 10, 10, 505 ] [ 10, 10, 509 ] no
[ 10, 10, 506 ] [ 10, 10, 509 ] no
[ 10, 10, 507 ] [ 10, 10, 509 ] no
[ 10, 10, 508 ] [ 10, 10, 509 ] no
[ 10, 10, 509 ] [ 10, 10, 509 ] yes, by accident
[ 10, 10, 510 ] [ 10, 10, 509 ] no
[ 10, 10, 511 ] [ 10, 10, 509 ] no
[ 10, 10, 512 ] [ 10, 10, 512 ] yes
[ 10, 10, 513 ] [ 10, 10, 513 ] yes
[ 10, 10, 514 ] [ 10, 10, 514 ] yes
[ 10, 10, 515 ] [ 10, 10, 515 ] yes
[ 10, 10, 516 ] [ 10, 10, 516 ] yes
[ 10, 10, 517 ] [ 10, 10, 517 ] yes

One strange thing is, that all numbers between 1151 and 1280 are mapped to 1277, while 1151 and 1280 are transmitted correctly. Also, numbers a little smaller than 1151 and a little bigger than 1280 work fine. This in funny, because 1152 (the first "wrong number") is the sum of 1024 and 128, while 1280 (the first number working again) is the sum of 1024 and 256. To me, it looks like some certain ranges of numbers are causing these problems. You will find the same strange pattern around 2048, 4096, 8192 and so on. Its always the same: Numbers smaller than 2048 are causing trouble, numbers above are working fine. We find these strange patterns at all numbers that are the power of two - but not only at these! I hope my description helps you to find the cause :)

Yours Sincerely, Felix

felixletkemann commented 6 years ago

I found out something more about this strange behaviour: The buffer that is given as an argument to utils.parseCBORint in cbor/lib/decorder.js seems to contain the wrong value already. When the error occurs, the buffer always contains (hex) FD. For example:

grafik

"fd" is not there when the error does not occur. Example:

grafik

The wrong buffer seems to be created in *_parse() in decorder.js in the line: const buf = yield numbytes

Yours Sincerely, Felix

felixletkemann commented 6 years ago

I just found out, that this is most likely not a problem of node-cbor but of some other part of my application. I just noticed, that the "fd" already appears in the buffer I am passing to the decodeAllSync function.

hildjj commented 6 years ago

Please close this when you're absolutely sure it's not a node-cbor issue.

felixletkemann commented 6 years ago

I am absolutely sure. I have finally solved the issue and the problem was part of my application :)