{"record":{"id":"3f8313c1e4ac700a","repo":"DrKLO/Telegram","slug":"invalid-initialization-data-size","errorCode":null,"errorMessage":"Invalid initialization data size","messagePattern":"Invalid initialization data size","errorType":"exception","errorClass":"OpusDecoderException","httpStatus":null,"severity":"error","filePath":"TMessagesProj/src/main/java/com/google/android/exoplayer2/ext/opus/OpusDecoder.java","lineNumber":93,"sourceCode":"  public OpusDecoder(\n      int numInputBuffers,\n      int numOutputBuffers,\n      int initialInputBufferSize,\n      List<byte[]> initializationData,\n      @Nullable CryptoConfig cryptoConfig,\n      boolean outputFloat)\n      throws OpusDecoderException {\n    super(new DecoderInputBuffer[numInputBuffers], new SimpleDecoderOutputBuffer[numOutputBuffers]);\n    if (!OpusLibrary.isAvailable()) {\n      throw new OpusDecoderException(\"Failed to load decoder native libraries\");\n    }\n    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);","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/DrKLO/Telegram/blob/45ab8f4308496e1f01026a97fcdb0d58a5274474/TMessagesProj/src/main/java/com/google/android/exoplayer2/ext/opus/OpusDecoder.java#L75-L111","documentation":"The OpusDecoder constructor requires the codec initializationData list to hold exactly 1 element (just the Opus identification header) or exactly 3 elements (header plus two 8-byte buffers for codec delay and seek pre-roll, the layout produced by ExoPlayer's Opus extractor). Any other size is treated as malformed codec private data and rejected before any header bytes are read.","triggerScenarios":"Constructing OpusDecoder with a Format whose initializationData was populated with the wrong number of buffers - a hand-built Format, a buggy custom extractor, or a file that is not genuinely Opus being fed to the Opus renderer.","commonSituations":"Unit tests that build a Format manually and forget the extra buffers; a demuxer that emits 2 or 4 buffers; media mislabeled as audio/opus; partial container corruption that makes the extractor emit no header buffer.","solutions":["Let ExoPlayer's built-in Opus extractor (Ogg/Opus or Matroska/Opus) populate initializationData rather than building the list by hand.","Ensure initializationData is exactly Collections.singletonList(header) or [header, codecDelay(8 bytes), seekPreRoll(8 bytes)].","Validate the source is a real Opus stream before routing it to LibopusAudioRenderer."],"exampleFix":"// before\nList<byte[]> init = new ArrayList<>();\ninit.add(header);\ninit.add(codecDelayShort); // wrong size -> forces 2-element list\nnew OpusDecoder(..., init, ...);\n\n// after - either 1 header, or header + two 8-byte longs\nList<byte[]> init = Collections.singletonList(header);\n// or: Arrays.asList(header, longToBytes(codecDelayNs), longToBytes(seekPreRollNs));\nnew OpusDecoder(..., init, ...);","handlingStrategy":"validation","validationCode":"List<byte[]> init = format.initializationData;\nif (init == null || (init.size() != 1 && init.size() != 3)) {\n  throw new IllegalArgumentException(\n      \"Opus initializationData must have 1 or 3 buffers, got \" + (init == null ? 0 : init.size()));\n}\nnew OpusDecoder(NUM_BUFFERS, NUM_BUFFERS, initSize, init, cryptoConfig, outputFloat);","typeGuard":null,"tryCatchPattern":"try {\n  new OpusDecoder(..., format.initializationData, cryptoConfig, outputFloat);\n} catch (OpusDecoderException e) {\n  if (e.getMessage().startsWith(\"Invalid initialization data size\")) {\n    // mark format unsupported / re-extract\n  } else { throw e; }\n}","preventionTips":["Always let the Opus extractor populate Format.initializationData.","Never hand-build an Opus Format with arbitrary initializationData.","In tests, use real Opus header bytes or fixtures copied from a real stream."],"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"}