{"record":{"id":"b7ad8903633a7bdc","repo":"gchq/CyberChef","slug":"invalid-plaintext-character-letter","errorCode":null,"errorMessage":"Invalid Plaintext character : ${letter}","messagePattern":"Invalid Plaintext character : (.+?)","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/Lorenz.mjs","lineNumber":519,"sourceCode":"     */\n    convertToITA2(input, intype, mode) {\n        let result = \"\";\n        let figShifted = false;\n\n        for (const character of input) {\n            const letter = character.toUpperCase();\n\n            // Convert input text to ITA2 (including figure/letter shifts)\n            if (intype === \"ITA2\" || mode === \"Receive\") {\n                if (validITA2.indexOf(letter) === -1) {\n                    let errltr = letter;\n                    if (errltr===\"\\n\") errltr = \"Carriage Return\";\n                    if (errltr===\" \") errltr = \"Space\";\n                    throw new OperationError(\"Invalid ITA2 character : \"+errltr);\n                }\n                result += letter;\n            } else {\n                if (validChars.indexOf(letter) === -1) throw new OperationError(\"Invalid Plaintext character : \"+letter);\n\n                if (!figShifted && figShiftedChars.indexOf(letter) !== -1) {\n                    // in letters mode and next char needs to be figure shifted\n                    figShifted = true;\n                    result += \"55\" + figShiftArr[letter];\n                } else if (figShifted) {\n                    // in figures mode and next char needs to be letter shifted\n                    if (letter===\"\\n\") {\n                        result += \"34\";\n                    } else if (letter===\"\\r\") {\n                        result += \"4\";\n                    } else if (figShiftedChars.indexOf(letter) === -1) {\n                        figShifted = false;\n                        result += \"88\" + letter;\n                    } else {\n                        result += figShiftArr[letter];\n                    }\n","sourceCodeStart":501,"sourceCodeEnd":537,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/Lorenz.mjs#L501-L537","documentation":"Thrown by the Lorenz SZ operation when, in plaintext Send mode (intype !== 'ITA2' and mode !== 'Receive'), an input character is not in the supported plaintext character set. Each character is upper-cased and looked up in validChars; a miss throws at Lorenz.mjs:519. The plaintext path then translates the character into ITA2, inserting figure/letter shifts as needed, so only characters it can encode are permitted.","triggerScenarios":"Running the Lorenz operation with 'Input Type'='Plaintext' and 'Mode'='Send' (the default encoding direction) while the input contains a character the operation cannot represent in ITA2 — e.g. extended Unicode, emojis, accented letters, or punctuation not in the supported set. Raised at Lorenz.mjs:519.","commonSituations":"Pasting rich text / Unicode (curly quotes, accented characters, emoji) into the plaintext field; expecting arbitrary ASCII punctuation to be encodable; feeding binary/garbage data through the plaintext path.","solutions":["Restrict input to the supported plaintext character set (basic A-Z, digits, and the punctuation symbols the operation encodes).","Pre-sanitise input: strip or transliterate unsupported characters (e.g. smart quotes to ASCII, remove emoji) before running.","If your data is already ITA2, switch 'Input Type' to 'ITA2' instead.","Check the operation description / wiki for the exact plaintext alphabet supported."],"exampleFix":"// before — unsupported Unicode in plaintext path\ninput = '“HELLO” — café ☕';\n\n// after — transliterate to supported plaintext\ninput = '\"HELLO\" - cafe';","handlingStrategy":"validation","validationCode":"// Approximate allow-list for the Lorenz plaintext path.\nconst VALID_PLAIN = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 .,?!:;\\'\"()-/+=&%#\\n';\nfunction onlyPlaintext(str) {\n  return [...str.toUpperCase()].every(c => VALID_PLAIN.includes(c));\n}\nif (intype !== 'ITA2' && mode !== 'Receive' && !onlyPlaintext(input)) {\n  throw new Error('Input has unsupported plaintext characters');\n}","typeGuard":"function isLorenzPlaintext(v: unknown): v is string {\n  if (typeof v !== 'string') return false;\n  const allowed = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 .,?!:;\\'\"()-/+=&%#\\n';\n  return [...v.toUpperCase()].every(c => allowed.includes(c));\n}","tryCatchPattern":null,"preventionTips":["Transliterate smart quotes, accents, and emoji to ASCII before the plaintext path.","If the data is already ITA2, switch Input Type to 'ITA2'.","Sanitise pasted rich text to plain ASCII first."],"tags":["lorenz","cipher","validation","plaintext","character-encoding"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}