{"abstract":"An EXIF value of 0 or 9 is passed to the renderer even though a valid XMP orientation exists.","category":"Image orientation metadata","checks":8,"contract":"Resolve the displayed orientation tag from metadata sources. For HEIF, the container transforms are authoritative and EXIF/XMP are ignored: irot is anticlockwise quarter turns (default 0) applied first, then imir mirrors about the vertical axis (0, left-right) or the horizontal axis (1, top-bottom); the result is mapped to a tag through (k clockwise quarter turns after m mirrors) = {(0,0):1, (0,1):2, (2,0):3, (2,1):4, (3,1):5, (1,0):6, (1,1):7, (3,0):8}. For other containers a valid integer EXIF value 1..8 wins; otherwise an XMP string that is a single digit 1..8 after trimming whitespace; otherwise 1.","evaluation_group":"w2-image-orientation-metadata-source-precedence","failed_approach":"A truthiness check still accepts 9 and even the boolean True.","family":"w2-image-orientation-metadata-source-precedence-exif-range","id":"FA-79016","implementations":{"attempt":{"sha256":"ee169ac611a7e2366772a1e95c2a2ee2d4218ebc07984c930af526e26c0e5ad8","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(meta):\n    from_km = {(0, 0): 1, (0, 1): 2, (2, 0): 3, (2, 1): 4, (3, 1): 5, (1, 0): 6, (1, 1): 7, (3, 0): 8}\n    c = meta.get('container')\n    if c == 'heif':\n        rot = meta.get('irot')\n        mir = meta.get('imir')\n        rot = 0 if rot is None else rot % 4\n        if mir is None:\n            return from_km[((-rot) % 4, 0)]\n        if mir == 0:\n            return from_km[(rot, 1)]\n        return from_km[((rot + 2) % 4, 1)]\n    e = meta.get('exif')\n    if e:\n        return e\n    x = meta.get('xmp')\n    if isinstance(x, str):\n        s = x.strip()\n        if s in ('1', '2', '3', '4', '5', '6', '7', '8'):\n            return int(s)\n    return 1\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[[{'container': 'jpeg', 'exif': 0, 'xmp': '\\t5'}, 5], [{'container': 'tiff', 'exif': True, 'xmp': '7 '}, 7], [{'container': 'tiff', 'exif': 9, 'xmp': '6'}, 6], [{'container': 'png'}, 1], [{'container': 'jpeg', 'xmp': '2'}, 2], [{'container': 'heif', 'xmp': '\\t5', 'irot': 3}, 6], [{'container': 'tiff'}, 1], [{'container': 'jpeg', 'exif': 9}, 1]], [[{'container': 'jpeg', 'exif': 0}, 1], [{'container': 'jpeg', 'exif': True, 'xmp': '\\t5'}, 5], [{'container': 'jpeg', 'exif': 9, 'irot': 2}, 1], [{'container': 'png', 'xmp': '3\\n'}, 3], [{'container': 'jpeg', 'xmp': '3\\n'}, 3], [{'container': 'heif', 'exif': 5, 'xmp': ' 8', 'imir': 0}, 2], [{'container': 'heif', 'exif': 3, 'xmp': 'x', 'irot': 0}, 1], [{'container': 'jpeg', 'exif': 0, 'xmp': '6'}, 6]], [[{'container': 'jpeg', 'exif': 9, 'xmp': ' 8'}, 8], [{'container': 'jpeg', 'exif': True, 'xmp': '3\\n', 'irot': 3, 'imir': 0}, 3], [{'container': 'png', 'exif': 9, 'xmp': '2'}, 2], [{'container': 'tiff'}, 1], [{'container': 'jpeg'}, 1], [{'container': 'heif', 'exif': 6, 'xmp': 'x', 'irot': 2}, 3], [{'container': 'png', 'exif': 1}, 1], [{'container': 'jpeg', 'exif': 0}, 1]], [[{'container': 'jpeg', 'exif': 9, 'xmp': '0', 'irot': 0}, 1], [{'container': 'png', 'exif': 9, 'xmp': ' 8'}, 8], [{'container': 'jpeg', 'exif': 9}, 1], [{'container': 'jpeg', 'exif': 1}, 1], [{'container': 'heif', 'exif': 1, 'xmp': '7 ', 'irot': 2}, 3], [{'container': 'heif', 'xmp': '\\t5'}, 1], [{'container': 'jpeg', 'xmp': '7 '}, 7], [{'container': 'jpeg', 'exif': 0, 'xmp': '6'}, 6]], [[{'container': 'tiff', 'exif': 9}, 1], [{'container': 'jpeg', 'exif': 9}, 1], [{'container': 'png', 'exif': 9, 'irot': 3, 'imir': 1}, 1], [{'container': 'png', 'xmp': '7 '}, 7], [{'container': 'heif', 'irot': 2}, 3], [{'container': 'heif', 'xmp': ' 8', 'irot': 1}, 8], [{'container': 'jpeg', 'xmp': 'x'}, 1], [{'container': 'jpeg', 'exif': 9, 'xmp': '2'}, 2]]]\nlabels = [\"regression: EXIF value validation\", \"repair trap\", \"combined fault\", \"control\", \"control\", \"boundary\", \"boundary\", \"control\"]\nfor i, (args, expected) in enumerate(fixtures[N-1]):\n    check(\"%s %d\" % (labels[i % len(labels)], i), solve(args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"broken":{"sha256":"94bde50e3c0fd7637cc5dd5437b8b61c9be753a0d28609b6a47f5b1210c83009","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(meta):\n    from_km = {(0, 0): 1, (0, 1): 2, (2, 0): 3, (2, 1): 4, (3, 1): 5, (1, 0): 6, (1, 1): 7, (3, 0): 8}\n    c = meta.get('container')\n    if c == 'heif':\n        rot = meta.get('irot')\n        mir = meta.get('imir')\n        rot = 0 if rot is None else rot % 4\n        if mir is None:\n            return from_km[((-rot) % 4, 0)]\n        if mir == 0:\n            return from_km[(rot, 1)]\n        return from_km[((rot + 2) % 4, 1)]\n    e = meta.get('exif')\n    if isinstance(e, int) and not isinstance(e, bool):\n        return e\n    x = meta.get('xmp')\n    if isinstance(x, str):\n        s = x.strip()\n        if s in ('1', '2', '3', '4', '5', '6', '7', '8'):\n            return int(s)\n    return 1\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[[{'container': 'jpeg', 'exif': 0, 'xmp': '\\t5'}, 5], [{'container': 'tiff', 'exif': True, 'xmp': '7 '}, 7], [{'container': 'tiff', 'exif': 9, 'xmp': '6'}, 6], [{'container': 'png'}, 1], [{'container': 'jpeg', 'xmp': '2'}, 2], [{'container': 'heif', 'xmp': '\\t5', 'irot': 3}, 6], [{'container': 'tiff'}, 1], [{'container': 'jpeg', 'exif': 9}, 1]], [[{'container': 'jpeg', 'exif': 0}, 1], [{'container': 'jpeg', 'exif': True, 'xmp': '\\t5'}, 5], [{'container': 'jpeg', 'exif': 9, 'irot': 2}, 1], [{'container': 'png', 'xmp': '3\\n'}, 3], [{'container': 'jpeg', 'xmp': '3\\n'}, 3], [{'container': 'heif', 'exif': 5, 'xmp': ' 8', 'imir': 0}, 2], [{'container': 'heif', 'exif': 3, 'xmp': 'x', 'irot': 0}, 1], [{'container': 'jpeg', 'exif': 0, 'xmp': '6'}, 6]], [[{'container': 'jpeg', 'exif': 9, 'xmp': ' 8'}, 8], [{'container': 'jpeg', 'exif': True, 'xmp': '3\\n', 'irot': 3, 'imir': 0}, 3], [{'container': 'png', 'exif': 9, 'xmp': '2'}, 2], [{'container': 'tiff'}, 1], [{'container': 'jpeg'}, 1], [{'container': 'heif', 'exif': 6, 'xmp': 'x', 'irot': 2}, 3], [{'container': 'png', 'exif': 1}, 1], [{'container': 'jpeg', 'exif': 0}, 1]], [[{'container': 'jpeg', 'exif': 9, 'xmp': '0', 'irot': 0}, 1], [{'container': 'png', 'exif': 9, 'xmp': ' 8'}, 8], [{'container': 'jpeg', 'exif': 9}, 1], [{'container': 'jpeg', 'exif': 1}, 1], [{'container': 'heif', 'exif': 1, 'xmp': '7 ', 'irot': 2}, 3], [{'container': 'heif', 'xmp': '\\t5'}, 1], [{'container': 'jpeg', 'xmp': '7 '}, 7], [{'container': 'jpeg', 'exif': 0, 'xmp': '6'}, 6]], [[{'container': 'tiff', 'exif': 9}, 1], [{'container': 'jpeg', 'exif': 9}, 1], [{'container': 'png', 'exif': 9, 'irot': 3, 'imir': 1}, 1], [{'container': 'png', 'xmp': '7 '}, 7], [{'container': 'heif', 'irot': 2}, 3], [{'container': 'heif', 'xmp': ' 8', 'irot': 1}, 8], [{'container': 'jpeg', 'xmp': 'x'}, 1], [{'container': 'jpeg', 'exif': 9, 'xmp': '2'}, 2]]]\nlabels = [\"regression: EXIF value validation\", \"repair trap\", \"combined fault\", \"control\", \"control\", \"boundary\", \"boundary\", \"control\"]\nfor i, (args, expected) in enumerate(fixtures[N-1]):\n    check(\"%s %d\" % (labels[i % len(labels)], i), solve(args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"fixed":{"sha256":"fd3174c38668f960eeacdaa7662e58e2eafe6a6aa81bccb0fec574d808a9a97e","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(meta):\n    from_km = {(0, 0): 1, (0, 1): 2, (2, 0): 3, (2, 1): 4, (3, 1): 5, (1, 0): 6, (1, 1): 7, (3, 0): 8}\n    c = meta.get('container')\n    if c == 'heif':\n        rot = meta.get('irot')\n        mir = meta.get('imir')\n        rot = 0 if rot is None else rot % 4\n        if mir is None:\n            return from_km[((-rot) % 4, 0)]\n        if mir == 0:\n            return from_km[(rot, 1)]\n        return from_km[((rot + 2) % 4, 1)]\n    e = meta.get('exif')\n    if isinstance(e, int) and not isinstance(e, bool) and 1 <= e <= 8:\n        return e\n    x = meta.get('xmp')\n    if isinstance(x, str):\n        s = x.strip()\n        if s in ('1', '2', '3', '4', '5', '6', '7', '8'):\n            return int(s)\n    return 1\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[[{'container': 'jpeg', 'exif': 0, 'xmp': '\\t5'}, 5], [{'container': 'tiff', 'exif': True, 'xmp': '7 '}, 7], [{'container': 'tiff', 'exif': 9, 'xmp': '6'}, 6], [{'container': 'png'}, 1], [{'container': 'jpeg', 'xmp': '2'}, 2], [{'container': 'heif', 'xmp': '\\t5', 'irot': 3}, 6], [{'container': 'tiff'}, 1], [{'container': 'jpeg', 'exif': 9}, 1]], [[{'container': 'jpeg', 'exif': 0}, 1], [{'container': 'jpeg', 'exif': True, 'xmp': '\\t5'}, 5], [{'container': 'jpeg', 'exif': 9, 'irot': 2}, 1], [{'container': 'png', 'xmp': '3\\n'}, 3], [{'container': 'jpeg', 'xmp': '3\\n'}, 3], [{'container': 'heif', 'exif': 5, 'xmp': ' 8', 'imir': 0}, 2], [{'container': 'heif', 'exif': 3, 'xmp': 'x', 'irot': 0}, 1], [{'container': 'jpeg', 'exif': 0, 'xmp': '6'}, 6]], [[{'container': 'jpeg', 'exif': 9, 'xmp': ' 8'}, 8], [{'container': 'jpeg', 'exif': True, 'xmp': '3\\n', 'irot': 3, 'imir': 0}, 3], [{'container': 'png', 'exif': 9, 'xmp': '2'}, 2], [{'container': 'tiff'}, 1], [{'container': 'jpeg'}, 1], [{'container': 'heif', 'exif': 6, 'xmp': 'x', 'irot': 2}, 3], [{'container': 'png', 'exif': 1}, 1], [{'container': 'jpeg', 'exif': 0}, 1]], [[{'container': 'jpeg', 'exif': 9, 'xmp': '0', 'irot': 0}, 1], [{'container': 'png', 'exif': 9, 'xmp': ' 8'}, 8], [{'container': 'jpeg', 'exif': 9}, 1], [{'container': 'jpeg', 'exif': 1}, 1], [{'container': 'heif', 'exif': 1, 'xmp': '7 ', 'irot': 2}, 3], [{'container': 'heif', 'xmp': '\\t5'}, 1], [{'container': 'jpeg', 'xmp': '7 '}, 7], [{'container': 'jpeg', 'exif': 0, 'xmp': '6'}, 6]], [[{'container': 'tiff', 'exif': 9}, 1], [{'container': 'jpeg', 'exif': 9}, 1], [{'container': 'png', 'exif': 9, 'irot': 3, 'imir': 1}, 1], [{'container': 'png', 'xmp': '7 '}, 7], [{'container': 'heif', 'irot': 2}, 3], [{'container': 'heif', 'xmp': ' 8', 'irot': 1}, 8], [{'container': 'jpeg', 'xmp': 'x'}, 1], [{'container': 'jpeg', 'exif': 9, 'xmp': '2'}, 2]]]\nlabels = [\"regression: EXIF value validation\", \"repair trap\", \"combined fault\", \"control\", \"control\", \"boundary\", \"boundary\", \"control\"]\nfor i, (args, expected) in enumerate(fixtures[N-1]):\n    check(\"%s %d\" % (labels[i % len(labels)], i), solve(args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"}},"limitations":"A deterministic bounded teaching model with a stipulated contract; it makes no claim of conformance to any published specification. 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.","method":"Deterministic executable model with adversarial boundary fixtures.","provenance":{"created_by":"Failure Map","dependencies":"Python standard library","family":"w2-image-orientation-metadata-source-precedence-exif-range","generated_at":"2026-09-29T14:49:40.520664+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Camera, phone and scanner images carry an orientation hint separately from the stored pixels; galleries, thumbnailers, editors and upload pipelines must interpret it consistently or photos appear sideways, mirrored or doubly rotated.","repair":"Accept EXIF only for integers 1..8 and otherwise continue to XMP.","root_cause":"The EXIF value is accepted without checking the 1..8 range, so fallback never happens.","sha256":"f9e39629f66de8c44fbf3f4d9b97d30ee62c6085288e5913dc8b28fb50afa24b","title":"Out-of-range EXIF orientation overrides XMP · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":39.558,"exit_code":1,"observations":[{"actual":5,"check":"regression: EXIF value validation 0","expected":5,"passed":true},{"actual":true,"check":"repair trap 1","expected":7,"passed":false},{"actual":9,"check":"combined fault 2","expected":6,"passed":false},{"actual":1,"check":"control 3","expected":1,"passed":true},{"actual":2,"check":"control 4","expected":2,"passed":true},{"actual":6,"check":"boundary 5","expected":6,"passed":true},{"actual":1,"check":"boundary 6","expected":1,"passed":true},{"actual":9,"check":"control 7","expected":1,"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: EXIF value validation 0\", \"actual\": 5, \"expected\": 5, \"passed\": true}, {\"check\": \"repair trap 1\", \"actual\": true, \"expected\": 7, \"passed\": false}, {\"check\": \"combined fault 2\", \"actual\": 9, \"expected\": 6, \"passed\": false}, {\"check\": \"control 3\", \"actual\": 1, \"expected\": 1, \"passed\": true}, {\"check\": \"control 4\", \"actual\": 2, \"expected\": 2, \"passed\": true}, {\"check\": \"boundary 5\", \"actual\": 6, \"expected\": 6, \"passed\": true}, {\"check\": \"boundary 6\", \"actual\": 1, \"expected\": 1, \"passed\": true}, {\"check\": \"control 7\", \"actual\": 9, \"expected\": 1, \"passed\": false}], \"passed\": false}\n"},"broken":{"elapsed_ms":40.518,"exit_code":1,"observations":[{"actual":0,"check":"regression: EXIF value validation 0","expected":5,"passed":false},{"actual":7,"check":"repair trap 1","expected":7,"passed":true},{"actual":9,"check":"combined fault 2","expected":6,"passed":false},{"actual":1,"check":"control 3","expected":1,"passed":true},{"actual":2,"check":"control 4","expected":2,"passed":true},{"actual":6,"check":"boundary 5","expected":6,"passed":true},{"actual":1,"check":"boundary 6","expected":1,"passed":true},{"actual":9,"check":"control 7","expected":1,"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: EXIF value validation 0\", \"actual\": 0, \"expected\": 5, \"passed\": false}, {\"check\": \"repair trap 1\", \"actual\": 7, \"expected\": 7, \"passed\": true}, {\"check\": \"combined fault 2\", \"actual\": 9, \"expected\": 6, \"passed\": false}, {\"check\": \"control 3\", \"actual\": 1, \"expected\": 1, \"passed\": true}, {\"check\": \"control 4\", \"actual\": 2, \"expected\": 2, \"passed\": true}, {\"check\": \"boundary 5\", \"actual\": 6, \"expected\": 6, \"passed\": true}, {\"check\": \"boundary 6\", \"actual\": 1, \"expected\": 1, \"passed\": true}, {\"check\": \"control 7\", \"actual\": 9, \"expected\": 1, \"passed\": false}], \"passed\": false}\n"},"fixed":{"elapsed_ms":38.692,"exit_code":0,"observations":[{"actual":5,"check":"regression: EXIF value validation 0","expected":5,"passed":true},{"actual":7,"check":"repair trap 1","expected":7,"passed":true},{"actual":6,"check":"combined fault 2","expected":6,"passed":true},{"actual":1,"check":"control 3","expected":1,"passed":true},{"actual":2,"check":"control 4","expected":2,"passed":true},{"actual":6,"check":"boundary 5","expected":6,"passed":true},{"actual":1,"check":"boundary 6","expected":1,"passed":true},{"actual":1,"check":"control 7","expected":1,"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: EXIF value validation 0\", \"actual\": 5, \"expected\": 5, \"passed\": true}, {\"check\": \"repair trap 1\", \"actual\": 7, \"expected\": 7, \"passed\": true}, {\"check\": \"combined fault 2\", \"actual\": 6, \"expected\": 6, \"passed\": true}, {\"check\": \"control 3\", \"actual\": 1, \"expected\": 1, \"passed\": true}, {\"check\": \"control 4\", \"actual\": 2, \"expected\": 2, \"passed\": true}, {\"check\": \"boundary 5\", \"actual\": 6, \"expected\": 6, \"passed\": true}, {\"check\": \"boundary 6\", \"actual\": 1, \"expected\": 1, \"passed\": true}, {\"check\": \"control 7\", \"actual\": 1, \"expected\": 1, \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}