{"record":{"id":"e19bdab32a41a865","repo":"AUTOMATIC1111/stable-diffusion-webui","slug":"bad-file-inside-filename-name","errorCode":null,"errorMessage":"bad file inside {filename}: {name}","messagePattern":"bad file inside (.+?): (.+?)","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"modules/safe.py","lineNumber":76,"sourceCode":"            import pytorch_lightning.callbacks.model_checkpoint\r\n            return pytorch_lightning.callbacks.model_checkpoint.ModelCheckpoint\r\n        if module == \"__builtin__\" and name == 'set':\r\n            return set\r\n\r\n        # Forbid everything else.\r\n        raise Exception(f\"global '{module}/{name}' is forbidden\")\r\n\r\n\r\n# Regular expression that accepts 'dirname/version', 'dirname/byteorder', 'dirname/data.pkl', '.data/serialization_id', and 'dirname/data/<number>'\r\nallowed_zip_names_re = re.compile(r\"^([^/]+)/((data/\\d+)|version|byteorder|.data/serialization_id|(data\\.pkl))$\")\r\ndata_pkl_re = re.compile(r\"^([^/]+)/data\\.pkl$\")\r\n\r\ndef check_zip_filenames(filename, names):\r\n    for name in names:\r\n        if allowed_zip_names_re.match(name):\r\n            continue\r\n\r\n        raise Exception(f\"bad file inside {filename}: {name}\")\r\n\r\n\r\ndef check_pt(filename, extra_handler):\r\n    try:\r\n\r\n        # new pytorch format is a zip file\r\n        with zipfile.ZipFile(filename) as z:\r\n            check_zip_filenames(filename, z.namelist())\r\n\r\n            # find filename of data.pkl in zip file: '<directory name>/data.pkl'\r\n            data_pkl_filenames = [f for f in z.namelist() if data_pkl_re.match(f)]\r\n            if len(data_pkl_filenames) == 0:\r\n                raise Exception(f\"data.pkl not found in {filename}\")\r\n            if len(data_pkl_filenames) > 1:\r\n                raise Exception(f\"Multiple data.pkl found in {filename}\")\r\n            with z.open(data_pkl_filenames[0]) as file:\r\n                unpickler = RestrictedUnpickler(file)\r\n                unpickler.extra_handler = extra_handler\r","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/82a973c04367123ae98bd9abdf80d9eda9b910e2/modules/safe.py#L58-L94","documentation":"check_pt treats new-format PyTorch files as zip archives and validates every member name against allowed_zip_names_re, which only permits '<dir>/version', '<dir>/byteorder', '<dir>/data.pkl', '<dir>/.data/serialization_id' and '<dir>/data/<number>'. Any other entry (extra folders, sibling files, typical zip-bomb path tricks) raises 'bad file inside'. This is a structural safety check on untrusted checkpoints.","triggerScenarios":"Loading a .pt/.ckpt that is a zip whose archive contains unexpected member names — e.g. a repacked checkpoint with extra files added, a directory prefix change, nested folders, or a hand-zipped model that does not follow the torch archive layout.","commonSituations":"Users re-zipping checkpoints (adding READMEs or metadata files inside the archive); files produced by unusual saving code (custom zipfile writers); rarely, crafted archives attempting path traversal.","solutions":["Re-save the model properly with torch.save(state_dict, path) from a trusted environment so the archive layout is canonical.","Prefer the .safetensors format for distribution — it sidesteps pickle/zip checks entirely.","Do not edit or add files inside .pt/.ckpt zip archives; keep them exactly as exported."],"exampleFix":"# before: hand-zipped archive with extra files\n# model.zip contains: data.pkl, data/0, README.md  -> 'bad file inside'\n\n# after: canonical re-save\nimport torch\ntorch.save(state_dict, 'model.pt')  # produces only allowed member names","handlingStrategy":"validation","validationCode":"import re, zipfile\n\nallowed = re.compile(r\"^([^/]+)/((data/\\d+)|version|byteorder|.data/serialization_id|(data\\.pkl))$\")\n\ndef pt_zip_ok(path):\n    with zipfile.ZipFile(path) as z:\n        return all(allowed.match(n) for n in z.namelist())\n\nassert pt_zip_ok('model.pt'), 'archive layout is not a canonical torch checkpoint'","typeGuard":"def is_canonical_torch_zip(path: str) -> bool:\n    import re, zipfile\n    allowed = re.compile(r\"^([^/]+)/((data/\\d+)|version|byteorder|.data/serialization_id|(data\\.pkl))$\")\n    try:\n        with zipfile.ZipFile(path) as z:\n            return all(allowed.match(n) for n in z.namelist())\n    except zipfile.BadZipFile:\n        return False","tryCatchPattern":"try:\n    weights = torch.load(path)\nexcept Exception as e:\n    if 'bad file inside' in str(e):\n        raise RuntimeError(f'{path} has a non-standard archive layout; re-save with torch.save or use safetensors')\n    raise","preventionTips":["Never re-pack or add files into .pt/.ckpt zip archives.","Distribute models as safetensors to avoid pickle/zip structure issues entirely."],"tags":["security","pickle","zip","checkpoint","validation"],"backgroundTag":null,"analyzedSha":"82a973c04367123ae98bd9abdf80d9eda9b910e2","analyzedAt":"2026-08-14T16:46:43.225Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}