FA-28651 / HTTP redirects / Open access
Expand redirect templates with context-specific escaping and missing-variable policy: capture zero based · case 01
Expand redirect templates with context-specific escaping and missing-variable policy: the capture zero based branch emits an incorrect decision.
ROOT CAUSE
The capture-zero-based decision uses 'captures[index-1] if captures and 0<=index<=len(captures) else None'; this violates the stipulated controller policy.
VERIFIED REPAIR
At this decision use 'captures[index] if 0<=index<len(captures) else None', preserving the other controller outputs.
Unsuccessful approach: The partial repair uses 'captures[0] if captures else None' and still fails an explicit boundary or control.
Case contract
Expand redirect templates with context-specific escaping and missing-variable policy. The explicit fixture inputs and outputs define a bounded offline policy; request identity must accompany the decision.
Why this case matters
Models a redirect controller decision before following a target or exposing a redirect result.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
from urllib.parse import urlsplit, unquote, quote
import posixpath
import re
N = 1
observations = []
def solve(request, template, value, captures, index, query_value, literal):
return {'request': request, 'decision': [quote(value,safe=''), template.replace('{id}',value), captures[index-1] if captures and 0<=index<=len(captures) else None, index < 0 or index >= len(captures), quote(query_value,safe=''), literal, bool(re.search(r'\{[^{}]+\}',template.replace('{id}',value))), captures[index] == '' if 0<=index<len(captures) else False, len(value.encode('utf-8')), template.count('{id}')]}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('fixture 1', solve('/requests/' + str(N) + '/0', '/item/{id}', 'a/b', ['zero', 'one'], 1, 'a&b', '{id}'), {'request': '/requests/' + str(N) + '/0', 'decision': ['a%2Fb', '/item/a/b', 'one', False, 'a%26b', '{id}', False, False, 3, 1]})
check('fixture 2', solve('/requests/' + str(N) + '/1', '/{id}/{id}', 'x y', ['only'], 0, 'a+b', 'plain'), {'request': '/requests/' + str(N) + '/1', 'decision': ['x%20y', '/x y/x y', 'only', False, 'a%2Bb', 'plain', False, False, 3, 2]})
check('fixture 3', solve('/requests/' + str(N) + '/2', '/fixed', 'z', [], 0, '', '{missing}'), {'request': '/requests/' + str(N) + '/2', 'decision': ['z', '/fixed', None, True, '', '{missing}', False, False, 1, 0]})
check('fixture 4', solve('/requests/' + str(N) + '/3', '/{id}', '%2F', ['a', 'b', 'c'], 2, 'x=y', '{id}'), {'request': '/requests/' + str(N) + '/3', 'decision': ['%252F', '/%2F', 'c', False, 'x%3Dy', '{id}', False, False, 3, 1]})
check('fixture 5', solve('/requests/' + str(N) + '/4', '/{id}', 'café', ['a'], 2, 'a b', '{{id}}'), {'request': '/requests/' + str(N) + '/4', 'decision': ['caf%C3%A9', '/café', None, True, 'a%20b', '{{id}}', False, False, 5, 1]})
check('fixture 6', solve('/requests/' + str(N) + '/5', '/{id}', '', [''], 0, '#frag', ''), {'request': '/requests/' + str(N) + '/5', 'decision': ['', '/', '', False, '%23frag', '', False, True, 0, 1]})
check('fixture 7', solve('/requests/' + str(N) + '/6', '/{other}/{id}', '/a//b', ['x'], 0, 'a/b', 'literal'), {'request': '/requests/' + str(N) + '/6', 'decision': ['%2Fa%2F%2Fb', '/{other}//a//b', 'x', False, 'a%2Fb', 'literal', True, False, 5, 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 |
|---|---|---|---|
| fixture 1 | {'decision': ['a%2Fb', '/item/a/b', 'zero', False, 'a%26b', '{id}', False, False, 3, 1], 'request': '/requests/1/0'} | {'decision': ['a%2Fb', '/item/a/b', 'one', False, 'a%26b', '{id}', False, False, 3, 1], 'request': '/requests/1/0'} | Failed |
| fixture 2 | {'decision': ['x%20y', '/x y/x y', 'only', False, 'a%2Bb', 'plain', False, False, 3, 2], 'request': '/requests/1/1'} | {'decision': ['x%20y', '/x y/x y', 'only', False, 'a%2Bb', 'plain', False, False, 3, 2], 'request': '/requests/1/1'} | Passed |
| fixture 3 | {'decision': ['z', '/fixed', None, True, '', '{missing}', False, False, 1, 0], 'request': '/requests/1/2'} | {'decision': ['z', '/fixed', None, True, '', '{missing}', False, False, 1, 0], 'request': '/requests/1/2'} | Passed |
| fixture 4 | {'decision': ['%252F', '/%2F', 'b', False, 'x%3Dy', '{id}', False, False, 3, 1], 'request': '/requests/1/3'} | {'decision': ['%252F', '/%2F', 'c', False, 'x%3Dy', '{id}', False, False, 3, 1], 'request': '/requests/1/3'} | Failed |
| fixture 5 | {'decision': ['caf%C3%A9', '/café', None, True, 'a%20b', '{{id}}', False, False, 5, 1], 'request': '/requests/1/4'} | {'decision': ['caf%C3%A9', '/café', None, True, 'a%20b', '{{id}}', False, False, 5, 1], 'request': '/requests/1/4'} | Passed |
| fixture 6 | {'decision': ['', '/', '', False, '%23frag', '', False, True, 0, 1], 'request': '/requests/1/5'} | {'decision': ['', '/', '', False, '%23frag', '', False, True, 0, 1], 'request': '/requests/1/5'} | Passed |
| fixture 7 | {'decision': ['%2Fa%2F%2Fb', '/{other}//a//b', 'x', False, 'a%2Fb', 'literal', True, False, 5, 1], 'request': '/requests/1/6'} | {'decision': ['%2Fa%2F%2Fb', '/{other}//a//b', 'x', False, 'a%2Fb', 'literal', True, False, 5, 1], 'request': '/requests/1/6'} | Passed |
SHA-256 / 0ad64910eb39bf9abed502dfae4cbf54674d8ff078ab3fc27bf5bc4339add086
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
from urllib.parse import urlsplit, unquote, quote
import posixpath
import re
N = 1
observations = []
def solve(request, template, value, captures, index, query_value, literal):
return {'request': request, 'decision': [quote(value,safe=''), template.replace('{id}',value), captures[0] if captures else None, index < 0 or index >= len(captures), quote(query_value,safe=''), literal, bool(re.search(r'\{[^{}]+\}',template.replace('{id}',value))), captures[index] == '' if 0<=index<len(captures) else False, len(value.encode('utf-8')), template.count('{id}')]}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('fixture 1', solve('/requests/' + str(N) + '/0', '/item/{id}', 'a/b', ['zero', 'one'], 1, 'a&b', '{id}'), {'request': '/requests/' + str(N) + '/0', 'decision': ['a%2Fb', '/item/a/b', 'one', False, 'a%26b', '{id}', False, False, 3, 1]})
check('fixture 2', solve('/requests/' + str(N) + '/1', '/{id}/{id}', 'x y', ['only'], 0, 'a+b', 'plain'), {'request': '/requests/' + str(N) + '/1', 'decision': ['x%20y', '/x y/x y', 'only', False, 'a%2Bb', 'plain', False, False, 3, 2]})
check('fixture 3', solve('/requests/' + str(N) + '/2', '/fixed', 'z', [], 0, '', '{missing}'), {'request': '/requests/' + str(N) + '/2', 'decision': ['z', '/fixed', None, True, '', '{missing}', False, False, 1, 0]})
check('fixture 4', solve('/requests/' + str(N) + '/3', '/{id}', '%2F', ['a', 'b', 'c'], 2, 'x=y', '{id}'), {'request': '/requests/' + str(N) + '/3', 'decision': ['%252F', '/%2F', 'c', False, 'x%3Dy', '{id}', False, False, 3, 1]})
check('fixture 5', solve('/requests/' + str(N) + '/4', '/{id}', 'café', ['a'], 2, 'a b', '{{id}}'), {'request': '/requests/' + str(N) + '/4', 'decision': ['caf%C3%A9', '/café', None, True, 'a%20b', '{{id}}', False, False, 5, 1]})
check('fixture 6', solve('/requests/' + str(N) + '/5', '/{id}', '', [''], 0, '#frag', ''), {'request': '/requests/' + str(N) + '/5', 'decision': ['', '/', '', False, '%23frag', '', False, True, 0, 1]})
check('fixture 7', solve('/requests/' + str(N) + '/6', '/{other}/{id}', '/a//b', ['x'], 0, 'a/b', 'literal'), {'request': '/requests/' + str(N) + '/6', 'decision': ['%2Fa%2F%2Fb', '/{other}//a//b', 'x', False, 'a%2Fb', 'literal', True, False, 5, 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 |
|---|---|---|---|
| fixture 1 | {'decision': ['a%2Fb', '/item/a/b', 'zero', False, 'a%26b', '{id}', False, False, 3, 1], 'request': '/requests/1/0'} | {'decision': ['a%2Fb', '/item/a/b', 'one', False, 'a%26b', '{id}', False, False, 3, 1], 'request': '/requests/1/0'} | Failed |
| fixture 2 | {'decision': ['x%20y', '/x y/x y', 'only', False, 'a%2Bb', 'plain', False, False, 3, 2], 'request': '/requests/1/1'} | {'decision': ['x%20y', '/x y/x y', 'only', False, 'a%2Bb', 'plain', False, False, 3, 2], 'request': '/requests/1/1'} | Passed |
| fixture 3 | {'decision': ['z', '/fixed', None, True, '', '{missing}', False, False, 1, 0], 'request': '/requests/1/2'} | {'decision': ['z', '/fixed', None, True, '', '{missing}', False, False, 1, 0], 'request': '/requests/1/2'} | Passed |
| fixture 4 | {'decision': ['%252F', '/%2F', 'a', False, 'x%3Dy', '{id}', False, False, 3, 1], 'request': '/requests/1/3'} | {'decision': ['%252F', '/%2F', 'c', False, 'x%3Dy', '{id}', False, False, 3, 1], 'request': '/requests/1/3'} | Failed |
| fixture 5 | {'decision': ['caf%C3%A9', '/café', 'a', True, 'a%20b', '{{id}}', False, False, 5, 1], 'request': '/requests/1/4'} | {'decision': ['caf%C3%A9', '/café', None, True, 'a%20b', '{{id}}', False, False, 5, 1], 'request': '/requests/1/4'} | Failed |
| fixture 6 | {'decision': ['', '/', '', False, '%23frag', '', False, True, 0, 1], 'request': '/requests/1/5'} | {'decision': ['', '/', '', False, '%23frag', '', False, True, 0, 1], 'request': '/requests/1/5'} | Passed |
| fixture 7 | {'decision': ['%2Fa%2F%2Fb', '/{other}//a//b', 'x', False, 'a%2Fb', 'literal', True, False, 5, 1], 'request': '/requests/1/6'} | {'decision': ['%2Fa%2F%2Fb', '/{other}//a//b', 'x', False, 'a%2Fb', 'literal', True, False, 5, 1], 'request': '/requests/1/6'} | Passed |
SHA-256 / 5f49b37a51a48d6c4a6102946d0cfd5b34d0c598216328733f805f9ad1e179df
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
from urllib.parse import urlsplit, unquote, quote
import posixpath
import re
N = 1
observations = []
def solve(request, template, value, captures, index, query_value, literal):
return {'request': request, 'decision': [quote(value,safe=''), template.replace('{id}',value), captures[index] if 0<=index<len(captures) else None, index < 0 or index >= len(captures), quote(query_value,safe=''), literal, bool(re.search(r'\{[^{}]+\}',template.replace('{id}',value))), captures[index] == '' if 0<=index<len(captures) else False, len(value.encode('utf-8')), template.count('{id}')]}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('fixture 1', solve('/requests/' + str(N) + '/0', '/item/{id}', 'a/b', ['zero', 'one'], 1, 'a&b', '{id}'), {'request': '/requests/' + str(N) + '/0', 'decision': ['a%2Fb', '/item/a/b', 'one', False, 'a%26b', '{id}', False, False, 3, 1]})
check('fixture 2', solve('/requests/' + str(N) + '/1', '/{id}/{id}', 'x y', ['only'], 0, 'a+b', 'plain'), {'request': '/requests/' + str(N) + '/1', 'decision': ['x%20y', '/x y/x y', 'only', False, 'a%2Bb', 'plain', False, False, 3, 2]})
check('fixture 3', solve('/requests/' + str(N) + '/2', '/fixed', 'z', [], 0, '', '{missing}'), {'request': '/requests/' + str(N) + '/2', 'decision': ['z', '/fixed', None, True, '', '{missing}', False, False, 1, 0]})
check('fixture 4', solve('/requests/' + str(N) + '/3', '/{id}', '%2F', ['a', 'b', 'c'], 2, 'x=y', '{id}'), {'request': '/requests/' + str(N) + '/3', 'decision': ['%252F', '/%2F', 'c', False, 'x%3Dy', '{id}', False, False, 3, 1]})
check('fixture 5', solve('/requests/' + str(N) + '/4', '/{id}', 'café', ['a'], 2, 'a b', '{{id}}'), {'request': '/requests/' + str(N) + '/4', 'decision': ['caf%C3%A9', '/café', None, True, 'a%20b', '{{id}}', False, False, 5, 1]})
check('fixture 6', solve('/requests/' + str(N) + '/5', '/{id}', '', [''], 0, '#frag', ''), {'request': '/requests/' + str(N) + '/5', 'decision': ['', '/', '', False, '%23frag', '', False, True, 0, 1]})
check('fixture 7', solve('/requests/' + str(N) + '/6', '/{other}/{id}', '/a//b', ['x'], 0, 'a/b', 'literal'), {'request': '/requests/' + str(N) + '/6', 'decision': ['%2Fa%2F%2Fb', '/{other}//a//b', 'x', False, 'a%2Fb', 'literal', True, False, 5, 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 |
|---|---|---|---|
| fixture 1 | {'decision': ['a%2Fb', '/item/a/b', 'one', False, 'a%26b', '{id}', False, False, 3, 1], 'request': '/requests/1/0'} | {'decision': ['a%2Fb', '/item/a/b', 'one', False, 'a%26b', '{id}', False, False, 3, 1], 'request': '/requests/1/0'} | Passed |
| fixture 2 | {'decision': ['x%20y', '/x y/x y', 'only', False, 'a%2Bb', 'plain', False, False, 3, 2], 'request': '/requests/1/1'} | {'decision': ['x%20y', '/x y/x y', 'only', False, 'a%2Bb', 'plain', False, False, 3, 2], 'request': '/requests/1/1'} | Passed |
| fixture 3 | {'decision': ['z', '/fixed', None, True, '', '{missing}', False, False, 1, 0], 'request': '/requests/1/2'} | {'decision': ['z', '/fixed', None, True, '', '{missing}', False, False, 1, 0], 'request': '/requests/1/2'} | Passed |
| fixture 4 | {'decision': ['%252F', '/%2F', 'c', False, 'x%3Dy', '{id}', False, False, 3, 1], 'request': '/requests/1/3'} | {'decision': ['%252F', '/%2F', 'c', False, 'x%3Dy', '{id}', False, False, 3, 1], 'request': '/requests/1/3'} | Passed |
| fixture 5 | {'decision': ['caf%C3%A9', '/café', None, True, 'a%20b', '{{id}}', False, False, 5, 1], 'request': '/requests/1/4'} | {'decision': ['caf%C3%A9', '/café', None, True, 'a%20b', '{{id}}', False, False, 5, 1], 'request': '/requests/1/4'} | Passed |
| fixture 6 | {'decision': ['', '/', '', False, '%23frag', '', False, True, 0, 1], 'request': '/requests/1/5'} | {'decision': ['', '/', '', False, '%23frag', '', False, True, 0, 1], 'request': '/requests/1/5'} | Passed |
| fixture 7 | {'decision': ['%2Fa%2F%2Fb', '/{other}//a//b', 'x', False, 'a%2Fb', 'literal', True, False, 5, 1], 'request': '/requests/1/6'} | {'decision': ['%2Fa%2F%2Fb', '/{other}//a//b', 'x', False, 'a%2Fb', 'literal', True, False, 5, 1], 'request': '/requests/1/6'} | Passed |
SHA-256 / 3ad2a64a5005ec30f643e7b581fd5f41e44bd2d0df3e605329eb68648956a630
Verification & scope
Stipulated offline redirect policy, not a complete HTTP, browser, URL, cache, or security implementation. Numbered variants vary request correlation identity. 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:35.825277+00:00.
Case digest / 107dfb83a9f64983aed5915dbfd792f31ac47397ee148abe55a9c9bb3dd75706