Check field_code and type_code when readFieldOrdinal() is called (#81)

Added verification that nth and type are valid when read from BinaryParser
This commit is contained in:
Nathan Nichols
2020-07-07 13:58:24 -05:00
parent 485ec4e924
commit 8ac03699aa
2 changed files with 35 additions and 8 deletions

View File

@@ -107,9 +107,24 @@ class BinaryParser {
* @return Field ordinal * @return Field ordinal
*/ */
readFieldOrdinal(): number { readFieldOrdinal(): number {
const tagByte = this.readUInt8(); let type = this.readUInt8();
const type = (tagByte & 0xf0) >>> 4 || this.readUInt8(); let nth = type & 15;
const nth = tagByte & 0x0f || this.readUInt8(); type >>= 4;
if (type === 0) {
type = this.readUInt8();
if (type === 0 || type < 16) {
throw new Error("Cannot read FieldOrdinal, type_code out of range");
}
}
if (nth === 0) {
nth = this.readUInt8();
if (nth === 0 || nth < 16) {
throw new Error("Cannot read FieldOrdinal, field_code out of range");
}
}
return (type << 16) | nth; return (type << 16) | nth;
} }

View File

@@ -50,7 +50,6 @@ function basicApiTests () {
expect(parser.readUInt32()).toEqual(0xFFFFFFFF) expect(parser.readUInt32()).toEqual(0xFFFFFFFF)
}) })
} }
basicApiTests()
function transactionParsingTests () { function transactionParsingTests () {
const transaction = { const transaction = {
@@ -184,7 +183,6 @@ function transactionParsingTests () {
expect(_.isPlainObject(jsonFromBinary)).toBe(true) expect(_.isPlainObject(jsonFromBinary)).toBe(true)
}) })
} }
transactionParsingTests()
function amountParsingTests () { function amountParsingTests () {
_.filter(fixtures.values_tests, { type: 'Amount' }).forEach((f, i) => { _.filter(fixtures.values_tests, { type: 'Amount' }).forEach((f, i) => {
@@ -206,7 +204,6 @@ function amountParsingTests () {
}) })
}) })
} }
amountParsingTests()
function fieldParsingTests () { function fieldParsingTests () {
fixtures.fields_tests.forEach((f, i) => { fixtures.fields_tests.forEach((f, i) => {
@@ -217,8 +214,20 @@ function fieldParsingTests () {
expect(field.type.name).toEqual(f.type_name) expect(field.type.name).toEqual(f.type_name)
}) })
}) })
test("Field throws when type code out of range", () => {
const parser = makeParser("0101");
expect(() => parser.readField()).toThrow(new Error("Cannot read FieldOrdinal, type_code out of range"));
})
test("Field throws when field code out of range", () => {
const parser = makeParser("1001");
expect(() => parser.readFieldOrdinal()).toThrowError(new Error("Cannot read FieldOrdinal, field_code out of range"))
})
test("Field throws when both type and field code out of range", () => {
const parser = makeParser("000101");
expect(() => parser.readFieldOrdinal()).toThrowError(new Error("Cannot read FieldOrdinal, type_code out of range"))
})
} }
fieldParsingTests()
function assertRecyclable (json, forField) { function assertRecyclable (json, forField) {
const Type = forField.associatedType const Type = forField.associatedType
@@ -366,9 +375,12 @@ function pathSetBinaryTests () {
) )
}) })
} }
pathSetBinaryTests()
describe('Binary Parser', function() { describe('Binary Parser', function() {
describe('pathSetBinaryTests', pathSetBinaryTests); describe('pathSetBinaryTests', pathSetBinaryTests);
describe('nestedObjectTests', nestedObjectTests); describe('nestedObjectTests', nestedObjectTests);
describe('fieldParsingTests', fieldParsingTests);
describe('amountParsingTests', amountParsingTests);
describe('transactionParsingTests', transactionParsingTests);
describe('basicApiTests', basicApiTests);
}); });