FA-27801 / HTTP ranges / Open access
A segment playlist resolves byte-range tags into per-segment Range values: comment and tag lines are never treated as segment URIs · case 01
A segment playlist resolves byte-range tags into per-segment Range values: comment and tag lines are never treated as segment URIs.
ROOT CAUSE
The playlist-byterange-non-uri-tags decision uses 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('#EXT'): 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.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('#') and ':' in line: 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.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('#EXT'):
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('non-uri-tags 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('non-uri-tags 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('non-uri-tags 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('non-uri-tags 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('non-uri-tags fixture 4', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:10','a.ts']))), json.loads(json.dumps(None)))
check('non-uri-tags fixture 5', json.loads(json.dumps(solve(['full.ts','#EXT-X-BYTERANGE:10','a.ts']))), json.loads(json.dumps(None)))
check('non-uri-tags 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('non-uri-tags 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('non-uri-tags fixture 8', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:0@0','a.ts']))), json.loads(json.dumps(None)))
check('non-uri-tags 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('non-uri-tags 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('non-uri-tags fixture 11', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:1x@0','a.ts']))), json.loads(json.dumps(None)))
check('non-uri-tags fixture 12', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:10@','a.ts']))), json.loads(json.dumps(None)))
check('non-uri-tags fixture 13', json.loads(json.dumps(solve(['','#EXT-X-BYTERANGE:3@7',' ','c.ts']))), json.loads(json.dumps([['c.ts','bytes=7-9']])))
check('non-uri-tags 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 |
|---|---|---|---|
| non-uri-tags 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 |
| non-uri-tags fixture 1 | [['# generated by tool', None], ['b.ts', 'bytes=5-14']] | [['b.ts', 'bytes=5-14']] | Failed |
| non-uri-tags fixture 2 | None | None | Passed |
| non-uri-tags fixture 3 | None | None | Passed |
| non-uri-tags fixture 4 | None | None | Passed |
| non-uri-tags fixture 5 | None | None | Passed |
| non-uri-tags fixture 6 | None | None | Passed |
| non-uri-tags fixture 7 | [['a.ts', 'bytes=0-9'], ['b.ts', None]] | [['a.ts', 'bytes=0-9'], ['b.ts', None]] | Passed |
| non-uri-tags fixture 8 | None | None | Passed |
| non-uri-tags fixture 9 | None | None | Passed |
| non-uri-tags fixture 10 | [['a.ts', 'bytes=0-9'], ['a.ts', 'bytes=10-13']] | [['a.ts', 'bytes=0-9'], ['a.ts', 'bytes=10-13']] | Passed |
| non-uri-tags fixture 11 | None | None | Passed |
| non-uri-tags fixture 12 | None | None | Passed |
| non-uri-tags fixture 13 | [['c.ts', 'bytes=7-9']] | [['c.ts', 'bytes=7-9']] | Passed |
| non-uri-tags 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 / 23287e9609f7c1dbd445260be35bc888fd633e1f47cc25023241e0e1bc4390e0
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.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('#') and ':' in line:
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('non-uri-tags 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('non-uri-tags 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('non-uri-tags 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('non-uri-tags 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('non-uri-tags fixture 4', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:10','a.ts']))), json.loads(json.dumps(None)))
check('non-uri-tags fixture 5', json.loads(json.dumps(solve(['full.ts','#EXT-X-BYTERANGE:10','a.ts']))), json.loads(json.dumps(None)))
check('non-uri-tags 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('non-uri-tags 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('non-uri-tags fixture 8', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:0@0','a.ts']))), json.loads(json.dumps(None)))
check('non-uri-tags 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('non-uri-tags 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('non-uri-tags fixture 11', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:1x@0','a.ts']))), json.loads(json.dumps(None)))
check('non-uri-tags fixture 12', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:10@','a.ts']))), json.loads(json.dumps(None)))
check('non-uri-tags fixture 13', json.loads(json.dumps(solve(['','#EXT-X-BYTERANGE:3@7',' ','c.ts']))), json.loads(json.dumps([['c.ts','bytes=7-9']])))
check('non-uri-tags 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 |
|---|---|---|---|
| non-uri-tags fixture 0 | [['#EXTM3U', None], ['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']] | Failed |
| non-uri-tags fixture 1 | [['#EXTM3U', None], ['# generated by tool', None], ['b.ts', 'bytes=5-14']] | [['b.ts', 'bytes=5-14']] | Failed |
| non-uri-tags fixture 2 | None | None | Passed |
| non-uri-tags fixture 3 | None | None | Passed |
| non-uri-tags fixture 4 | None | None | Passed |
| non-uri-tags fixture 5 | None | None | Passed |
| non-uri-tags fixture 6 | None | None | Passed |
| non-uri-tags fixture 7 | [['a.ts', 'bytes=0-9'], ['b.ts', None]] | [['a.ts', 'bytes=0-9'], ['b.ts', None]] | Passed |
| non-uri-tags fixture 8 | None | None | Passed |
| non-uri-tags fixture 9 | None | None | Passed |
| non-uri-tags fixture 10 | [['#EXTM3U', None], ['a.ts', 'bytes=0-9'], ['a.ts', 'bytes=10-13']] | [['a.ts', 'bytes=0-9'], ['a.ts', 'bytes=10-13']] | Failed |
| non-uri-tags fixture 11 | None | None | Passed |
| non-uri-tags fixture 12 | None | None | Passed |
| non-uri-tags fixture 13 | [['c.ts', 'bytes=7-9']] | [['c.ts', 'bytes=7-9']] | Passed |
| non-uri-tags 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 / c87934d16b6fcc9af21ef682f0ce32d874c5cf89306f47d8ffcc6f5b782453f3
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('non-uri-tags 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('non-uri-tags 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('non-uri-tags 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('non-uri-tags 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('non-uri-tags fixture 4', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:10','a.ts']))), json.loads(json.dumps(None)))
check('non-uri-tags fixture 5', json.loads(json.dumps(solve(['full.ts','#EXT-X-BYTERANGE:10','a.ts']))), json.loads(json.dumps(None)))
check('non-uri-tags 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('non-uri-tags 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('non-uri-tags fixture 8', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:0@0','a.ts']))), json.loads(json.dumps(None)))
check('non-uri-tags 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('non-uri-tags 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('non-uri-tags fixture 11', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:1x@0','a.ts']))), json.loads(json.dumps(None)))
check('non-uri-tags fixture 12', json.loads(json.dumps(solve(['#EXT-X-BYTERANGE:10@','a.ts']))), json.loads(json.dumps(None)))
check('non-uri-tags fixture 13', json.loads(json.dumps(solve(['','#EXT-X-BYTERANGE:3@7',' ','c.ts']))), json.loads(json.dumps([['c.ts','bytes=7-9']])))
check('non-uri-tags 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 |
|---|---|---|---|
| non-uri-tags 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 |
| non-uri-tags fixture 1 | [['b.ts', 'bytes=5-14']] | [['b.ts', 'bytes=5-14']] | Passed |
| non-uri-tags fixture 2 | None | None | Passed |
| non-uri-tags fixture 3 | None | None | Passed |
| non-uri-tags fixture 4 | None | None | Passed |
| non-uri-tags fixture 5 | None | None | Passed |
| non-uri-tags fixture 6 | None | None | Passed |
| non-uri-tags fixture 7 | [['a.ts', 'bytes=0-9'], ['b.ts', None]] | [['a.ts', 'bytes=0-9'], ['b.ts', None]] | Passed |
| non-uri-tags fixture 8 | None | None | Passed |
| non-uri-tags fixture 9 | None | None | Passed |
| non-uri-tags fixture 10 | [['a.ts', 'bytes=0-9'], ['a.ts', 'bytes=10-13']] | [['a.ts', 'bytes=0-9'], ['a.ts', 'bytes=10-13']] | Passed |
| non-uri-tags fixture 11 | None | None | Passed |
| non-uri-tags fixture 12 | None | None | Passed |
| non-uri-tags fixture 13 | [['c.ts', 'bytes=7-9']] | [['c.ts', 'bytes=7-9']] | Passed |
| non-uri-tags 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 / 8339c7ee6737ea123712d298d7817ea8659429fa1badcb714fa8769e6e1df1cb
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.300274+00:00.
Case digest / 368cc22783a7eaa4d5c000c9fdc0a29c9a4371690b7eb4877951fa5789282d9a