From 5d6d4b56dcf78f8bd919fcd455645c6c05de98ba Mon Sep 17 00:00:00 2001
From: John Thacker <johnthacker@gmail.com>
Date: Fri, 3 Apr 2026 13:33:52 +0000
Subject: [PATCH] iLBC codec: Report proper decoded length in multiframe case

Per RFC 3952, multiple iLBC frames can may be included in a single
RTP packet.[1] (Note the error there about octets per frame in the
20 ms case, contradicting sections 2 and 3.1; errata has been
submitted.) The output length needs to be sized to accommodate the
full length, as the iLBC library decodes all the frames.

1 - https://datatracker.ietf.org/doc/html/rfc3952#section-3.2

Fix #21145

AI-Assisted: no


(cherry picked from commit 7a284824c92fecc6c57d770317919388c33983ac)

Co-authored-by: John Thacker <johnthacker@gmail.com>
---
 plugins/codecs/iLBC/iLBCdecode.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

Index: wireshark-3.6.24/plugins/codecs/iLBC/iLBCdecode.c
===================================================================
--- wireshark-3.6.24.orig/plugins/codecs/iLBC/iLBCdecode.c
+++ wireshark-3.6.24/plugins/codecs/iLBC/iLBCdecode.c
@@ -1,6 +1,8 @@
 /* iLBCdecode.c
  * iLBC codec
  *
+ * https://datatracker.ietf.org/doc/html/rfc3952
+ *
  * Wireshark - Network traffic analyzer
  * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1998 Gerald Combs
@@ -77,16 +79,24 @@ codec_iLBC_decode(void *ctx, const void
 #endif
     int16_t *dataOut = (int16_t *)outputSamples;
     ilbc_ctx_t *dataCtx = (ilbc_ctx_t *)ctx;
-    size_t outputSamplesCount;
+    size_t outputSamplesCount, outputFramesCount;
 
     if (!outputSamples || !outputSamplesSize)
     {
+        /* XXX - If the payload size is a multiple of 950 (the GCM of the
+         * 20 ms and 30 ms payload lengths), we don't know which variant it
+         * is and the iLBC library doesn't seem to autodetect but uses what
+         * we initialize as. RFC 3952 3.2 is of no help here, suggesting
+         * only this algorithm.
+         * Do we need a codec preference? */
         if (0 == inputBytesSize%ILBC_PAYLOAD_LEN_20MS) {
             /* 20ms packet size = 160 samples = 320 bytes */
-            return BLOCKL_20MS*SAMPLE_SIZE;
+            outputFramesCount = inputBytesSize / ILBC_PAYLOAD_LEN_20MS;
+            return outputFramesCount*BLOCKL_20MS*SAMPLE_SIZE;
         } else if (0 == inputBytesSize%ILBC_PAYLOAD_LEN_30MS) {
             /* 30ms packet size = 240 samples = 480 bytes */
-            return BLOCKL_30MS*SAMPLE_SIZE;
+            outputFramesCount = inputBytesSize / ILBC_PAYLOAD_LEN_30MS;
+            return outputFramesCount*BLOCKL_30MS*SAMPLE_SIZE;
         } else {
             /* unknown packet size */
             return 0;
