{"record":{"id":"55534a24e2636d0f","repo":"jdx/mise","slug":"malformed-load-command-table-in","errorCode":null,"errorMessage":"malformed load command table in {}","messagePattern":"malformed load command table in (.+?)","errorType":"exception","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"src/system/packages/brew/macho.rs","lineNumber":85,"sourceCode":"        // not a 64-bit LE Mach-O (32-bit or big-endian) — nothing modern on\n        // arm64 macOS; leave it to the caller's generic byte-level pass\n        return Ok(false);\n    }\n    let ncmds = u32_at(slice, 16) as usize;\n    let sizeofcmds = u32_at(slice, 20) as usize;\n    if HEADER_SIZE_64 + sizeofcmds > slice.len() {\n        bail!(\"malformed Mach-O in {}\", path.display());\n    }\n\n    // upper bound for growing the load-command table: the first byte of\n    // section data (everything between sizeofcmds and there is padding)\n    let lc_end = HEADER_SIZE_64 + sizeofcmds;\n    let mut first_data = slice.len();\n    {\n        let mut off = HEADER_SIZE_64;\n        for _ in 0..ncmds {\n            if off + 8 > lc_end {\n                bail!(\"malformed load command table in {}\", path.display());\n            }\n            let cmd = u32_at(slice, off);\n            let cmdsize = u32_at(slice, off + 4) as usize;\n            if cmdsize < 8 || off + cmdsize > lc_end {\n                bail!(\"malformed load command in {}\", path.display());\n            }\n            if cmd == LC_SEGMENT_64 {\n                let nsects = u32_at(slice, off + 64) as usize;\n                for i in 0..nsects {\n                    // struct section_64 is 80 bytes; offset field at +48\n                    let sect = off + 72 + i * 80;\n                    if sect + 80 > off + cmdsize {\n                        break;\n                    }\n                    let file_off = u32_at(slice, sect + 48) as usize;\n                    if file_off > 0 {\n                        first_data = first_data.min(file_off);\n                    }","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/system/packages/brew/macho.rs#L67-L103","documentation":"While scanning the ncmds load commands of a 64-bit Mach-O, the running offset reached the end of the table (lc_end = 32 + sizeofcmds) before all commands were read — at least 8 bytes are needed per command header. The declared table size and command count disagree, so the file is treated as malformed.","triggerScenarios":"patch_slice first scan loop: off + 8 > lc_end before ncmds iterations complete. Produced by corrupted headers where sizeofcmds is too small for ncmds, or by fuzzed/hand-crafted Mach-O files.","commonSituations":"Corrupted bottle artifacts; files damaged in transit or by disk issues; test/fuzz binaries with deliberately inconsistent headers.","solutions":["Re-download the bottle (clear cache) and retry the pour","Cross-check with otool -l — inconsistency visible there confirms file corruption","Report upstream if the file is reproducibly valid elsewhere"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Verify ncmds commands fit within sizeofcmds before patching.\nfn load_command_table_ok(slice: &[u8]) -> bool {\n    let ncmds = u32_at(slice, 16) as usize;\n    let lc_end = 32 + u32_at(slice, 20) as usize;\n    let mut off = 32;\n    for _ in 0..ncmds {\n        if off + 8 > lc_end { return false; }\n        off += u32_at(slice, off + 4) as usize;\n    }\n    true\n}","typeGuard":"fn macho_table_walkable(slice: &[u8]) -> bool {\n    macho_header_ok(slice) && load_command_table_ok(slice)\n}","tryCatchPattern":"if let Err(e) = patch_macho(&mut content, &replacements, &path) {\n    // log and skip this artifact rather than failing the whole pour\n    warn!(\"{}: skipping Mach-O relocation: {e:#}\", path.display());\n}","preventionTips":["Validate bottle integrity (sha256) before extraction","Use otool -l as ground truth when triaging malformed-table reports"],"tags":["brew","macho","macos","binary-patching","validation"],"backgroundTag":"mach-o-header-validation-failed","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}