{"record":{"id":"8a95e8839004a7ff","repo":"Intervention/image","slug":"invalid-phys-chunk-length","errorCode":null,"errorMessage":"Invalid pHYs chunk length","messagePattern":"Invalid pHYs chunk length","errorType":"exception","errorClass":"AnalyzerException","httpStatus":null,"severity":"warning","filePath":"src/Drivers/Gd/Analyzers/ResolutionAnalyzer.php","lineNumber":206,"sourceCode":"            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');\n                }\n\n                // read data\n                $data = fread($handle, $length);\n\n                $x = unpack('N', substr($data, 0, 4))[1];\n                $y = unpack('N', substr($data, 4, 4))[1];\n                $unit = ord(substr($data, 8, 1));\n\n                // unit=1 means pixels per metre → convert to DPI\n                // unit=0 means unknown unit (just a ratio) → return raw values\n                if ($unit === 1) {\n                    return [\n                        round($x * .0254),\n                        round($y * .0254),\n                    ];\n                }\n","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/Intervention/image/blob/5598b9e39751c34afc5cdee84abef77f92c26f68/src/Drivers/Gd/Analyzers/ResolutionAnalyzer.php#L188-L224","documentation":"After locating the pHYs chunk in a PNG, the parser reads the chunk's big-endian length field and requires exactly 9 bytes (4 for X pixels-per-unit, 4 for Y, 1 for unit). Any other length means the chunk is malformed and its 9-byte fixed layout cannot be trusted, so parsing aborts. The surrounding recovery chain catches this; through resolution() it degrades to the default fallback.","triggerScenarios":"A PNG whose pHYs chunk has a length other than 9 (bit-corrupted file, chunk splicing bug in a compression tool, deliberately malformed test file).","commonSituations":"Files corrupted in transit or storage; PNGs rewritten by non-conformant optimizers; fuzzing corpora.","solutions":["Validate/re-encode the PNG: pngcheck file.png, then re-save with a conformant encoder","If the file must keep its (broken) chunk, call setResolution() manually and skip origin recovery","Reject structurally invalid uploads at ingest with pngcheck or a strict decoder before handing them to the library"],"exampleFix":"# verify and repair\npngcheck -v broken.png   # reports: pHYs: invalid chunk length\nconvert broken.png fixed.png  # re-encode with clean chunks","handlingStrategy":"validation","validationCode":"// run pngcheck or a strict decoder before processing\nexec('pngcheck -q ' . escapeshellarg($path), $out, $code);\n$pngStructurallyValid = $code === 0;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate PNG structure at ingest with pngcheck or imagecreatefrompng + getimagesize","Re-encode user PNGs through a conformant encoder before resolution-sensitive processing"],"tags":["gd","resolution","png","phys-chunk","corrupt-file"],"backgroundTag":"corrupt-png-chunk","analyzedSha":"5598b9e39751c34afc5cdee84abef77f92c26f68","analyzedAt":"2026-08-23T02:17:31.068Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}