FAILURE MAP
← Case archive

FA-78176 / Subtitle cue timing / Open access

WebVTT cue timing line parsing: field range check · case 01

A timestamp with 60 minutes or seconds is accepted and rolls over silently.

Verified by executionVariant 1 · 9 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The range check allows the value 60.

VERIFIED REPAIR

Reject minute or second fields above 59.

Unsuccessful approach: Checking only the seconds field still admits a minute field of 60.

Case contract

Parse "START --> END [settings...]" (whitespace separated). Timestamps are [hh:]mm:ss.ttt with hours of two or more digits, minutes and seconds exactly two digits below 60, and exactly three fraction digits after a period. END must be after START. Return [start_ms,end_ms,settings joined by single spaces] or None.

Why this case matters

Subtitle timing defects shift, hide or overlap captions that viewers depend on for comprehension and accessibility.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import re
N = 1
observations = []
def solve(line):
    parts=line.split()
    if len(parts)<3 or parts[1]!='-->':
        return None
    def ts(x):
        m=re.fullmatch(r'(?:(\d{2,}):)?(\d{2}):(\d{2})\.(\d{3})',x)
        if not m:
            return None
        h,mi,se,f=m.groups()
        if int(mi)>60 or int(se)>60:
            return None
        return int(h or 0)*3600000+int(mi)*60000+int(se)*1000+int(f)
    a=ts(parts[0]); b=ts(parts[2])
    if a is None or b is None or b<=a:
        return None
    return [a,b,' '.join(parts[3:])]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: field range check', ['60:59.500 --> 100:00:00.000'], None), ('regression variant: field range check', ['01:60:00.000 --> 100:00:00.000 align:start'], None), ('partial repair probe: field range check', ['01:59:09.999 --> 01:60:09.500'], None), ('partial repair variant: field range check', ['00:09.000 --> 100:60:59.999'], None), ('boundary control', ['00:01.000 --> 00:02.000'], [1000, 2000, '']), ('boundary control', ['00:59.999 --> 01:00.000 line:0 size:50%'], [59999, 60000, 'line:0 size:50%']), ('normal control', ['00:01.000 --> 00:01.000'], None), ('normal control', ['59:09.5 --> 00:02.000 align:start'], None), ('normal control', ['01:01:60,500 -> 01:01:60,500'], None)], [('regression: field range check', ['00:60:00.000 --> 100:00:00.000 align:start'], None), ('regression variant: field range check', ['00:59:59.000 --> 100:01:60.000'], None), ('partial repair probe: field range check', ['01:60:00.000 --> 100:00:00.000 align:start'], None), ('partial repair variant: field range check', ['00:09.000 --> 100:60:59.999'], None), ('boundary control', ['00:01.000 --> 00:01.000'], None), ('boundary control', ['00:01.000 --> 00:02.000'], [1000, 2000, '']), ('normal control', ['100:60:00.5 --> 01:60:09.000 line:0 position:10%'], None), ('normal control', ['60:09.5 -> 60:09.5'], None), ('normal control', ['01:00:09,500 --> 00:00.001'], None)], [('regression: field range check', ['01:60:60.999 --> 100:59:00.000 align:start'], None), ('regression variant: field range check', ['00:09.000 --> 100:60:59.999'], None), ('partial repair probe: field range check', ['00:60:09.500 --> 100:00:00.000'], None), ('partial repair variant: field range check', ['00:59:09.500 --> 60:59.000 size:50% align:end'], None), ('boundary control', ['100:00:00.000 --> 100:00:01.000 align:start'], [360000000, 360001000, 'align:start']), ('boundary control', ['00:01.000 --> 00:01.000'], None), ('normal control', ['01:09,500 --> 01:09,500'], None), ('normal control', ['01:5:09.000 --> 00:00.001'], None), ('normal control', ['5:60.500 --> 5:60.500 align:start'], None)], [('regression: field range check', ['01:59:09.999 --> 01:60:09.500'], None), ('regression variant: field range check', ['00:60:09.500 --> 100:00:00.000'], None), ('partial repair probe: field range check', ['00:59:09.500 --> 60:59.000 size:50% align:end'], None), ('partial repair variant: field range check', ['60:59.500 --> 100:00:00.000'], None), ('boundary control', ['00:59.999 --> 01:00.000 line:0 size:50%'], [59999, 60000, 'line:0 size:50%']), ('boundary control', ['100:00:00.000 --> 100:00:01.000 align:start'], [360000000, 360001000, 'align:start']), ('normal control', ['60:60.999 --> 00:00.001'], None), ('normal control', ['01:59:59,500 --> 01:59:59,500 size:50% align:end'], None), ('normal control', ['59:60.5 --> 100:00:00.000 line:0 position:10%'], None)], [('regression: field range check', ['00:59:60.999 --> 01:60:59.000'], None), ('regression variant: field range check', ['00:01:60.000 --> 100:00:00.000 line:0 position:10%'], None), ('partial repair probe: field range check', ['00:59:09.500 --> 60:59.000 size:50% align:end'], None), ('partial repair variant: field range check', ['60:59.500 --> 100:00:00.000'], None), ('boundary control', ['00:01.000 --> 00:02.000'], [1000, 2000, '']), ('boundary control', ['00:59.999 --> 01:00.000 line:0 size:50%'], [59999, 60000, 'line:0 size:50%']), ('normal control', ['01:5:60.500 --> 00:00.001 size:50% align:end'], None), ('normal control', ['100:00:59.000 --> 00:02.000 size:50% align:end'], None), ('normal control', ['100:59:09.000 --> 100:59:09.000'], None)]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
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 fixtureActualExpectedOutcome
regression: field range check[3659500, 360000000, '']NoneFailed
regression variant: field range check[7200000, 360000000, 'align:start']NoneFailed
partial repair probe: field range check[7149999, 7209500, '']NoneFailed
partial repair variant: field range check[9000, 363659999, '']NoneFailed
boundary control[1000, 2000, ''][1000, 2000, '']Passed
boundary control[59999, 60000, 'line:0 size:50%'][59999, 60000, 'line:0 size:50%']Passed
normal controlNoneNonePassed
normal controlNoneNonePassed
normal controlNoneNonePassed

