-
-
Save axic/c7a3cbeafad0ca867b04b784c1a757a8 to your computer and use it in GitHub Desktop.
Loop based (extensible) EOF1 validator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
FORMAT = 0xEF | |
MAGIC = 0xFF # To be defined | |
VERSION = 0x01 | |
S_TERMINATOR = 0x00 | |
S_CODE = 0x01 | |
S_DATA = 0x02 | |
def validate_code(code: bytes) -> bool: | |
# Old-style contracts are still allowed | |
if len(code) == 0: | |
return True | |
if code[0] != FORMAT: | |
return True | |
if len(code) < 2: | |
return True | |
if code[0] == FORMAT and code[1] != MAGIC: | |
return True | |
# Format and magic is validated | |
if len(code) < 3: | |
return False | |
if code[2] != VERSION: | |
return False | |
# No sections | |
if len(code) < 4: | |
return False | |
# Process section headers | |
total_content_size = 0 | |
pos = 3 | |
while True: | |
if (pos + 1) > len(code): | |
return False | |
section_id = code[pos] | |
pos += 1 | |
if section_id == S_TERMINATOR: | |
break | |
if section_id != S_CODE and section_id != S_DATA: | |
return False | |
if (pos + 2) > len(code): | |
return False | |
section_size = (code[pos] << 8) | code[pos + 1] | |
pos += 2 | |
if section_size == 0: | |
return False | |
total_content_size += section_size | |
# First section is not the code section | |
if code[3] != S_CODE: | |
return False | |
return len(code) == (pos + total_content_size) | |
# Legacy contracts | |
assert validate_code(b'') == True | |
assert validate_code(b'\x00') == True | |
assert validate_code(b'\xef') == True | |
# Any value outside the magic | |
for magic in range(254): | |
assert validate_code(['\xef', magic]) == True | |
# EOF1 contracts | |
assert validate_code(b'\xef\xff') == False # Only magic | |
assert validate_code(b'\xef\xff\x01') == False # Only version | |
assert validate_code(b'\xef\xff\x00') == False # Wrong version | |
assert validate_code(b'\xef\xff\x01\x00') == False # Only terminator | |
assert validate_code(b'\xef\xff\x01\x00\x0ff') == False # Trailing bytes | |
assert validate_code(b'\xef\xff\x01\x01') == False # Truncated section header | |
assert validate_code(b'\xef\xff\x01\x02') == False # Truncated section header | |
assert validate_code(b'\xef\xff\x01\x03') == False # Invalid section id | |
assert validate_code(b'\xef\xff\x01\x01\x00') == False # Truncated section size | |
assert validate_code(b'\xef\xff\x01\x01\x00\x00') == False # Empty section size | |
assert validate_code(b'\xef\xff\x01\x01\x00\x01') == False # No terminator after section | |
assert validate_code(b'\xef\xff\x01\x01\x00\x01\x00') == False # Missing section contents | |
assert validate_code(b'\xef\xff\x01\x01\x00\x01\x00\xfe') == True # Valid format with 1-byte of code | |
assert validate_code(b'\xef\xff\x01\x02\x00\x01\x00\xaa') == False # Only data section | |
assert validate_code(b'\xef\xff\x01\x01\x00\x01\x02\x00\x01\x00\xfe\xaa') == True # Code and data section | |
# TODO: add multiple code sections, multiple dat asections, multiple code+data sections |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment