{"record":{"id":"0611f28b4212bf41","repo":"PHPOffice/PhpSpreadsheet","slug":"bitmap-doesn-t-contain-enough-data-n","errorCode":null,"errorMessage":"$bitmap doesn't contain enough data.\\n","messagePattern":"\\$bitmap doesn't contain enough data\\.\\\\n","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Writer\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Writer/Xls/Worksheet.php","lineNumber":2473,"sourceCode":"     *\n     * @return array{0: int, 1: int, 2: int, 3: string} Data and properties of the bitmap\n     *\n     * @codeCoverageIgnore\n     */\n    public function processBitmap(string $bitmap): array\n    {\n        // Open file.\n        $bmp_fd = @fopen($bitmap, 'rb');\n        if ($bmp_fd === false || 0 === (int) filesize($bitmap)) {\n            throw new WriterException(\"Couldn't import $bitmap\");\n        }\n\n        // Slurp the file into a string.\n        $data = (string) fread($bmp_fd, (int) filesize($bitmap));\n\n        // Check that the file is big enough to be a bitmap.\n        if (strlen($data) <= 0x36) {\n            throw new WriterException(\"$bitmap doesn't contain enough data.\\n\");\n        }\n\n        // The first 2 bytes are used to identify the bitmap.\n\n        $identity = unpack('A2ident', $data);\n        if ($identity === false || $identity['ident'] != 'BM') {\n            throw new WriterException(\"$bitmap doesn't appear to be a valid bitmap image.\\n\");\n        }\n\n        // Remove bitmap data: ID.\n        $data = substr($data, 2);\n\n        // Read and remove the bitmap size. This is more reliable than reading\n        // the data size at offset 0x22.\n        //\n        $size_array = unpack('Vsa', substr($data, 0, 4)) ?: [];\n        /** @var int */\n        $size = $size_array['sa'];","sourceCodeStart":2455,"sourceCodeEnd":2491,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Writer/Xls/Worksheet.php#L2455-L2491","documentation":"After slurping the file into memory, processBitmap() rejects anything of 54 bytes (0x36) or fewer - smaller than a minimal BMP file header plus info header. This guards the subsequent offset-based unpack() calls from reading garbage. It catches truncated files and placeholder stubs; 0-byte files were already rejected by the previous check.","triggerScenarios":"A BMP file truncated below 54 bytes (interrupted download), a text/HTML error page saved with a .bmp extension, or a 1-53 byte stub passed to insertBitmap().","commonSituations":"Interrupted uploads/downloads; proxies or antivirus replacing the file body; unit-test fixtures that are empty shells.","solutions":["Re-download or re-export the original BMP","Verify integrity (size and hash) before calling insertBitmap()","Convert to PNG/JPEG and use the Drawing API instead of raw Xls bitmaps"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const MIN_BMP_SIZE = 54; // 0x36: file header (14) + info header (40)\n\nif (!is_file($path) || filesize($path) < MIN_BMP_SIZE) {\n    throw new InvalidArgumentException(\"File too small to be a BMP: $path\");\n}\n$worksheetWriter->insertBitmap($row, $col, $path);","typeGuard":null,"tryCatchPattern":"try {\n    $worksheetWriter->insertBitmap($row, $col, $path);\n} catch (\\PhpOffice\\PhpSpreadsheet\\Writer\\Exception $e) {\n    if (str_contains($e->getMessage(), 'contain enough data')) {\n        error_log(\"Truncated bitmap rejected: $path\"); // re-fetch source image\n    }\n}","preventionTips":["Verify downloads completed (size and hash) before using files","Validate uploaded images with getimagesize(), which fails on truncated files","Keep original sources so truncated artifacts can be regenerated"],"tags":["phpspreadsheet","xls","bitmap","corrupt-file","image"],"backgroundTag":"corrupt-image-file","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}