diff mbox series

[FFmpeg-devel,3/3] avcodec/siren: add checksum calculation

Message ID b335cc4a394d53188c12e8374d47d5aa6e4ac4ef.1631959242.git.pross@xvid.org
State Accepted
Commit 855014ff83dae786e914b4c7df88d263ec4122a7
Headers show
Series [FFmpeg-devel,1/3] avcodec/siren: prevent getbitcontext overread
Related show

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished
andriy/make_ppc success Make finished
andriy/make_fate_ppc success Make fate finished

Commit Message

Peter Ross Sept. 18, 2021, 10:03 a.m. UTC
---
 libavcodec/siren.c | 32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

Comments

Lynne Sept. 18, 2021, 5:15 p.m. UTC | #1
18 Sept 2021, 12:03 by pross@xvid.org:

> ---
>  libavcodec/siren.c | 32 +++++++++++++++++++++++++++++++-
>  1 file changed, 31 insertions(+), 1 deletion(-)
>
> diff --git a/libavcodec/siren.c b/libavcodec/siren.c
> index 92fd3632f5..2d3969f24c 100644
> --- a/libavcodec/siren.c
> +++ b/libavcodec/siren.c
> @@ -756,7 +756,37 @@ static int siren_decode(AVCodecContext *avctx, void *data,
>  frame_error = 1;
>  }
>  
> -    skip_bits(gb, s->checksum_bits);
> +    if ((avctx->err_recognition & AV_EF_CRCCHECK) && s->checksum_bits) {
> +        static const uint16_t ChecksumTable[4] = {0x7F80, 0x7878, 0x6666, 0x5555};
> +        int wpf, checksum, sum, calculated_checksum, temp1;
> +
> +        checksum = get_bits(gb, s->checksum_bits);
> +
> +        wpf = bits_per_frame / 16;
> +        sum = 0;
> +        for (int i = 0; i < wpf - 1; i++)
> +            sum ^= AV_RB16(avpkt->data + i * 2) << (i % 15);
> +        sum ^= (AV_RB16(avpkt->data + (wpf - 1) * 2) & ~checksum) << ((wpf - 1) % 15);
> +        sum = (sum >> 15) ^ (sum & 0x7FFF);
> +
> +        calculated_checksum = 0;
> +        for (int i = 0; i < 4; i++) {
> +            temp1 = ChecksumTable[i] & sum;
> +
> +            for (int j = 8; j > 0; j >>= 1)
> +                temp1 ^= temp1 >> j;
> +
> +            calculated_checksum <<= 1;
> +            calculated_checksum |= temp1 & 1;
> +        }
> +
> +        if (checksum != calculated_checksum) {
> +            av_log(avctx, AV_LOG_WARNING, "Invalid checksum\n");
> +            if (avctx->err_recognition & AV_EF_EXPLODE)
> +                return AVERROR_INVALIDDATA;
> +            frame_error = 1;
> +        }
> +    } 
>

Looks good to me.
diff mbox series

Patch

diff --git a/libavcodec/siren.c b/libavcodec/siren.c
index 92fd3632f5..2d3969f24c 100644
--- a/libavcodec/siren.c
+++ b/libavcodec/siren.c
@@ -756,7 +756,37 @@  static int siren_decode(AVCodecContext *avctx, void *data,
             frame_error = 1;
     }
 
-    skip_bits(gb, s->checksum_bits);
+    if ((avctx->err_recognition & AV_EF_CRCCHECK) && s->checksum_bits) {
+        static const uint16_t ChecksumTable[4] = {0x7F80, 0x7878, 0x6666, 0x5555};
+        int wpf, checksum, sum, calculated_checksum, temp1;
+
+        checksum = get_bits(gb, s->checksum_bits);
+
+        wpf = bits_per_frame / 16;
+        sum = 0;
+        for (int i = 0; i < wpf - 1; i++)
+            sum ^= AV_RB16(avpkt->data + i * 2) << (i % 15);
+        sum ^= (AV_RB16(avpkt->data + (wpf - 1) * 2) & ~checksum) << ((wpf - 1) % 15);
+        sum = (sum >> 15) ^ (sum & 0x7FFF);
+
+        calculated_checksum = 0;
+        for (int i = 0; i < 4; i++) {
+            temp1 = ChecksumTable[i] & sum;
+
+            for (int j = 8; j > 0; j >>= 1)
+                temp1 ^= temp1 >> j;
+
+            calculated_checksum <<= 1;
+            calculated_checksum |= temp1 & 1;
+        }
+
+        if (checksum != calculated_checksum) {
+            av_log(avctx, AV_LOG_WARNING, "Invalid checksum\n");
+            if (avctx->err_recognition & AV_EF_EXPLODE)
+                return AVERROR_INVALIDDATA;
+            frame_error = 1;
+        }
+    }
 
     if (frame_error) {
         memcpy(s->imdct_in, s->backup_frame, number_of_valid_coefs * sizeof(float));