Fix the frame decoder for a TCP byte stream

Review the AI's codeEasy12 min

Your task

A telecom protocol sends length-prefixed frames over TCP. An AI's first parser assumed one Read returns one whole packet, but TCP is a byte stream: a read can return half a header or one and a half frames. The new decoder joins what arrives and cuts frames by their lengths.

An assistant wrote decode_frames(chunks, max_frame_len). It is in the editor. It has a bug. Find it and fix it.

Input and output:

  • chunks: the pieces the socket returned, in order. Where one chunk ends means nothing.
  • max_frame_len: the largest payload length the decoder accepts.
  • Each frame is a 4-character header, the payload length as digits with leading zeros such as 0005, then that many payload characters.
  • Return the complete payloads, in order, or a single error string.

Rules the tests check:

  • Join the chunks into one stream and read frames from the start.
  • While at least 4 characters remain, read the next header:
    • If it is not 4 digits from 0 to 9, return ["ERROR:bad_header"] and nothing else.
    • If its length is above max_frame_len, return ["ERROR:frame_too_large"] and nothing else. Decide this as soon as the header is read, before the payload has arrived.
    • If fewer than that many characters follow the header, stop: the rest has not arrived yet.
    • Otherwise take the payload and continue after it.
  • Return the payloads read. A length of 0 gives an empty payload.

Examples

decode_frames(chunks: list[str], max_frame_len: int) -> list[str]
Example 1
Inputdecode_frames(["00", "05hel", "lo0003abc"], 100)
Output["hello", "abc"]
Example 2
Inputdecode_frames(["0005hel"], 100)
Output[]
Example 3
Inputdecode_frames(["000"], 100)
Output[]