ref: cae4445fb7f9bae2e2f318969e1f779729f3c0d1
parent: 65f11d326db773b2353d5066fd6b9191e9b3df81
author: Andrew Allen <bitllama@google.com>
date: Mon Dec 4 11:05:57 EST 2017
Ensure mapping matrix size is always valid. Signed-off-by: Jean-Marc Valin <jmvalin@jmvalin.ca>
--- a/src/mapping_matrix.c
+++ b/src/mapping_matrix.c
@@ -39,9 +39,21 @@
#define MATRIX_INDEX(nb_rows, row, col) (nb_rows * col + row)
-int mapping_matrix_get_size(int rows, int cols)
+opus_int32 mapping_matrix_get_size(int rows, int cols)
{
- return align(sizeof(MappingMatrix)) + align(rows * cols * sizeof(opus_int16));
+ opus_int32 size;
+
+ /* Mapping Matrix must only support up to 255 channels in or out.
+ * Additionally, the total cell count must be <= 65004 octets in order
+ * for the matrix to be stored in an OGG header.
+ */
+ if (rows > 255 || cols > 255)
+ return 0;
+ size = rows * (opus_int32)cols * sizeof(opus_int16);
+ if (size > 65004)
+ return 0;
+
+ return align(sizeof(MappingMatrix)) + align(size);
}
opus_int16 *mapping_matrix_get_data(const MappingMatrix *matrix)
--- a/src/mapping_matrix.h
+++ b/src/mapping_matrix.h
@@ -50,7 +50,7 @@
/* Matrix cell data goes here using col-wise ordering. */
} MappingMatrix;
-int mapping_matrix_get_size(int rows, int cols);
+opus_int32 mapping_matrix_get_size(int rows, int cols);
opus_int16 *mapping_matrix_get_data(const MappingMatrix *matrix);
--- a/src/opus_projection_decoder.c
+++ b/src/opus_projection_decoder.c
@@ -110,6 +110,9 @@
matrix_size =
mapping_matrix_get_size(streams + coupled_streams, channels);
+ if (!matrix_size)
+ return 0;
+
decoder_size = opus_multistream_decoder_get_size(streams, coupled_streams);
if (!decoder_size)
return 0;
@@ -147,7 +150,14 @@
}
/* Assign demixing matrix. */
- st->demixing_matrix_size_in_bytes = mapping_matrix_get_size(channels, nb_input_streams);
+ st->demixing_matrix_size_in_bytes =
+ mapping_matrix_get_size(channels, nb_input_streams);
+ if (!st->demixing_matrix_size_in_bytes)
+ {
+ RESTORE_STACK;
+ return OPUS_BAD_ARG;
+ }
+
mapping_matrix_init(get_demixing_matrix(st), channels, nb_input_streams, 0,
buf, demixing_matrix_size);
--- a/src/opus_projection_encoder.c
+++ b/src/opus_projection_encoder.c
@@ -150,6 +150,9 @@
matrix_rows = order_plus_one * order_plus_one + 2;
matrix_size = mapping_matrix_get_size(matrix_rows, matrix_rows);
+ if (!matrix_size)
+ return 0;
+
encoder_size =
opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams);
if (!encoder_size)
@@ -210,6 +213,8 @@
}
st->mixing_matrix_size_in_bytes = mapping_matrix_get_size(
mixing_matrix->rows, mixing_matrix->cols);
+ if (!st->mixing_matrix_size_in_bytes)
+ return OPUS_BAD_ARG;
/* Assign demixing matrix based on available pre-computed matrices. */
demixing_matrix = get_demixing_matrix(st);
@@ -233,6 +238,8 @@
}
st->demixing_matrix_size_in_bytes = mapping_matrix_get_size(
demixing_matrix->rows, demixing_matrix->cols);
+ if (!st->demixing_matrix_size_in_bytes)
+ return OPUS_BAD_ARG;
}
else
return OPUS_UNIMPLEMENTED;
--- a/tests/test_opus_projection.c
+++ b/tests/test_opus_projection.c
@@ -96,6 +96,7 @@
-29491, 3277, 0, -3277};
int i, ret;
+ opus_int32 simple_matrix_size;
opus_val16 *input_val16;
opus_val16 *output_val16;
opus_int16 *output_int16;
@@ -107,9 +108,12 @@
output_val16 = (opus_val16 *)opus_alloc(align(sizeof(opus_val16) * SIMPLE_MATRIX_OUTPUT_SIZE));
/* Initialize matrix */
- simple_matrix = (MappingMatrix *)opus_alloc(
- mapping_matrix_get_size(simple_matrix_params.rows,
- simple_matrix_params.cols));
+ simple_matrix_size = mapping_matrix_get_size(simple_matrix_params.rows,
+ simple_matrix_params.cols);
+ if (!simple_matrix_size)
+ test_failed();
+
+ simple_matrix = (MappingMatrix *)opus_alloc(simple_matrix_size);
mapping_matrix_init(simple_matrix, simple_matrix_params.rows,
simple_matrix_params.cols, simple_matrix_params.gain, simple_matrix_data,
sizeof(simple_matrix_data));