Exercise 3 solution import struct HEADER = struct.Struct(" len(buf): raise ValueError(f"record at {pos} wants {n} bytes, {len(buf) - start} left") yield t, buf[start:start + n] pos = start + n def build(node): if node["kind"] == "file": body = pack_tlv(NAME, node["name"].encode()) + pack_tlv(SIZE, struct.pack(" MAX_DEPTH: raise ValueError("nested too deeply") nodes = [] for t, v in iter_tlv(buf): if t == FILE: node = {"kind": "file", "name": None, "size": None} for ct, cv in iter_tlv(v): if ct == NAME: node["name"] = cv.decode() elif ct == SIZE: (node["size"],) = struct.unpack("", e) inner = pack_tlv(NAME, b"x") + HEADER.pack(FILE, 500) + b"abc" bad = pack_tlv(FOLDER, inner) try: parse(bad) except ValueError as e: print("overrun ->", e) try: parse(blob[:-1]) except ValueError as e: print("cut ->", e) # 66 # root/ # a.txt (10 bytes) # docs/ # b.md (2048 bytes) # empty/ # True # deep -> nested too deeply # overrun -> record at 4 wants 500 bytes, 3 left # cut -> record at 0 wants 63 bytes, 62 left (Run as written; the output matched the comments.) Explanation: A folder's value is itself a run of records: its own name followed by its children. parse reads that value with the same iterator, so a child can never read past its parent, because the child sees only the parent's value bytes. That is why an inner length of 500 inside a 14-byte folder is caught as an overrun. The depth limit stops hostile input from nesting records until the program runs out of stack.