def read_int(r: BufferReader) -> memoryview: if r.get() != 0x02: raise ValueError n = read_length(r) if n == 0: raise ValueError if r.peek() & 0x80: raise ValueError # negative integer if r.peek() == 0x00 and n > 1: r.get() n -= 1 if r.peek() & 0x80 == 0x00: raise ValueError # excessive zero-padding if r.peek() == 0x00: raise ValueError # excessive zero-padding return r.read_memoryview(n)
def decode_int(r: BufferReader) -> bytes: if r.get() != 0x02: raise ValueError n = decode_length(r) if n == 0: raise ValueError if r.peek() & 0x80: raise ValueError # negative integer if r.peek() == 0x00 and n > 1: r.get() n -= 1 if r.peek() & 0x80 == 0x00: raise ValueError # excessive zero-padding if r.peek() == 0x00: raise ValueError # excessive zero-padding return r.read(n)
def read_length(r: BufferReader) -> int: init = r.get() if init < 0x80: # short form encodes length in initial octet return init if init == 0x80 or init == 0xFF or r.peek() == 0x00: raise ValueError # indefinite length, RFU or not shortest possible # long form n = 0 for _ in range(init & 0x7F): n = n * 0x100 + r.get() if n < 128: raise ValueError # encoding is not the shortest possible return n