{"abstract":"SETUP.EXE passes because the extension comparison is case-sensitive.","category":"Email MIME structure","checks":7,"contract":"Leaves {type, filename, disp, size}. A leaf is blocked when its last filename extension (trimmed, lower-cased) is in blocked_ext, its type is application/x-msdownload, or its size exceeds max_size. A non-attachment leaf without a filename (a body) is never blocked. Blocked leaves become \"strip\", others \"keep\"; a blocked leaf anywhere under multipart/signed cannot be stripped, and then the whole message is \"reject\". Result: the per-leaf action list or \"reject\".","evaluation_group":"w2-email_mime_structure-attachment-stripping","failed_approach":"Lower-casing without trimming leaves a trailing space on the extension. The attempted `(n.get('filename') or '').lower()` still disagrees with a fixture.","family":"w2-email_mime_structure-attachment-stripping-extension-normalization","id":"FA-76801","implementations":{"attempt":{"sha256":"a008c8587279dfbb3e27e41cea6d8b9bc9538cd1d6591b0c2c43300d4284a8d5","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(tree, blocked_ext, max_size):\n    actions = []\n    def walk(n, signed):\n        t = n['type'].lower()\n        if t.startswith('multipart/'):\n            for c in n['parts']:\n                walk(c, signed or t == 'multipart/signed')\n            return\n        name = (n.get('filename') or '').lower()\n        ext = name.rsplit('.', 1)[-1] if '.' in name else ''\n        bad = ext in blocked_ext or t == 'application/x-msdownload' or n.get('size', 0) > max_size\n        if (n.get('disp') or '').lower() != 'attachment' and not name:\n            bad = False\n        if bad and signed:\n            actions.append('reject')\n        else:\n            actions.append('strip' if bad else 'keep')\n    walk(tree, False)\n    return 'reject' if 'reject' in actions else actions\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\n_CASES = {1: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice1.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP1.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 1}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5001}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 1000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 1001}]}, [], 1000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r1.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])], 2: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice2.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP2.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 2}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5002}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 2000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 2001}]}, [], 2000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r2.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])], 3: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice3.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP3.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 3}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5003}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 3000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 3001}]}, [], 3000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r3.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])], 4: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice4.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP4.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 4}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5004}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 4000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 4001}]}, [], 4000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r4.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])], 5: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice5.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP5.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 5}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5005}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 5000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 5001}]}, [], 5000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r5.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])]}\nfor _label, _args, _expected in _CASES[N]:\n    check(_label, 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":"5f259394c0a8c217e005d60bdcf0cb364f9898d46ba6bc174f4913599f6c471a","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(tree, blocked_ext, max_size):\n    actions = []\n    def walk(n, signed):\n        t = n['type'].lower()\n        if t.startswith('multipart/'):\n            for c in n['parts']:\n                walk(c, signed or t == 'multipart/signed')\n            return\n        name = (n.get('filename') or '').strip()\n        ext = name.rsplit('.', 1)[-1] if '.' in name else ''\n        bad = ext in blocked_ext or t == 'application/x-msdownload' or n.get('size', 0) > max_size\n        if (n.get('disp') or '').lower() != 'attachment' and not name:\n            bad = False\n        if bad and signed:\n            actions.append('reject')\n        else:\n            actions.append('strip' if bad else 'keep')\n    walk(tree, False)\n    return 'reject' if 'reject' in actions else actions\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\n_CASES = {1: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice1.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP1.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 1}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5001}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 1000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 1001}]}, [], 1000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r1.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])], 2: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice2.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP2.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 2}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5002}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 2000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 2001}]}, [], 2000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r2.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])], 3: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice3.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP3.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 3}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5003}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 3000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 3001}]}, [], 3000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r3.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])], 4: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice4.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP4.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 4}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5004}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 4000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 4001}]}, [], 4000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r4.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])], 5: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice5.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP5.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 5}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5005}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 5000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 5001}]}, [], 5000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r5.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])]}\nfor _label, _args, _expected in _CASES[N]:\n    check(_label, 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":"c75af58699560d6615527b9c35088db3b69d568b971b5a0fb01e61f37640e16a","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(tree, blocked_ext, max_size):\n    actions = []\n    def walk(n, signed):\n        t = n['type'].lower()\n        if t.startswith('multipart/'):\n            for c in n['parts']:\n                walk(c, signed or t == 'multipart/signed')\n            return\n        name = (n.get('filename') or '').strip().lower()\n        ext = name.rsplit('.', 1)[-1] if '.' in name else ''\n        bad = ext in blocked_ext or t == 'application/x-msdownload' or n.get('size', 0) > max_size\n        if (n.get('disp') or '').lower() != 'attachment' and not name:\n            bad = False\n        if bad and signed:\n            actions.append('reject')\n        else:\n            actions.append('strip' if bad else 'keep')\n    walk(tree, False)\n    return 'reject' if 'reject' in actions else actions\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\n_CASES = {1: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice1.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP1.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 1}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5001}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 1000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 1001}]}, [], 1000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r1.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])], 2: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice2.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP2.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 2}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5002}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 2000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 2001}]}, [], 2000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r2.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])], 3: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice3.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP3.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 3}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5003}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 3000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 3001}]}, [], 3000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r3.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])], 4: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice4.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP4.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 4}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5004}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 4000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 4001}]}, [], 4000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r4.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])], 5: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice5.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP5.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 5}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5005}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 5000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 5001}]}, [], 5000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r5.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])]}\nfor _label, _args, _expected in _CASES[N]:\n    check(_label, 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":"Stipulated offline model over pre-parsed MIME dictionaries; not a conforming MIME parser, generator or mail client. 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-email_mime_structure-attachment-stripping-extension-normalization","generated_at":"2026-09-29T14:49:19.707314+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Mail gateways strip dangerous attachments but must not silently break signed messages.","repair":"Use `(n.get('filename') or '').strip().lower()` for the extension normalization decision and keep every other rule of the model unchanged.","root_cause":"The extension normalization decision evaluates `(n.get('filename') or '').strip()` where the contract requires `(n.get('filename') or '').strip().lower()`.","sha256":"3f874676d639044a9e829b25131dc150d39ecfe7ad9faf97ad2d1704f0f288cb","title":"Strip blocked attachments under a content policy: extension normalization · case 01","variant":1,"variant_policy":"N selects a different enumerated fixture set (renamed identifiers, part counts and sizes); boundary fixtures recur across variants.","verification":{"attempt":{"elapsed_ms":39.86,"exit_code":1,"observations":[{"actual":["keep","strip"],"check":"double extension","expected":["keep","strip"],"passed":true},{"actual":["keep","keep"],"check":"upper-case padded extension","expected":["keep","strip"],"passed":false},{"actual":"reject","check":"blocked part inside signed mixed","expected":"reject","passed":true},{"actual":["keep","strip","strip"],"check":"large body and named inline part","expected":["keep","strip","strip"],"passed":true},{"actual":["keep","keep","strip"],"check":"size boundaries","expected":["keep","keep","strip"],"passed":true},{"actual":"reject","check":"executable type in signed","expected":"reject","passed":true},{"actual":["keep","keep"],"check":"clean message","expected":["keep","keep"],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"double extension\", \"actual\": [\"keep\", \"strip\"], \"expected\": [\"keep\", \"strip\"], \"passed\": true}, {\"check\": \"upper-case padded extension\", \"actual\": [\"keep\", \"keep\"], \"expected\": [\"keep\", \"strip\"], \"passed\": false}, {\"check\": \"blocked part inside signed mixed\", \"actual\": \"reject\", \"expected\": \"reject\", \"passed\": true}, {\"check\": \"large body and named inline part\", \"actual\": [\"keep\", \"strip\", \"strip\"], \"expected\": [\"keep\", \"strip\", \"strip\"], \"passed\": true}, {\"check\": \"size boundaries\", \"actual\": [\"keep\", \"keep\", \"strip\"], \"expected\": [\"keep\", \"keep\", \"strip\"], \"passed\": true}, {\"check\": \"executable type in signed\", \"actual\": \"reject\", \"expected\": \"reject\", \"passed\": true}, {\"check\": \"clean message\", \"actual\": [\"keep\", \"keep\"], \"expected\": [\"keep\", \"keep\"], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":41.262,"exit_code":1,"observations":[{"actual":["keep","strip"],"check":"double extension","expected":["keep","strip"],"passed":true},{"actual":["keep","keep"],"check":"upper-case padded extension","expected":["keep","strip"],"passed":false},{"actual":"reject","check":"blocked part inside signed mixed","expected":"reject","passed":true},{"actual":["keep","strip","strip"],"check":"large body and named inline part","expected":["keep","strip","strip"],"passed":true},{"actual":["keep","keep","strip"],"check":"size boundaries","expected":["keep","keep","strip"],"passed":true},{"actual":"reject","check":"executable type in signed","expected":"reject","passed":true},{"actual":["keep","keep"],"check":"clean message","expected":["keep","keep"],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"double extension\", \"actual\": [\"keep\", \"strip\"], \"expected\": [\"keep\", \"strip\"], \"passed\": true}, {\"check\": \"upper-case padded extension\", \"actual\": [\"keep\", \"keep\"], \"expected\": [\"keep\", \"strip\"], \"passed\": false}, {\"check\": \"blocked part inside signed mixed\", \"actual\": \"reject\", \"expected\": \"reject\", \"passed\": true}, {\"check\": \"large body and named inline part\", \"actual\": [\"keep\", \"strip\", \"strip\"], \"expected\": [\"keep\", \"strip\", \"strip\"], \"passed\": true}, {\"check\": \"size boundaries\", \"actual\": [\"keep\", \"keep\", \"strip\"], \"expected\": [\"keep\", \"keep\", \"strip\"], \"passed\": true}, {\"check\": \"executable type in signed\", \"actual\": \"reject\", \"expected\": \"reject\", \"passed\": true}, {\"check\": \"clean message\", \"actual\": [\"keep\", \"keep\"], \"expected\": [\"keep\", \"keep\"], \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":39.755,"exit_code":0,"observations":[{"actual":["keep","strip"],"check":"double extension","expected":["keep","strip"],"passed":true},{"actual":["keep","strip"],"check":"upper-case padded extension","expected":["keep","strip"],"passed":true},{"actual":"reject","check":"blocked part inside signed mixed","expected":"reject","passed":true},{"actual":["keep","strip","strip"],"check":"large body and named inline part","expected":["keep","strip","strip"],"passed":true},{"actual":["keep","keep","strip"],"check":"size boundaries","expected":["keep","keep","strip"],"passed":true},{"actual":"reject","check":"executable type in signed","expected":"reject","passed":true},{"actual":["keep","keep"],"check":"clean message","expected":["keep","keep"],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"double extension\", \"actual\": [\"keep\", \"strip\"], \"expected\": [\"keep\", \"strip\"], \"passed\": true}, {\"check\": \"upper-case padded extension\", \"actual\": [\"keep\", \"strip\"], \"expected\": [\"keep\", \"strip\"], \"passed\": true}, {\"check\": \"blocked part inside signed mixed\", \"actual\": \"reject\", \"expected\": \"reject\", \"passed\": true}, {\"check\": \"large body and named inline part\", \"actual\": [\"keep\", \"strip\", \"strip\"], \"expected\": [\"keep\", \"strip\", \"strip\"], \"passed\": true}, {\"check\": \"size boundaries\", \"actual\": [\"keep\", \"keep\", \"strip\"], \"expected\": [\"keep\", \"keep\", \"strip\"], \"passed\": true}, {\"check\": \"executable type in signed\", \"actual\": \"reject\", \"expected\": \"reject\", \"passed\": true}, {\"check\": \"clean message\", \"actual\": [\"keep\", \"keep\"], \"expected\": [\"keep\", \"keep\"], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}