Describe the bug
ciphers/xor_cipher.ts::XORCipher skips line-terminator characters, leaving them un-encrypted. It applies the cipher with str.replace(/./g, ...), but in JavaScript . (without the s / dotAll flag) does not match line terminators — \n (U+000A), \r (U+000D),
,
. Those characters are passed through unchanged instead of being XORed with the key.
export const XORCipher = (str: string, key: number): string =>
str.replace(/./g, (char: string) =>
String.fromCharCode(char.charCodeAt(0) ^ key)
)
The docstring says "Each character is bitwise XORed with the key … We loop through the input string, XORing each character", but newline-class characters are not XORed.
To Reproduce
const enc = XORCipher("A\nB", 1)
// input char codes: [65, 10, 66]
// enc char codes: [64, 10, 67] <- 10 (\n) should be 11 (10 ^ 1)
The 'A' (65→64) and 'B' (66→67) are XORed, but '\n' (10) stays 10 instead of becoming 11.
Expected behavior
Every character — including \n, \r,
,
— is XORed with the key, so XORCipher("A\nB", 1) yields char codes [64, 11, 67].
Actual behavior
Line-terminator characters are left unchanged, so the "encrypted" output still contains the original newlines (an information leak, and the output is not a correct XOR of the input).
Suggested fix
Don't rely on the dot-matches-everything assumption. Either add the dotAll flag (/./gs) or, more robustly, map over code points directly:
export const XORCipher = (str: string, key: number): string =>
Array.from(str, (char) => String.fromCharCode(char.charCodeAt(0) ^ key)).join('')
(The Array.from form also avoids the regex entirely.)
Describe the bug
ciphers/xor_cipher.ts::XORCipherskips line-terminator characters, leaving them un-encrypted. It applies the cipher withstr.replace(/./g, ...), but in JavaScript.(without thes/ dotAll flag) does not match line terminators —\n(U+000A),\r(U+000D),,. Those characters are passed through unchanged instead of being XORed with the key.The docstring says "Each character is bitwise XORed with the key … We loop through the input string, XORing each character", but newline-class characters are not XORed.
To Reproduce
The
'A'(65→64) and'B'(66→67) are XORed, but'\n'(10) stays 10 instead of becoming 11.Expected behavior
Every character — including
\n,\r,,— is XORed with the key, soXORCipher("A\nB", 1)yields char codes[64, 11, 67].Actual behavior
Line-terminator characters are left unchanged, so the "encrypted" output still contains the original newlines (an information leak, and the output is not a correct XOR of the input).
Suggested fix
Don't rely on the dot-matches-everything assumption. Either add the dotAll flag (
/./gs) or, more robustly, map over code points directly:(The
Array.fromform also avoids the regex entirely.)