diff --git a/src/core/lib/TLVParser.mjs b/src/core/lib/TLVParser.mjs index cb8432c147..1afd052e06 100644 --- a/src/core/lib/TLVParser.mjs +++ b/src/core/lib/TLVParser.mjs @@ -33,20 +33,29 @@ export default class TLVParser { * @returns {number} */ getLength() { + let bytesInLength = this.bytesInLength; + let bigEndian = false; + if (this.basicEncodingRules) { - const bit = this.input[this.location]; - if (bit & 0x80) { - this.bytesInLength = bit & ~0x80; + const firstLengthByte = this.input[this.location]; + this.location++; + + if (firstLengthByte & 0x80) { + bytesInLength = firstLengthByte & ~0x80; + bigEndian = true; } else { - this.location++; - return bit & ~0x80; + return firstLengthByte & ~0x80; } } let length = 0; - for (let i = 0; i < this.bytesInLength; i++) { - length += this.input[this.location] * Math.pow(Math.pow(2, 8), i); + for (let i = 0; i < bytesInLength; i++) { + if (bigEndian) { + length = (length << 8) + this.input[this.location]; + } else { + length += this.input[this.location] * Math.pow(Math.pow(2, 8), i); + } this.location++; } diff --git a/tests/operations/tests/ParseTLV.mjs b/tests/operations/tests/ParseTLV.mjs index 5c99eee252..9033848d30 100644 --- a/tests/operations/tests/ParseTLV.mjs +++ b/tests/operations/tests/ParseTLV.mjs @@ -52,5 +52,46 @@ TestRegister.addTests([ "args": [1, 4, true] // length value is patently wrong, should be ignored by BER. } ] + }, + { + name: "Parse TLV: BER long-form length (two-byte length encoding)", + input: "\x01\x82\x01\x00" + "A".repeat(256) + "\x02\x03\x41\x42\x43", + expectedOutput: JSON.stringify([ + {"key": [1], "length": 256, "value": Array(256).fill(65)}, + {"key": [2], "length": 3, "value": [65, 66, 67]} + ], null, 4), + recipeConfig: [ + { + "op": "Parse TLV", + "args": [1, 1, true] + } + ] + }, + { + name: "Parse TLV: BER long-form length (one-byte length encoding)", + input: "\x01\x81\x80" + "B".repeat(128), + expectedOutput: JSON.stringify([ + {"key": [1], "length": 128, "value": Array(128).fill(66)} + ], null, 4), + recipeConfig: [ + { + "op": "Parse TLV", + "args": [1, 1, true] + } + ] + }, + { + name: "Parse TLV: BER multiple entries with mixed short and long-form lengths", + input: "\x01\x05\x48\x65\x6c\x6c\x6f\x02\x81\x05\x57\x6f\x72\x6c\x64", + expectedOutput: JSON.stringify([ + {"key": [1], "length": 5, "value": [72, 101, 108, 108, 111]}, + {"key": [2], "length": 5, "value": [87, 111, 114, 108, 100]} + ], null, 4), + recipeConfig: [ + { + "op": "Parse TLV", + "args": [1, 1, true] + } + ] } ]);