From 697beca22dcdf04ee7720218741f34a7ec0bb86d Mon Sep 17 00:00:00 2001 From: Mark Harris <mark.hsj@gmail.com> Date: Sun, 27 May 2018 17:47:28 -0700 Subject: [PATCH] Only call isqrt32() with a positive argument Fixes test_opus_projection failure under ubsan, due to clz(0). --- celt/mathops.c | 3 ++- src/opus_multistream_encoder.c | 6 ++++-- src/opus_projection_encoder.c | 10 ++++++---- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/celt/mathops.c b/celt/mathops.c index 78b52cc84..6ee9b9e10 100644 --- a/celt/mathops.c +++ b/celt/mathops.c @@ -38,7 +38,8 @@ #include "mathops.h" /*Compute floor(sqrt(_val)) with exact arithmetic. - This has been tested on all possible 32-bit inputs.*/ + _val must be greater than 0. + This has been tested on all possible 32-bit inputs greater than 0.*/ unsigned isqrt32(opus_uint32 _val){ unsigned b; unsigned g; diff --git a/src/opus_multistream_encoder.c b/src/opus_multistream_encoder.c index 1df9e7db8..aa48a61b0 100644 --- a/src/opus_multistream_encoder.c +++ b/src/opus_multistream_encoder.c @@ -108,12 +108,14 @@ static int validate_ambisonics(int nb_channels, int *nb_streams, int *nb_coupled int acn_channels; int nondiegetic_channels; + if (nb_channels < 1 || nb_channels > 227) + return 0; + order_plus_one = isqrt32(nb_channels); acn_channels = order_plus_one * order_plus_one; nondiegetic_channels = nb_channels - acn_channels; - if (order_plus_one < 1 || order_plus_one > 15 || - (nondiegetic_channels != 0 && nondiegetic_channels != 2)) + if (nondiegetic_channels != 0 && nondiegetic_channels != 2) return 0; if (nb_streams) diff --git a/src/opus_projection_encoder.c b/src/opus_projection_encoder.c index 1c403c316..1fbcf471f 100644 --- a/src/opus_projection_encoder.c +++ b/src/opus_projection_encoder.c @@ -86,15 +86,17 @@ static int get_order_plus_one_from_channels(int channels, int *order_plus_one) /* Allowed numbers of channels: * (1 + n)^2 + 2j, for n = 0...14 and j = 0 or 1. */ + if (channels < 1 || channels > 227) + return OPUS_BAD_ARG; + order_plus_one_ = isqrt32(channels); acn_channels = order_plus_one_ * order_plus_one_; nondiegetic_channels = channels - acn_channels; + if (nondiegetic_channels != 0 && nondiegetic_channels != 2) + return OPUS_BAD_ARG; + if (order_plus_one) *order_plus_one = order_plus_one_; - - if (order_plus_one_ < 1 || order_plus_one_ > 15 || - (nondiegetic_channels != 0 && nondiegetic_channels != 2)) - return OPUS_BAD_ARG; return OPUS_OK; } -- GitLab