SHA-256 / 1cb2efa7ac6e1739185d3672b8a4d825429963b4f299d17834cb0fea59a6866d

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import re
N = 1
observations = []
def solve(line):
    parts=line.split()
    if len(parts)<3 or parts[1]!='-->':
        return None
    def ts(x):
        m=re.fullmatch(r'(?:(\d{2,}):)?(\d{2}):(\d{2})\.(\d{3})',x)
        if not m:
            return None
        h,mi,se,f=m.groups()
        if int(se)>59:
            return None
        return int(h or 0)*3600000+int(mi)*60000+int(se)*1000+int(f)
    a=ts(parts[0]); b=ts(parts[2])
    if a is None or b is None or b<=a:
        return None
    return [a,b,' '.join(parts[3:])]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: field range check', ['60:59.500 --> 100:00:00.000'], None), ('regression variant: field range check', ['01:60:00.000 --> 100:00:00.000 align:start'], None), ('partial repair probe: field range check', ['01:59:09.999 --> 01:60:09.500'], None), ('partial repair variant: field range check', ['00:09.000 --> 100:60:59.999'], None), ('boundary control', ['00:01.000 --> 00:02.000'], [1000, 2000, '']), ('boundary control', ['00:59.999 --> 01:00.000 line:0 size:50%'], [59999, 60000, 'line:0 size:50%']), ('normal control', ['00:01.000 --> 00:01.000'], None), ('normal control', ['59:09.5 --> 00:02.000 align:start'], None), ('normal control', ['01:01:60,500 -> 01:01:60,500'], None)], [('regression: field range check', ['00:60:00.000 --> 100:00:00.000 align:start'], None), ('regression variant: field range check', ['00:59:59.000 --> 100:01:60.000'], None), ('partial repair probe: field range check', ['01:60:00.000 --> 100:00:00.000 align:start'], None), ('partial repair variant: field range check', ['00:09.000 --> 100:60:59.999'], None), ('boundary control', ['00:01.000 --> 00:01.000'], None), ('boundary control', ['00:01.000 --> 00:02.000'], [1000, 2000, '']), ('normal control', ['100:60:00.5 --> 01:60:09.000 line:0 position:10%'], None), ('normal control', ['60:09.5 -> 60:09.5'], None), ('normal control', ['01:00:09,500 --> 00:00.001'], None)], [('regression: field range check', ['01:60:60.999 --> 100:59:00.000 align:start'], None), ('regression variant: field range check', ['00:09.000 --> 100:60:59.999'], None), ('partial repair probe: field range check', ['00:60:09.500 --> 100:00:00.000'], None), ('partial repair variant: field range check', ['00:59:09.500 --> 60:59.000 size:50% align:end'], None), ('boundary control', ['100:00:00.000 --> 100:00:01.000 align:start'], [360000000, 360001000, 'align:start']), ('boundary control', ['00:01.000 --> 00:01.000'], None), ('normal control', ['01:09,500 --> 01:09,500'], None), ('normal control', ['01:5:09.000 --> 00:00.001'], None), ('normal control', ['5:60.500 --> 5:60.500 align:start'], None)], [('regression: field range check', ['01:59:09.999 --> 01:60:09.500'], None), ('regression variant: field range check', ['00:60:09.500 --> 100:00:00.000'], None), ('partial repair probe: field range check', ['00:59:09.500 --> 60:59.000 size:50% align:end'], None), ('partial repair variant: field range check', ['60:59.500 --> 100:00:00.000'], None), ('boundary control', ['00:59.999 --> 01:00.000 line:0 size:50%'], [59999, 60000, 'line:0 size:50%']), ('boundary control', ['100:00:00.000 --> 100:00:01.000 align:start'], [360000000, 360001000, 'align:start']), ('normal control', ['60:60.999 --> 00:00.001'], None), ('normal control', ['01:59:59,500 --> 01:59:59,500 size:50% align:end'], None), ('normal control', ['59:60.5 --> 100:00:00.000 line:0 position:10%'], None)], [('regression: field range check', ['00:59:60.999 --> 01:60:59.000'], None), ('regression variant: field range check', ['00:01:60.000 --> 100:00:00.000 line:0 position:10%'], None), ('partial repair probe: field range check', ['00:59:09.500 --> 60:59.000 size:50% align:end'], None), ('partial repair variant: field range check', ['60:59.500 --> 100:00:00.000'], None), ('boundary control', ['00:01.000 --> 00:02.000'], [1000, 2000, '']), ('boundary control', ['00:59.999 --> 01:00.000 line:0 size:50%'], [59999, 60000, 'line:0 size:50%']), ('normal control', ['01:5:60.500 --> 00:00.001 size:50% align:end'], None), ('normal control', ['100:00:59.000 --> 00:02.000 size:50% align:end'], None), ('normal control', ['100:59:09.000 --> 100:59:09.000'], None)]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
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 fixtureActualExpectedOutcome
regression: field range check[3659500, 360000000, '']NoneFailed
regression variant: field range check[7200000, 360000000, 'align:start']NoneFailed
partial repair probe: field range check[7149999, 7209500, '']NoneFailed
partial repair variant: field range check[9000, 363659999, '']NoneFailed
boundary control[1000, 2000, ''][1000, 2000, '']Passed
boundary control[59999, 60000, 'line:0 size:50%'][59999, 60000, 'line:0 size:50%']Passed
normal controlNoneNonePassed
normal controlNoneNonePassed
normal controlNoneNonePassed

