From e7ec933cb8b8ebaeb82f89a3ffc34f290cdd7b02 Mon Sep 17 00:00:00 2001
From: Ralph Giles <giles@mozilla.com>
Date: Fri, 30 Nov 2012 18:00:38 -0800
Subject: [PATCH] Add a regression test for the padding issue.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This is a heavily modified version of the demonstration program
Jüri Aedla posted to the mailing list. Verified to pass with
the current commit, but fail with the tree from two commits ago.

http://lists.xiph.org/pipermail/opus/2012-November/001834.html
---
 Makefile.am               |  7 ++--
 tests/test_opus_padding.c | 67 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+), 2 deletions(-)
 create mode 100644 tests/test_opus_padding.c

diff --git a/Makefile.am b/Makefile.am
index bab9f6d87..cca953b5a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -28,9 +28,9 @@ pkginclude_HEADERS = include/opus.h include/opus_multistream.h include/opus_type
 
 noinst_HEADERS = $(OPUS_HEAD) $(SILK_HEAD) $(CELT_HEAD)
 
-noinst_PROGRAMS = opus_demo repacketizer_demo opus_compare tests/test_opus_api tests/test_opus_encode tests/test_opus_decode celt/tests/test_unit_cwrs32 celt/tests/test_unit_dft celt/tests/test_unit_entropy celt/tests/test_unit_laplace celt/tests/test_unit_mathops celt/tests/test_unit_mdct celt/tests/test_unit_rotation celt/tests/test_unit_types
+noinst_PROGRAMS = opus_demo repacketizer_demo opus_compare tests/test_opus_api tests/test_opus_encode tests/test_opus_decode tests/test_opus_padding celt/tests/test_unit_cwrs32 celt/tests/test_unit_dft celt/tests/test_unit_entropy celt/tests/test_unit_laplace celt/tests/test_unit_mathops celt/tests/test_unit_mdct celt/tests/test_unit_rotation celt/tests/test_unit_types
 
-TESTS = celt/tests/test_unit_types celt/tests/test_unit_mathops celt/tests/test_unit_entropy celt/tests/test_unit_laplace celt/tests/test_unit_dft celt/tests/test_unit_mdct celt/tests/test_unit_rotation celt/tests/test_unit_cwrs32 tests/test_opus_api tests/test_opus_decode tests/test_opus_encode
+TESTS = celt/tests/test_unit_types celt/tests/test_unit_mathops celt/tests/test_unit_entropy celt/tests/test_unit_laplace celt/tests/test_unit_dft celt/tests/test_unit_mdct celt/tests/test_unit_rotation celt/tests/test_unit_cwrs32 tests/test_opus_api tests/test_opus_decode tests/test_opus_encode tests/test_opus_padding
 
 opus_demo_SOURCES = src/opus_demo.c
 
@@ -52,6 +52,9 @@ tests_test_opus_encode_LDADD = libopus.la -lm
 tests_test_opus_decode_SOURCES = tests/test_opus_decode.c tests/test_opus_common.h
 tests_test_opus_decode_LDADD = libopus.la -lm
 
+tests_test_opus_padding_SOURCES = tests/test_opus_padding.c tests/test_opus_common.h
+tests_test_opus_padding_LDADD = libopus.la -lm
+
 celt_tests_test_unit_cwrs32_SOURCES = celt/tests/test_unit_cwrs32.c
 celt_tests_test_unit_cwrs32_LDADD = -lm
 
diff --git a/tests/test_opus_padding.c b/tests/test_opus_padding.c
new file mode 100644
index 000000000..c5efc2923
--- /dev/null
+++ b/tests/test_opus_padding.c
@@ -0,0 +1,67 @@
+/* Check for overflow in reading the padding length.
+ * Example by Jüri Aedla and Ralph Giles
+ * http://lists.xiph.org/pipermail/opus/2012-November/001834.html
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "opus.h"
+#include "test_opus_common.h"
+
+#define PACKETSIZE 16909318
+#define CHANNELS 2
+#define FRAMESIZE 5760
+
+int test_overflow(void)
+{
+  OpusDecoder *decoder;
+  int result;
+  int error;
+
+  unsigned char *in = malloc(PACKETSIZE);
+  opus_int16 *out = malloc(FRAMESIZE*CHANNELS*sizeof(*out));
+
+  fprintf(stderr, "  Checking for padding overflow... ");
+  if (!in || !out) {
+    fprintf(stderr, "FAIL (out of memory)\n");
+    return -1;
+  }
+  in[0] = 0xff;
+  in[1] = 0x41;
+  memset(in + 2, 0xff, PACKETSIZE - 3);
+  in[PACKETSIZE-1] = 0x0b;
+
+  decoder = opus_decoder_create(48000, CHANNELS, &error);
+  result = opus_decode(decoder, in, PACKETSIZE, out, FRAMESIZE, 0);
+  opus_decoder_destroy(decoder);
+
+  free(in);
+  free(out);
+
+  if (result != OPUS_INVALID_PACKET) {
+    fprintf(stderr, "FAIL!\n");
+    test_failed();
+  }
+
+  fprintf(stderr, "OK.\n");
+
+  return 1;
+}
+
+int main(void)
+{
+  const char *oversion;
+  int tests = 0;;
+
+  iseed = 0;
+  oversion = opus_get_version_string();
+  if (!oversion) test_failed();
+  fprintf(stderr, "Testing %s padding.\n", oversion);
+
+  tests += test_overflow();
+
+  fprintf(stderr, "All padding tests passed.\n");
+
+  return 0;
+}
-- 
GitLab