{"record":{"id":"9600a03188047bce","repo":"DrKLO/Telegram","slug":"invalid-header-length","errorCode":null,"errorMessage":"Invalid header length","messagePattern":"Invalid header length","errorType":"exception","errorClass":"OpusDecoderException","httpStatus":null,"severity":"error","filePath":"TMessagesProj/src/main/java/com/google/android/exoplayer2/ext/opus/OpusDecoder.java","lineNumber":105,"sourceCode":"    this.cryptoConfig = cryptoConfig;\n    if (cryptoConfig != null && !OpusLibrary.opusIsSecureDecodeSupported()) {\n      throw new OpusDecoderException(\"Opus decoder does not support secure decode\");\n    }\n    int initializationDataSize = initializationData.size();\n    if (initializationDataSize != 1 && initializationDataSize != 3) {\n      throw new OpusDecoderException(\"Invalid initialization data size\");\n    }\n    if (initializationDataSize == 3\n        && (initializationData.get(1).length != 8 || initializationData.get(2).length != 8)) {\n      throw new OpusDecoderException(\"Invalid pre-skip or seek pre-roll\");\n    }\n    preSkipSamples = getPreSkipSamples(initializationData);\n    seekPreRollSamples = getSeekPreRollSamples(initializationData);\n    skipSamples = preSkipSamples;\n\n    byte[] headerBytes = initializationData.get(0);\n    if (headerBytes.length < 19) {\n      throw new OpusDecoderException(\"Invalid header length\");\n    }\n    channelCount = getChannelCount(headerBytes);\n    if (channelCount > 8) {\n      throw new OpusDecoderException(\"Invalid channel count: \" + channelCount);\n    }\n    int gain = readSignedLittleEndian16(headerBytes, 16);\n\n    byte[] streamMap = new byte[8];\n    int numStreams;\n    int numCoupled;\n    if (headerBytes[18] == 0) { // Channel mapping\n      // If there is no channel mapping, use the defaults.\n      if (channelCount > 2) { // Maximum channel count with default layout.\n        throw new OpusDecoderException(\"Invalid header, missing stream map\");\n      }\n      numStreams = 1;\n      numCoupled = (channelCount == 2) ? 1 : 0;\n      streamMap[0] = 0;","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/DrKLO/Telegram/blob/45ab8f4308496e1f01026a97fcdb0d58a5274474/TMessagesProj/src/main/java/com/google/android/exoplayer2/ext/opus/OpusDecoder.java#L87-L123","documentation":"The Opus identification header (initializationData.get(0)) must be at least 19 bytes: RFC 7845 defines the fixed header fields (magic, version, channels, pre-skip, sample rate, gain, channel mapping family) ending at byte index 18. If headerBytes.length < 19 the header is truncated and the decoder refuses to parse channel/gain/mapping fields that follow.","triggerScenarios":"A truncated or corrupted Opus identification header extracted from a damaged Ogg/Opus or Matroska file, or a header buffer that was clipped during demuxing.","commonSituations":"Damaged downloads, partial files, a demuxer bug that returns a short buffer, or test content with a stub header.","solutions":["Re-extract the stream from a known-good Opus source so the full identification header is delivered.","Validate headerBytes.length >= 19 before constructing the decoder and reject the Format early with a clearer error."],"exampleFix":"// before\nbyte[] header = format.initializationData.get(0); // possibly < 19 bytes\nnew OpusDecoder(..., format.initializationData, ...);\n\n// after\nbyte[] header = format.initializationData.get(0);\nif (header.length < 19) {\n  throw new OpusDecoderException(\"Truncated Opus header: \" + header.length);\n}\nnew OpusDecoder(..., format.initializationData, ...);","handlingStrategy":"validation","validationCode":"byte[] header = format.initializationData.get(0);\nif (header == null || header.length < 19) {\n  throw new IllegalArgumentException(\"Opus identification header must be >= 19 bytes\");\n}\nnew OpusDecoder(NUM_BUFFERS, NUM_BUFFERS, initSize, format.initializationData, cryptoConfig, outputFloat);","typeGuard":null,"tryCatchPattern":"try {\n  new OpusDecoder(..., format.initializationData, cryptoConfig, outputFloat);\n} catch (OpusDecoderException e) {\n  if (e.getMessage().equals(\"Invalid header length\")) {\n    // header truncated: reject format / re-extract\n  } else { throw e; }\n}","preventionTips":["Reject Opus formats whose header is shorter than 19 bytes before decoding.","Re-extract from a known-good source when the header looks truncated."],"tags":["opus","decoder","format-validation","exoplayer","audio"],"backgroundTag":null,"analyzedSha":"45ab8f4308496e1f01026a97fcdb0d58a5274474","analyzedAt":"2026-08-14T05:19:30.815Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}