"""Two-sided contract checker for RFC 2425-style content-line folding.""" REQUIREMENTS = [ {"id": "R1", "text": "unfolding the output (SP/TAB-marked continuations) reproduces every " "original line exactly"}, {"id": "R2", "text": "no physical line exceeds 75 octets"}, {"id": "R3", "text": "no physical line splits a multi-byte UTF-8 character"}, {"id": "R4", "text": "the file uses CRLF between physical lines throughout"}, ] def _cont_byte(b: int) -> bool: return (b & 0xC0) == 0x80 def _safe_cut(b: bytes, limit: int) -> int: n = min(limit, len(b)) while 0 < n < len(b) and _cont_byte(b[n]): n -= 1 return n def check(spec: dict, path: str) -> list[tuple[str, bool, str]]: ids = [r["id"] for r in REQUIREMENTS] try: raw = open(path, "rb").read() except OSError as e: return [(i, False, f"could not open: {e}") for i in ids] if not raw: return [(i, False, "empty file") for i in ids] crlf_ok = b"\r\n" in raw and b"\n" not in raw.replace(b"\r\n", b"") physical = raw.split(b"\r\n") if b"\r\n" in raw else raw.split(b"\n") if physical and physical[-1] == b"": physical = physical[:-1] len_ok = all(len(p) <= 75 for p in physical) groups, cur = [], [] for p in physical: if p[:1] in (b" ", b"\t"): cur.append(p) else: if cur: groups.append(cur) cur = [p] if cur: groups.append(cur) logical = [g[0] + b"".join(p[1:] for p in g[1:]) for g in groups] split_ok = True for g in groups: for i, p in enumerate(g): body = p[1:] if i > 0 else p try: body.decode("utf-8", errors="strict") except UnicodeDecodeError: split_ok = False try: recon = [b.decode("utf-8") for b in logical] except UnicodeDecodeError: recon = None round_trip_ok = recon == spec["lines"] return [ ("R1", round_trip_ok, "reconstructs exactly" if round_trip_ok else f"got {recon!r}, wanted {spec['lines']!r}"), ("R2", len_ok, "all physical lines <=75 octets" if len_ok else f"a physical line exceeded 75 octets: {[len(p) for p in physical if len(p) > 75]}"), ("R3", split_ok, "no line splits a character" if split_ok else "a physical line is not valid UTF-8 on its own: a fold split a character"), ("R4", crlf_ok, "CRLF throughout" if crlf_ok else "not CRLF-terminated throughout"), ] def _fold_line(line: str, marker: bytes = b" ") -> list[bytes]: b = line.encode("utf-8") if len(b) <= 75: return [b] parts = [] n = _safe_cut(b, 75) parts.append(b[:n]) rest = b[n:] while rest: n2 = _safe_cut(rest, 74) or min(74, len(rest)) parts.append(rest[:n2]) rest = rest[n2:] return parts def build_reference(spec: dict, out_path: str) -> None: physical = [] for line in spec["lines"]: parts = _fold_line(line) physical.append(parts[0]) physical.extend(b" " + p for p in parts[1:]) with open(out_path, "wb") as fh: fh.write(b"\r\n".join(physical) + b"\r\n") def _variant_tab(spec: dict, out_path: str) -> None: physical = [] for line in spec["lines"]: parts = _fold_line(line) physical.append(parts[0]) physical.extend(b"\t" + p for p in parts[1:]) with open(out_path, "wb") as fh: fh.write(b"\r\n".join(physical) + b"\r\n") def _variant_conservative(spec: dict, out_path: str) -> None: physical = [] for line in spec["lines"]: b = line.encode("utf-8") if len(b) <= 60: physical.append(b) continue parts, rest, first = [], b, True while rest: n = _safe_cut(rest, 60 if first else 58) or min(58, len(rest)) parts.append(rest[:n]) rest = rest[n:] first = False physical.append(parts[0]) physical.extend(b" " + p for p in parts[1:]) with open(out_path, "wb") as fh: fh.write(b"\r\n".join(physical) + b"\r\n") VARIANTS = [("tab_continuation", _variant_tab), ("conservative_width", _variant_conservative)] def _sp_bytesplit(path: str) -> str: p = path + ".s1" raw = open(path, "rb").read() logical = [] for line in raw.split(b"\r\n"): if not line: continue if line[:1] in (b" ", b"\t"): logical[-1] += line[1:] else: logical.append(line) physical = [] for buf in logical: i = 0 first = True while i < len(buf): n = 75 if first else 74 chunk = buf[i:i + n] physical.append(chunk if first else b" " + chunk) i += n first = False if not buf: physical.append(b"") open(p, "wb").write(b"\r\n".join(physical) + b"\r\n") return p def _sp_no_fold(path: str) -> str: p = path + ".s2" raw = open(path, "rb").read() unfolded = raw.replace(b"\r\n ", b"").replace(b"\r\n\t", b"") open(p, "wb").write(unfolded) return p def _sp_lf(path: str) -> str: p = path + ".s3" raw = open(path, "rb").read().replace(b"\r\n", b"\n") open(p, "wb").write(raw) return p def _sp_drop_byte(path: str) -> str: p = path + ".s4" raw = open(path, "rb").read() idx = raw.find(b"\r\n ") if idx == -1: idx = raw.find(b"\r\n\t") if idx == -1: return path cut = idx + 4 raw = raw[:cut] + raw[cut + 1:] open(p, "wb").write(raw) return p SPOILERS = [ ("R3", "byte_offset_split", _sp_bytesplit), ("R2", "never_folded", _sp_no_fold), ("R4", "bare_lf", _sp_lf), ("R1", "dropped_byte", _sp_drop_byte), ]