diff --git a/eth/rlp.nim b/eth/rlp.nim index 855a887..ecd00a4 100644 --- a/eth/rlp.nim +++ b/eth/rlp.nim @@ -107,7 +107,9 @@ proc payloadOffset(self: Rlp): int = if isSingleByte(): 0 else: 1 + lengthBytesCount() template readAheadCheck(numberOfBytes) = - if position + numberOfBytes >= bytes.len: eosError() + # important to add nothing to the left side of the equation as `numberOfBytes` + # can in theory be at max size of its type already + if numberOfBytes >= bytes.len - position: eosError() template nonCanonicalNumberError = raise newException(MalformedRlpError, "Small number encoded in a non-canonical way") @@ -138,7 +140,9 @@ proc payloadBytesCount(self: Rlp): int = if remainingBytes > 1 and self.bytes[self.position + 1] == 0: raise newException(MalformedRlpError, "Number encoded with a leading zero") - if lengthBytes > sizeof(result): + # check if the size is not bigger than the max that result can hold + if lengthBytes > sizeof(result) or + (lengthBytes == sizeof(result) and self.bytes[self.position + 1].int > 127): raise newException(UnsupportedRlpError, "Message too large to fit in memory") for i in 1 .. lengthBytes: diff --git a/tests/rlp/cases/invalidRLPTest.json b/tests/rlp/cases/invalidRLPTest.json index bed8b30..0b06f27 100644 --- a/tests/rlp/cases/invalidRLPTest.json +++ b/tests/rlp/cases/invalidRLPTest.json @@ -42,5 +42,46 @@ "bytesShouldBeSingleByte7F": { "in": "INVALID", "out": "817F" + }, + + "fakelonglist": { + "in": "INVALID", + "out": "ff7fffffffffffffffff" + }, + + "fakelonglist2": { + "in": "INVALID", + "out": "ff800000000000000000" + }, + + "fakelongblob": { + "in": "INVALID", + "out": "bf7fffffffffffffffff" + }, + + "fakelongblob2": { + "in": "INVALID", + "out": "bf800000000000000000" + }, + + "fakelongblobinlist": { + "in": "INVALID", + "out": "f2bf7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + }, + + "fakelongblobinlist2": { + "in": "INVALID", + "out": "f2bf80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + }, + + "fakelonglistinlist": { + "in": "INVALID", + "out": "f2ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + }, + + "fakelonglistinlist2": { + "in": "INVALID", + "out": "f2ff80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" } + } diff --git a/tests/rlp/test_json_suite.nim b/tests/rlp/test_json_suite.nim index 0f9e87c..c5d498d 100644 --- a/tests/rlp/test_json_suite.nim +++ b/tests/rlp/test_json_suite.nim @@ -1,8 +1,12 @@ import - os, strutils, + os, strutils, strformat, util/json_testing -for file in walkDirRec("tests/cases"): +template sourceDir: string = currentSourcePath.rsplit(DirSep, 1)[0] + +const casesDir = &"{sourceDir}{DirSep}cases{DirSep}" + +for file in walkDirRec(casesDir): if file.endsWith("json"): runTests(file) diff --git a/tests/rlp/util/json_testing.nim b/tests/rlp/util/json_testing.nim index dedd6a2..a751dda 100644 --- a/tests/rlp/util/json_testing.nim +++ b/tests/rlp/util/json_testing.nim @@ -48,7 +48,7 @@ proc runTests*(filename: string) = inspectOutput = rlp.inspect(1) discard rlp.getType while rlp.hasData: discard rlp.toNodes - except MalformedRlpError, ValueError: + except MalformedRlpError, UnsupportedRlpError, ValueError: success = true if not success: testStatus "FAILED"