SHA-256 / ad8fa998483508808d372ade625f89a1675311f26d46d5c1be0ce6beba6ceb17

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
import re
N = 1
observations = []
def solve(line):
    parts=line.split()
    if len(parts)<3 or parts[1]!='-->':
        return None
    def ts(x):
        m=re.fullmatch(r'(?:(\d{2,}):)?(\d{2}):(\d{2})\.(\d{3})',x)
        if not m:
            return None
        h,mi,se,f=m.groups()
        if int(mi)>59 or int(se)>59:
            return None
        return int(h or 0)*3600000+int(mi)*60000+int(se)*1000+int(f)
    a=ts(parts[0]); b=ts(parts[2])
    if a is None or b is None or b<=a:
        return None
    return [a,b,' '.join(parts[3:])]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: field range check', ['60:59.500 --> 100:00:00.000'], None), ('regression variant: field range check', ['01:60:00.000 --> 100:00:00.000 align:start'], None), ('partial repair probe: field range check', ['01:59:09.999 --> 01:60:09.500'], None), ('partial repair variant: field range check', ['00:09.000 --> 100:60:59.999'], None), ('boundary control', ['00:01.000 --> 00:02.000'], [1000, 2000, '']), ('boundary control', ['00:59.999 --> 01:00.000 line:0 size:50%'], [59999, 60000, 'line:0 size:50%']), ('normal control', ['00:01.000 --> 00:01.000'], None), ('normal control', ['59:09.5 --> 00:02.000 align:start'], None), ('normal control', ['01:01:60,500 -> 01:01:60,500'], None)], [('regression: field range check', ['00:60:00.000 --> 100:00:00.000 align:start'], None), ('regression variant: field range check', ['00:59:59.000 --> 100:01:60.000'], None), ('partial repair probe: field range check', ['01:60:00.000 --> 100:00:00.000 align:start'], None), ('partial repair variant: field range check', ['00:09.000 --> 100:60:59.999'], None), ('boundary control', ['00:01.000 --> 00:01.000'], None), ('boundary control', ['00:01.000 --> 00:02.000'], [1000, 2000, '']), ('normal control', ['100:60:00.5 --> 01:60:09.000 line:0 position:10%'], None), ('normal control', ['60:09.5 -> 60:09.5'], None), ('normal control', ['01:00:09,500 --> 00:00.001'], None)], [('regression: field range check', ['01:60:60.999 --> 100:59:00.000 align:start'], None), ('regression variant: field range check', ['00:09.000 --> 100:60:59.999'], None), ('partial repair probe: field range check', ['00:60:09.500 --> 100:00:00.000'], None), ('partial repair variant: field range check', ['00:59:09.500 --> 60:59.000 size:50% align:end'], None), ('boundary control', ['100:00:00.000 --> 100:00:01.000 align:start'], [360000000, 360001000, 'align:start']), ('boundary control', ['00:01.000 --> 00:01.000'], None), ('normal control', ['01:09,500 --> 01:09,500'], None), ('normal control', ['01:5:09.000 --> 00:00.001'], None), ('normal control', ['5:60.500 --> 5:60.500 align:start'], None)], [('regression: field range check', ['01:59:09.999 --> 01:60:09.500'], None), ('regression variant: field range check', ['00:60:09.500 --> 100:00:00.000'], None), ('partial repair probe: field range check', ['00:59:09.500 --> 60:59.000 size:50% align:end'], None), ('partial repair variant: field range check', ['60:59.500 --> 100:00:00.000'], None), ('boundary control', ['00:59.999 --> 01:00.000 line:0 size:50%'], [59999, 60000, 'line:0 size:50%']), ('boundary control', ['100:00:00.000 --> 100:00:01.000 align:start'], [360000000, 360001000, 'align:start']), ('normal control', ['60:60.999 --> 00:00.001'], None), ('normal control', ['01:59:59,500 --> 01:59:59,500 size:50% align:end'], None), ('normal control', ['59:60.5 --> 100:00:00.000 line:0 position:10%'], None)], [('regression: field range check', ['00:59:60.999 --> 01:60:59.000'], None), ('regression variant: field range check', ['00:01:60.000 --> 100:00:00.000 line:0 position:10%'], None), ('partial repair probe: field range check', ['00:59:09.500 --> 60:59.000 size:50% align:end'], None), ('partial repair variant: field range check', ['60:59.500 --> 100:00:00.000'], None), ('boundary control', ['00:01.000 --> 00:02.000'], [1000, 2000, '']), ('boundary control', ['00:59.999 --> 01:00.000 line:0 size:50%'], [59999, 60000, 'line:0 size:50%']), ('normal control', ['01:5:60.500 --> 00:00.001 size:50% align:end'], None), ('normal control', ['100:00:59.000 --> 00:02.000 size:50% align:end'], None), ('normal control', ['100:59:09.000 --> 100:59:09.000'], None)]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
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 fixtureActualExpectedOutcome
regression: field range checkNoneNonePassed
regression variant: field range checkNoneNonePassed
partial repair probe: field range checkNoneNonePassed
partial repair variant: field range checkNoneNonePassed
boundary control[1000, 2000, ''][1000, 2000, '']Passed
boundary control[59999, 60000, 'line:0 size:50%'][59999, 60000, 'line:0 size:50%']Passed
normal controlNoneNonePassed
normal controlNoneNonePassed
normal controlNoneNonePassed

SHA-256 / 60ae4f04076432ef587efea5701436b13a138d550eca6e199187278950401e71

Verification & scope

A deterministic bounded teaching model with a stipulated toy contract; it does not claim conformance to any subtitle standard. 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:49:32.721383+00:00.

Case digest / 3ce402276e93fe9a7a347e795e97bde24d397dd464ef3c6e1118f571138b4fc0