{"record":{"id":"860f0ddc7eb60214","repo":"gchq/CyberChef","slug":"caught-in-probable-infinite-loop-while-parsing-huf","errorCode":null,"errorMessage":"Caught in probable infinite loop while parsing Huffman Block","messagePattern":"Caught in probable infinite loop while parsing Huffman Block","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/core/lib/FileSignatures.mjs","lineNumber":3928,"sourceCode":"/**\n * Parses a Huffman Block given the literal and distance tables\n *\n * @param {Stream} stream\n * @param {Uint32Array} litTab\n * @param {Uint32Array} distTab\n */\nfunction parseHuffmanBlock(stream, litTab, distTab) {\n    let code;\n    let loops = 0;\n    while ((code = readHuffmanCode(stream, litTab))) {\n        // console.log(\"Code: \" + code + \" (\" + Utils.chr(code) + \") \" + Utils.bin(code));\n\n        // End of block\n        if (code === 256) break;\n\n        // Detect probably infinite loops\n        if (++loops > 10000)\n            throw new Error(\"Caught in probable infinite loop while parsing Huffman Block\");\n\n        // Literal\n        if (code < 256) continue;\n\n        // Length code\n        stream.readBits(lengthExtraTable[code - 257], \"le\");\n\n        // Dist code\n        code = readHuffmanCode(stream, distTab);\n        stream.readBits(distanceExtraTable[code], \"le\");\n    }\n}\n\n\n/**\n * Builds a Huffman table given the relevant code lengths\n *\n * @param {Array} lengths","sourceCodeStart":3910,"sourceCodeEnd":3946,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/lib/FileSignatures.mjs#L3910-L3946","documentation":"A safety valve in parseHuffmanBlock. A valid DEFLATE Huffman block terminates when code 256 (end-of-block) is read; the loop counts iterations and throws a plain Error after 10000 codes without termination. It guards against malformed streams that would otherwise spin the parser indefinitely.","triggerScenarios":"Corrupted Huffman tables or scan data that emits literal codes forever; a malformed dynamic block whose end-of-block code can never be matched; crafted input designed to loop the parser (potential DoS vector).","commonSituations":"Bit-flipped compressed payload inside PNG/ZIP/GZIP; truncated table that mis-aligns subsequent reads; adversarial/crafted file fed to the extractor.","solutions":["Re-verify the compressed source integrity (CRC/check the container).","Cross-check with a canonical inflate implementation (Node zlib) to see if the stream is valid at all.","Discard the malformed input rather than attempting recovery."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  extractDeflate(bytes, offset);\n} catch (err) {\n  if (/probable infinite loop/.test(err.message)) {\n    // corrupt Huffman stream; abandon this input\n  } else throw err;\n}","preventionTips":["Verify compressed-payload integrity (container CRC) before deep parsing.","Cross-check with a reference inflate; if it rejects the stream, do not feed this parser.","Treat the 10000-iteration guard as a corruption signal, not a recoverable state."],"tags":["deflate","huffman","dos-guard","corruption","file-signatures"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}