{"record":{"id":"570f6fbd5da4f278","repo":"gchq/CyberChef","slug":"end-of-input-reached-before-end-of-script","errorCode":null,"errorMessage":"End of input reached before end of script","messagePattern":"End of input reached before end of script","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/PHPDeserialize.mjs","lineNumber":57,"sourceCode":"     * @returns {string}\n     */\n    run(input, args) {\n        /**\n         * Recursive method for deserializing.\n         * @returns {*}\n         */\n        function handleInput() {\n            /**\n             * Read `length` characters from the input, shifting them out the input.\n             * @param length\n             * @returns {string}\n             */\n            function read(length) {\n                let result = \"\";\n                for (let idx = 0; idx < length; idx++) {\n                    const char = inputPart.shift();\n                    if (char === undefined) {\n                        throw new OperationError(\"End of input reached before end of script\");\n                    }\n                    result += char;\n                }\n                return result;\n            }\n\n            /**\n             * Read characters from the input until `until` is found.\n             * @param until\n             * @returns {string}\n             */\n            function readUntil(until) {\n                let result = \"\";\n                for (;;) {\n                    const char = read(1);\n                    if (char === until) {\n                        break;\n                    } else {","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/PHPDeserialize.mjs#L39-L75","documentation":"The PHP deserialization parser's read() function shifts characters one-by-one from the input array. When shift() returns undefined before the requested length is consumed, the serialized string is truncated — the format declares more data than is present.","triggerScenarios":"A serialized string's length marker exceeds the available content (e.g., s:5:\"ab\"; claims 5 bytes but only 2 remain). An array declaration says a:3:{...} but the input ends before all key/value pairs are read. Any truncation mid-element due to copy-paste or encoding conversion that altered byte counts.","commonSituations":"Copy-pasting a serialized string and accidentally cutting it short. Encoding conversion (UTF-8 to Latin1) that changes multibyte character counts so the byte-length markers no longer match. Database extraction that truncated a serialized BLOB.","solutions":["Provide the complete, untruncated serialized string","Check that string length markers (e.g., s:N:\"...\") match the actual byte length of the content, accounting for multibyte characters","If the data came from a database or API, verify it was not truncated during extraction"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Pre-check: rough structural validation of PHP serialized data\nfunction looksLikePhpSerialized(s) {\n  return /^[nidbas]:/.test(s.trim());\n}\nif (!looksLikePhpSerialized(input)) {\n  throw new Error(\"Input does not start with a valid PHP serialization type marker.\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  const result = chef.phpDeserialize(input, [true]);\n} catch (e) {\n  if (/End of input/i.test(e.message)) {\n    console.error(\"Serialized data is truncated — provide the complete string\");\n  } else { throw e; }\n}","preventionTips":["Ensure the full serialized string is provided without truncation","Account for multibyte characters when verifying string length markers","If extracting from a database, verify the BLOB was not truncated"],"tags":["php","deserialization","parsing","data-integrity"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}