{"record":{"id":"d6fd2de3a8c88815","repo":"mozilla/pdf.js","slug":"invalid-acn-encoding","errorCode":null,"errorMessage":"invalid ACn encoding","messagePattern":"invalid ACn encoding","errorType":"exception","errorClass":"JpegError","httpStatus":null,"severity":"error","filePath":"src/core/jpg.js","lineNumber":317,"sourceCode":"    while (k <= e) {\n      const offsetZ = blockOffset + dctZigZag[k];\n      const sign = component.blockData[offsetZ] < 0 ? -1 : 1;\n      switch (successiveACState) {\n        case 0: // initial state\n          rs = decodeHuffman(component.huffmanTableAC);\n          s = rs & 15;\n          r = rs >> 4;\n          if (s === 0) {\n            if (r < 15) {\n              eobrun = receive(r) + (1 << r);\n              successiveACState = 4;\n            } else {\n              r = 16;\n              successiveACState = 1;\n            }\n          } else {\n            if (s !== 1) {\n              throw new JpegError(\"invalid ACn encoding\");\n            }\n            successiveACNextValue = receiveAndExtend(s);\n            successiveACState = r ? 2 : 3;\n          }\n          continue;\n        case 1: // skipping r zero items\n        case 2:\n          if (component.blockData[offsetZ]) {\n            component.blockData[offsetZ] += sign * (readBit() << successive);\n          } else {\n            r--;\n            if (r === 0) {\n              successiveACState = successiveACState === 2 ? 3 : 0;\n            }\n          }\n          break;\n        case 3: // set value for a zero item\n          if (component.blockData[offsetZ]) {","sourceCodeStart":299,"sourceCodeEnd":335,"githubUrl":"https://github.com/mozilla/pdf.js/blob/5903d58d58e4dd9ce6ffa3834aea8480f06b4ada/src/core/jpg.js#L299-L335","documentation":"Thrown inside decodeACSuccessive() during progressive JPEG successive-approximation AC refinement. After Huffman-decoding an AC symbol, the category nibble s must be 0 (EOB/run) or 1 (single refinement bit); any value 2-15 is illegal for successive refinement and triggers this error. It enforces a constraint from ITU-T T.81 section G.1.1.2.","triggerScenarios":"Fires only for progressive JPEGs (SOF2, 0xFFC2) during a successive-approximation AC scan, when the decoded AC Huffman symbol's low nibble (s) is greater than 1 while not in an EOB-run state. The condition `s !== 1` inside the `else` branch of state 0 is the exact guard.","commonSituations":"A progressively-encoded JPEG produced by a buggy or non-standard encoder, or scan data corrupted after the first (DC) pass. Often seen in PDFs that re-encode images with custom progressive pipelines or in images damaged by copy/transport.","solutions":["Decode the JPEG with a reference decoder (libjpeg-turbo) to confirm the progressive scan data is malformed.","If you control encoding, ensure successive AC refinement scans only emit category 0/1 symbols.","If the PDF is untrusted/legacy, wrap the parse+getData call in a try/catch on JpegError and fall back to a placeholder or the native browser decoder."],"exampleFix":"// before\njpegImg.parse(data);\nconst out = jpegImg.getData({ width: jpegImg.width, height: jpegImg.height });\n\n// after\ntry {\n  jpegImg.parse(data);\n  out = jpegImg.getData({ width: jpegImg.width, height: jpegImg.height });\n} catch (e) {\n  if (e.name === 'JpegError') { out = null; }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  jpegImg.parse(data);\n  out = jpegImg.getData({ width: jpegImg.width, height: jpegImg.height });\n} catch (e) {\n  if (e.name === 'JpegError') { out = null; }\n  throw e;\n}","preventionTips":["When generating progressive JPEGs, use a mature encoder (libjpeg-turbo/mozjpeg) to guarantee spec-compliant successive-approximation scans.","Validate progressive JPEGs with a reference decoder before embedding in PDFs.","Catch JpegError at the image-render boundary and substitute a placeholder."],"tags":["jpeg","progressive-jpeg","image-decoding","corrupt-data"],"backgroundTag":null,"analyzedSha":"5903d58d58e4dd9ce6ffa3834aea8480f06b4ada","analyzedAt":"2026-08-13T02:28:27.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}