{"record":{"id":"598daaa060e4f12b","repo":"PHPOffice/PhpSpreadsheet","slug":"unsupported-numeric-binary-operation","errorCode":null,"errorMessage":"Unsupported numeric binary operation","messagePattern":"Unsupported numeric binary operation","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Calculation\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Calculation/Calculation.php","lineNumber":2660,"sourceCode":"                case '/':\n                    if ($operand2 == 0) {\n                        //    Trap for Divide by Zero error\n                        $stack->push('Error', ExcelError::DIV0());\n                        $this->debugLog->writeDebugLog('Evaluation Result is %s', $this->showTypeDetails(ExcelError::DIV0()));\n\n                        return false;\n                    }\n                    $result = $operand1 / $operand2;\n\n                    break;\n                //    Power\n                case '^':\n                    $result = $operand1 ** $operand2;\n\n                    break;\n\n                default:\n                    throw new Exception('Unsupported numeric binary operation');\n            }\n        }\n\n        //    Log the result details\n        $this->debugLog->writeDebugLog('Evaluation Result is %s', $this->showTypeDetails($result));\n        //    And push the result onto the stack\n        $stack->push('Value', $result);\n\n        return $result;\n    }\n\n    /**\n     * Trigger an error, but nicely, if need be.\n     *\n     * @return false\n     */\n    protected function raiseFormulaError(string $errorMessage, int $code = 0, ?Throwable $exception = null): bool\n    {","sourceCodeStart":2642,"sourceCodeEnd":2678,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Calculation/Calculation.php#L2642-L2678","documentation":"Before doing any encoding detection, XmlScanner::findCharSet() checks whether the payload begins with the bytes \\x4c\\x6f\\xa7\\x94, which are '<?xm' in EBCDIC (code page 037/1027 family). An XML file that starts this way is an EBCDIC-encoded document, typically transferred straight from a mainframe; libxml cannot parse it and the scanner blocks it immediately with 'EBCDIC encoding not permitted' at XmlScanner.php:68.","triggerScenarios":"Calling IOFactory::load() or scanFile() on a file that was encoded in EBCDIC (e.g. CCSID 037/500/1026 on z/OS or AS/400) and copied or FTP'd in binary mode without ASCII conversion. The first four bytes match the EBCDIC '<?xm' magic and the exception fires before BOM or declaration sniffing even runs.","commonSituations":"Feeds or reports generated on IBM mainframes (z/OS) or IBM i and transferred in binary; SFTP/managed-file-transfer pipelines that skip encoding translation; archives where the file was never converted after leaving the host system.","solutions":["Convert the file from EBCDIC to UTF-8 before loading: iconv -f CP037 -t UTF-8 input.xml > input.utf8.xml (pick the CCSID that matches the source system).","Re-transfer the file from the host in ASCII/text mode, or have the generating job emit ASCII/UTF-8 directly.","If your pipeline routinely receives such files, add an upload gate that checks the first 4 bytes and auto-converts (or rejects) before the reader sees them.","Confirm the correct EBCDIC code page (037 vs 1026 vs 500) by round-tripping a known snippet, since national characters differ between pages."],"exampleFix":"// before\n$spreadsheet = \\PhpOffice\\PhpSpreadsheet\\IOFactory::load('mainframe-report.xml');\n// throws: EBCDIC encoding not permitted (starts with \\x4c\\x6f\\xa7\\x94)\n\n// after - convert EBCDIC (CP037) to UTF-8 before loading\n$xml = file_get_contents('mainframe-report.xml');\nif (str_starts_with($xml, \"\\x4c\\x6f\\xa7\\x94\")) {\n    $xml = mb_convert_encoding($xml, 'UTF-8', 'CP037');\n}\n$tmp = tempnam(sys_get_temp_dir(), 'xlsx');\nfile_put_contents($tmp, $xml);\n$spreadsheet = \\PhpOffice\\PhpSpreadsheet\\IOFactory::load($tmp);","handlingStrategy":"validation","validationCode":"// Detect and (optionally) convert EBCDIC before loading\nfunction normalizeEbcdic(string $path): string\n{\n    $raw = (string) file_get_contents($path);\n    if (str_starts_with($raw, \"\\x4c\\x6f\\xa7\\x94\")) { // EBCDIC '<?xm'\n        $raw = mb_convert_encoding($raw, 'UTF-8', 'CP037'); // adjust CCSID if needed\n    }\n    return $raw;\n}\n\n$clean = normalizeEbcdic($path);\n$tmp = tempnam(sys_get_temp_dir(), 'xlsx');\nfile_put_contents($tmp, $clean);\n$spreadsheet = \\PhpOffice\\PhpSpreadsheet\\IOFactory::load($tmp);","typeGuard":null,"tryCatchPattern":"use PhpOffice\\PhpSpreadsheet\\Reader\\Exception as ReaderException;\n\ntry {\n    $spreadsheet = \\PhpOffice\\PhpSpreadsheet\\IOFactory::load($path);\n} catch (ReaderException $e) {\n    if (str_contains($e->getMessage(), 'EBCDIC')) {\n        // re-request the file in ASCII/UTF-8 from the source system, or convert via iconv -f CP037\n    }\n    throw $e;\n}","preventionTips":["Configure mainframe/IBM i transfers to emit ASCII or UTF-8 (FTP ASCII mode, or CCSID conversion in the generating job).","Check the first four bytes of inbound partner feeds (\\x4c\\x6f\\xa7\\x94) and convert before ingestion.","Pin the correct EBCDIC code page in your conversion (037 vs 1026 vs 500) and verify national characters round-trip.","Document expected encodings per upstream source so mismatches surface as pipeline errors, not reader exceptions."],"tags":["php","phpspreadsheet","xml","ebcdic","character-encoding","mainframe","file-upload"],"backgroundTag":"unsupported-character-encoding","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}