{"record":{"id":"237fb7c416ae1802","repo":"Intervention/image","slug":"input-must-be-png-format","errorCode":null,"errorMessage":"Input must be PNG format","messagePattern":"Input must be PNG format","errorType":"exception","errorClass":"AnalyzerException","httpStatus":null,"severity":"info","filePath":"src/Drivers/Gd/Analyzers/ResolutionAnalyzer.php","lineNumber":188,"sourceCode":"            }\n\n            return $values[0] / $values[1];\n        }, $resolution);\n    }\n\n    /**\n     * @param resource $handle\n     * @throws AnalyzerException\n     * @return array<float>\n     */\n    private function resolutionFromPngPhys($handle): array\n    {\n        rewind($handle);\n        $signature = fread($handle, 8);\n\n        // no PNG content\n        if ($signature !== \"\\x89PNG\\x0D\\x0A\\x1A\\x0A\") {\n            throw new AnalyzerException('Input must be PNG format');\n        }\n\n        $marker = '';\n\n        while (!feof($handle)) {\n            $marker = strlen($marker) < 4 ? $marker . fread($handle, 1) : substr($marker, 1) . fread($handle, 1);\n\n            // find pHYs chunk\n            if ($marker === 'pHYs') {\n                // find length\n                fseek($handle, -8, SEEK_CUR);\n                $length = fread($handle, 4);\n                $length = unpack('N', $length)[1];\n                fseek($handle, 4, SEEK_CUR);\n\n                // pHYs chunk must be exactly 9 bytes\n                if ($length !== 9) {\n                    throw new AnalyzerException('Invalid pHYs chunk length');","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/Intervention/image/blob/5598b9e39751c34afc5cdee84abef77f92c26f68/src/Drivers/Gd/Analyzers/ResolutionAnalyzer.php#L170-L206","documentation":"The third resolution-recovery strategy reads the first 8 bytes of the origin stream and compares them against the exact PNG signature \\x89PNG\\x0D\\x0A\\x1A\\x0A. Any mismatch throws this AnalyzerException and ends the PNG branch. It is an internal precondition check — a non-PNG file simply cannot contain a pHYs chunk — and the exception is swallowed by the surrounding recovery chain.","triggerScenarios":"A JPEG, WebP, GIF, or arbitrary binary reaching resolutionFromPngPhys() after the JFIF and EXIF parsers both failed; files renamed to .png without being converted.","commonSituations":"Extension/mime mismatch uploads; recovery order placing PNG parsing last means every non-PNG origin without JFIF/EXIF density hits this path silently.","solutions":["No action needed: non-PNG origins are expected here and the analyzer falls back to 96 DPI","If you expected PNG data, verify the signature yourself: bin2hex(substr($data, 0, 8)) === '89504e470d0a1a0a'","Convert the file to real PNG before processing if pHYs density matters"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"$signature = (string) fread($handle, 8);\nrewind($handle);\n$isPng = $signature === \"\\x89PNG\\x0D\\x0A\\x1A\\x0A\";","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Verify magic bytes instead of trusting file extensions","Convert files to their claimed format before processing"],"tags":["gd","resolution","png","signature","internal"],"backgroundTag":"invalid-file-signature","analyzedSha":"5598b9e39751c34afc5cdee84abef77f92c26f68","analyzedAt":"2026-08-23T02:17:31.068Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}