FA-27796 / HTTP ranges / Open access
A segment playlist resolves byte-range tags into per-segment Range values: carriage returns from CRLF playlists are trimmed before parsing · case 01
A segment playlist resolves byte-range tags into per-segment Range values: carriage returns from CRLF playlists are trimmed before parsing.
ROOT CAUSE
The playlist-byterange-crlf-lines decision uses out=[] pending=None prev=None for raw in x: line=raw if not line: continue if line.startswith('#EXT-X-BYTERANGE:'): n,at,o=line[17:].partition('@') if not n.isdigit() or (at and not o.isdigit()): return None pending=[int(n),int(o) if at else None] elif line.startswith('#'): continue else: if pending is None: out.append([line,None]) prev=None else: n,o=pending if o is None: if prev is None or prev[0]!=line: return None o=prev[1] if n==0: return None out.append([line,'bytes=%d-%d'%(o,o+n-1)]) prev=[line,o+n] pending=None return out.
VERIFIED REPAIR
Apply the bounded decision exactly: out=[] pending=None prev=None for raw in x: line=raw.strip() if not line: continue if line.startswith('#EXT-X-BYTERANGE:'): n,at,o=line[17:].partition('@') if not n.isdigit() or (at and not o.isdigit()): return None pending=[int(n),int(o) if at else None] elif line.startswith('#'): continue else: if pending is None: out.append([line,None]) prev=None else: n,o=pending if o is None: if prev is None or prev[0]!=line: return None o=prev[1] if n==0: return None out.append([line,'bytes=%d-%d'%(o,o+n-1)]) prev=[line,o+n] pending=None return out
Unsuccessful approach: The partial repair uses out=[] pending=None prev=None for raw in x: line=raw.rstrip('\n') if not line: continue if line.startswith('#EXT-X-BYTERANGE:'): n,at,o=line[17:].partition('@') if not n.isdigit() or (at and not o.isdigit()): return None pending=[int(n),int(o) if at else None] elif line.startswith('#'): continue else: if pending is None: out.append([line,None]) prev=None else: n,o=pending if o is None: if prev is None or prev[0]!=line: return None o=prev[1] if n==0: return None out.append([line,'bytes=%d-%d'%(o,o+n-1)]) prev=[line,o+n] pending=None return out, which still violates the stated contract.
Case contract
x is a list of playlist lines. Lines are trimmed; blank lines skipped; every other line starting with # is a tag or comment. #EXT-X-BYTERANGE:n[@o] (ASCII decimals) applies only to the next URI line. Without @o the range continues at the byte after the immediately previous segment, which must be a sub-range of the same URI string; otherwise null. A URI without a byte-range tag is a whole-resource segment [uri,null] and breaks any continuation chain. Zero-length sub-ranges and malformed tags return null. Return [uri,inclusive bytes=a-b or null] rows.
Why this case matters
Range responses combine representation identity, conditional requests, framing, and partial-object state.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
out=[]
pending=None
prev=None
for raw in x:
line=raw
if not line: continue
if line.startswith('#EXT-X-BYTERANGE:'):
n,at,o=line[17:].partition('@')
if not n.isdigit() or (at and not o.isdigit()): return None
pending=[int(n),int(o) if at else None]
elif line.startswith('#'):
continue
else:
if pending is None:
out.append([line,None])
prev=None
else:
n,o=pending
if o is None:
if prev is None or prev[0]!=line: return None
o=prev[1]
if n==0: return None
out.append([line,'bytes=%d-%d'%(o,o+n-1)])
prev=[line,o+n]
pending=None
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('crlf-lines fixture 0', json.loads(json.dumps(solve(['#EXTM3U','#EXTINF:1,','#EXT-X-BYTERANGE:100@0','a.ts','#EXTINF:1,','#EXT-X-BYTERANGE:50','a.ts','#EXTINF:1,','#EXT-X-BYTERANGE:25','a.ts']))), json.loads(json.dumps([['a.ts','bytes=0-99'],['a.ts','bytes=100-149'],['a.ts','bytes=150-174']])))
check('crlf-lines fixture 1', json.loads(json.dumps(solve(['#EXTM3U','# generated by tool','#EXT-X-BYTERANGE:10@5','b.ts']))), json.loads(json.dumps([['b.ts','bytes=5-14']])))
check('crlf-lines fixture 2', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:10@0','a.ts','#EXT-X-BYTERANGE:10','b.ts']))), json.loads(json.dumps(None)))
check('crlf-lines fixture 3', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:10@0','a.ts?v=1','#EXT-X-BYTERANGE:10','a.ts?v=2']))), json.loads(json.dumps(None)))
check('crlf-lines fixture 4', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:10','a.ts']))), json.loads(json.dumps(None)))
check('crlf-lines fixture 5', json.loads(json.dumps(solve(['full.ts','#EXT-X-BYTERANGE:10','a.ts']))), json.loads(json.dumps(None)))
check('crlf-lines fixture 6', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:10@0','a.ts','a.ts','#EXT-X-BYTERANGE:10','a.ts']))), json.loads(json.dumps(None)))
check('crlf-lines fixture 7', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:10@0','a.ts','b.ts']))), json.loads(json.dumps([['a.ts','bytes=0-9'],['b.ts',None]])))
check('crlf-lines fixture 8', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:0@0','a.ts']))), json.loads(json.dumps(None)))
check('crlf-lines fixture 9', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:5@0','a.ts','#EXT-X-BYTERANGE:0','a.ts']))), json.loads(json.dumps(None)))
check('crlf-lines fixture 10', json.loads(json.dumps(solve(['#EXTM3U\r\n','#EXT-X-BYTERANGE:10@0\r\n','a.ts\r\n','#EXT-X-BYTERANGE:4\r\n','a.ts\r\n']))), json.loads(json.dumps([['a.ts','bytes=0-9'],['a.ts','bytes=10-13']])))
check('crlf-lines fixture 11', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:1x@0','a.ts']))), json.loads(json.dumps(None)))
check('crlf-lines fixture 12', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:10@','a.ts']))), json.loads(json.dumps(None)))
check('crlf-lines fixture 13', json.loads(json.dumps(solve(['','#EXT-X-BYTERANGE:3@7',' ','c.ts']))), json.loads(json.dumps([['c.ts','bytes=7-9']])))
check('crlf-lines fixture 14', json.loads(json.dumps(solve(["#EXT-X-BYTERANGE:%d@0"%N,'a.ts',"#EXT-X-BYTERANGE:%d"%N,'a.ts']))), json.loads(json.dumps([['a.ts',"bytes=0-%d"%(N-1)],['a.ts',"bytes=%d-%d"%(N,2*N-1)]])))
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| crlf-lines fixture 0 | [['a.ts', 'bytes=0-99'], ['a.ts', 'bytes=100-149'], ['a.ts', 'bytes=150-174']] | [['a.ts', 'bytes=0-99'], ['a.ts', 'bytes=100-149'], ['a.ts', 'bytes=150-174']] | Passed |
| crlf-lines fixture 1 | [['b.ts', 'bytes=5-14']] | [['b.ts', 'bytes=5-14']] | Passed |
| crlf-lines fixture 2 | None | None | Passed |
| crlf-lines fixture 3 | None | None | Passed |
| crlf-lines fixture 4 | None | None | Passed |
| crlf-lines fixture 5 | None | None | Passed |
| crlf-lines fixture 6 | None | None | Passed |
| crlf-lines fixture 7 | [['a.ts', 'bytes=0-9'], ['b.ts', None]] | [['a.ts', 'bytes=0-9'], ['b.ts', None]] | Passed |
| crlf-lines fixture 8 | None | None | Passed |
| crlf-lines fixture 9 | None | None | Passed |
| crlf-lines fixture 10 | None | [['a.ts', 'bytes=0-9'], ['a.ts', 'bytes=10-13']] | Failed |
| crlf-lines fixture 11 | None | None | Passed |
| crlf-lines fixture 12 | None | None | Passed |
| crlf-lines fixture 13 | [[' ', 'bytes=7-9'], ['c.ts', None]] | [['c.ts', 'bytes=7-9']] | Failed |
| crlf-lines fixture 14 | [['a.ts', 'bytes=0-0'], ['a.ts', 'bytes=1-1']] | [['a.ts', 'bytes=0-0'], ['a.ts', 'bytes=1-1']] | Passed |
SHA-256 / 249d245a48d6e60d61b8107acf4087bb725920643ca536846d9adacdcabbb86d
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
out=[]
pending=None
prev=None
for raw in x:
line=raw.rstrip('\n')
if not line: continue
if line.startswith('#EXT-X-BYTERANGE:'):
n,at,o=line[17:].partition('@')
if not n.isdigit() or (at and not o.isdigit()): return None
pending=[int(n),int(o) if at else None]
elif line.startswith('#'):
continue
else:
if pending is None:
out.append([line,None])
prev=None
else:
n,o=pending
if o is None:
if prev is None or prev[0]!=line: return None
o=prev[1]
if n==0: return None
out.append([line,'bytes=%d-%d'%(o,o+n-1)])
prev=[line,o+n]
pending=None
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('crlf-lines fixture 0', json.loads(json.dumps(solve(['#EXTM3U','#EXTINF:1,','#EXT-X-BYTERANGE:100@0','a.ts','#EXTINF:1,','#EXT-X-BYTERANGE:50','a.ts','#EXTINF:1,','#EXT-X-BYTERANGE:25','a.ts']))), json.loads(json.dumps([['a.ts','bytes=0-99'],['a.ts','bytes=100-149'],['a.ts','bytes=150-174']])))
check('crlf-lines fixture 1', json.loads(json.dumps(solve(['#EXTM3U','# generated by tool','#EXT-X-BYTERANGE:10@5','b.ts']))), json.loads(json.dumps([['b.ts','bytes=5-14']])))
check('crlf-lines fixture 2', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:10@0','a.ts','#EXT-X-BYTERANGE:10','b.ts']))), json.loads(json.dumps(None)))
check('crlf-lines fixture 3', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:10@0','a.ts?v=1','#EXT-X-BYTERANGE:10','a.ts?v=2']))), json.loads(json.dumps(None)))
check('crlf-lines fixture 4', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:10','a.ts']))), json.loads(json.dumps(None)))
check('crlf-lines fixture 5', json.loads(json.dumps(solve(['full.ts','#EXT-X-BYTERANGE:10','a.ts']))), json.loads(json.dumps(None)))
check('crlf-lines fixture 6', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:10@0','a.ts','a.ts','#EXT-X-BYTERANGE:10','a.ts']))), json.loads(json.dumps(None)))
check('crlf-lines fixture 7', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:10@0','a.ts','b.ts']))), json.loads(json.dumps([['a.ts','bytes=0-9'],['b.ts',None]])))
check('crlf-lines fixture 8', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:0@0','a.ts']))), json.loads(json.dumps(None)))
check('crlf-lines fixture 9', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:5@0','a.ts','#EXT-X-BYTERANGE:0','a.ts']))), json.loads(json.dumps(None)))
check('crlf-lines fixture 10', json.loads(json.dumps(solve(['#EXTM3U\r\n','#EXT-X-BYTERANGE:10@0\r\n','a.ts\r\n','#EXT-X-BYTERANGE:4\r\n','a.ts\r\n']))), json.loads(json.dumps([['a.ts','bytes=0-9'],['a.ts','bytes=10-13']])))
check('crlf-lines fixture 11', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:1x@0','a.ts']))), json.loads(json.dumps(None)))
check('crlf-lines fixture 12', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:10@','a.ts']))), json.loads(json.dumps(None)))
check('crlf-lines fixture 13', json.loads(json.dumps(solve(['','#EXT-X-BYTERANGE:3@7',' ','c.ts']))), json.loads(json.dumps([['c.ts','bytes=7-9']])))
check('crlf-lines fixture 14', json.loads(json.dumps(solve(["#EXT-X-BYTERANGE:%d@0"%N,'a.ts',"#EXT-X-BYTERANGE:%d"%N,'a.ts']))), json.loads(json.dumps([['a.ts',"bytes=0-%d"%(N-1)],['a.ts',"bytes=%d-%d"%(N,2*N-1)]])))
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| crlf-lines fixture 0 | [['a.ts', 'bytes=0-99'], ['a.ts', 'bytes=100-149'], ['a.ts', 'bytes=150-174']] | [['a.ts', 'bytes=0-99'], ['a.ts', 'bytes=100-149'], ['a.ts', 'bytes=150-174']] | Passed |
| crlf-lines fixture 1 | [['b.ts', 'bytes=5-14']] | [['b.ts', 'bytes=5-14']] | Passed |
| crlf-lines fixture 2 | None | None | Passed |
| crlf-lines fixture 3 | None | None | Passed |
| crlf-lines fixture 4 | None | None | Passed |
| crlf-lines fixture 5 | None | None | Passed |
| crlf-lines fixture 6 | None | None | Passed |
| crlf-lines fixture 7 | [['a.ts', 'bytes=0-9'], ['b.ts', None]] | [['a.ts', 'bytes=0-9'], ['b.ts', None]] | Passed |
| crlf-lines fixture 8 | None | None | Passed |
| crlf-lines fixture 9 | None | None | Passed |
| crlf-lines fixture 10 | None | [['a.ts', 'bytes=0-9'], ['a.ts', 'bytes=10-13']] | Failed |
| crlf-lines fixture 11 | None | None | Passed |
| crlf-lines fixture 12 | None | None | Passed |
| crlf-lines fixture 13 | [[' ', 'bytes=7-9'], ['c.ts', None]] | [['c.ts', 'bytes=7-9']] | Failed |
| crlf-lines fixture 14 | [['a.ts', 'bytes=0-0'], ['a.ts', 'bytes=1-1']] | [['a.ts', 'bytes=0-0'], ['a.ts', 'bytes=1-1']] | Passed |
SHA-256 / d8848239d7e55657927420020f57cf0796f65849f8e41cf365bb3bc08db4682f
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
out=[]
pending=None
prev=None
for raw in x:
line=raw.strip()
if not line: continue
if line.startswith('#EXT-X-BYTERANGE:'):
n,at,o=line[17:].partition('@')
if not n.isdigit() or (at and not o.isdigit()): return None
pending=[int(n),int(o) if at else None]
elif line.startswith('#'):
continue
else:
if pending is None:
out.append([line,None])
prev=None
else:
n,o=pending
if o is None:
if prev is None or prev[0]!=line: return None
o=prev[1]
if n==0: return None
out.append([line,'bytes=%d-%d'%(o,o+n-1)])
prev=[line,o+n]
pending=None
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('crlf-lines fixture 0', json.loads(json.dumps(solve(['#EXTM3U','#EXTINF:1,','#EXT-X-BYTERANGE:100@0','a.ts','#EXTINF:1,','#EXT-X-BYTERANGE:50','a.ts','#EXTINF:1,','#EXT-X-BYTERANGE:25','a.ts']))), json.loads(json.dumps([['a.ts','bytes=0-99'],['a.ts','bytes=100-149'],['a.ts','bytes=150-174']])))
check('crlf-lines fixture 1', json.loads(json.dumps(solve(['#EXTM3U','# generated by tool','#EXT-X-BYTERANGE:10@5','b.ts']))), json.loads(json.dumps([['b.ts','bytes=5-14']])))
check('crlf-lines fixture 2', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:10@0','a.ts','#EXT-X-BYTERANGE:10','b.ts']))), json.loads(json.dumps(None)))
check('crlf-lines fixture 3', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:10@0','a.ts?v=1','#EXT-X-BYTERANGE:10','a.ts?v=2']))), json.loads(json.dumps(None)))
check('crlf-lines fixture 4', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:10','a.ts']))), json.loads(json.dumps(None)))
check('crlf-lines fixture 5', json.loads(json.dumps(solve(['full.ts','#EXT-X-BYTERANGE:10','a.ts']))), json.loads(json.dumps(None)))
check('crlf-lines fixture 6', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:10@0','a.ts','a.ts','#EXT-X-BYTERANGE:10','a.ts']))), json.loads(json.dumps(None)))
check('crlf-lines fixture 7', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:10@0','a.ts','b.ts']))), json.loads(json.dumps([['a.ts','bytes=0-9'],['b.ts',None]])))
check('crlf-lines fixture 8', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:0@0','a.ts']))), json.loads(json.dumps(None)))
check('crlf-lines fixture 9', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:5@0','a.ts','#EXT-X-BYTERANGE:0','a.ts']))), json.loads(json.dumps(None)))
check('crlf-lines fixture 10', json.loads(json.dumps(solve(['#EXTM3U\r\n','#EXT-X-BYTERANGE:10@0\r\n','a.ts\r\n','#EXT-X-BYTERANGE:4\r\n','a.ts\r\n']))), json.loads(json.dumps([['a.ts','bytes=0-9'],['a.ts','bytes=10-13']])))
check('crlf-lines fixture 11', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:1x@0','a.ts']))), json.loads(json.dumps(None)))
check('crlf-lines fixture 12', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:10@','a.ts']))), json.loads(json.dumps(None)))
check('crlf-lines fixture 13', json.loads(json.dumps(solve(['','#EXT-X-BYTERANGE:3@7',' ','c.ts']))), json.loads(json.dumps([['c.ts','bytes=7-9']])))
check('crlf-lines fixture 14', json.loads(json.dumps(solve(["#EXT-X-BYTERANGE:%d@0"%N,'a.ts',"#EXT-X-BYTERANGE:%d"%N,'a.ts']))), json.loads(json.dumps([['a.ts',"bytes=0-%d"%(N-1)],['a.ts',"bytes=%d-%d"%(N,2*N-1)]])))
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| crlf-lines fixture 0 | [['a.ts', 'bytes=0-99'], ['a.ts', 'bytes=100-149'], ['a.ts', 'bytes=150-174']] | [['a.ts', 'bytes=0-99'], ['a.ts', 'bytes=100-149'], ['a.ts', 'bytes=150-174']] | Passed |
| crlf-lines fixture 1 | [['b.ts', 'bytes=5-14']] | [['b.ts', 'bytes=5-14']] | Passed |
| crlf-lines fixture 2 | None | None | Passed |
| crlf-lines fixture 3 | None | None | Passed |
| crlf-lines fixture 4 | None | None | Passed |
| crlf-lines fixture 5 | None | None | Passed |
| crlf-lines fixture 6 | None | None | Passed |
| crlf-lines fixture 7 | [['a.ts', 'bytes=0-9'], ['b.ts', None]] | [['a.ts', 'bytes=0-9'], ['b.ts', None]] | Passed |
| crlf-lines fixture 8 | None | None | Passed |
| crlf-lines fixture 9 | None | None | Passed |
| crlf-lines fixture 10 | [['a.ts', 'bytes=0-9'], ['a.ts', 'bytes=10-13']] | [['a.ts', 'bytes=0-9'], ['a.ts', 'bytes=10-13']] | Passed |
| crlf-lines fixture 11 | None | None | Passed |
| crlf-lines fixture 12 | None | None | Passed |
| crlf-lines fixture 13 | [['c.ts', 'bytes=7-9']] | [['c.ts', 'bytes=7-9']] | Passed |
| crlf-lines fixture 14 | [['a.ts', 'bytes=0-0'], ['a.ts', 'bytes=1-1']] | [['a.ts', 'bytes=0-0'], ['a.ts', 'bytes=1-1']] | Passed |
SHA-256 / 94ce5a85b88cb0419461ff6f9801c9db1fe9b74b225dd3fcacd28756ad4bff72
Verification & scope
Deterministic simplified range service, with stipulated local policies and already parsed trusted inputs; not a complete HTTP implementation. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:41:28.263291+00:00.
Case digest / e174e61e9616912d1b75aae548639c8785430e0d31373b73a3e33cfc21464fb8