Explorar o código

avformat/framecrcenc: Don't read after the end of side-data

Nothing guarantees that the size of side data containing a palette
is actually divisible by four (although it should be); but for
big-endian systems, an algorithm is used that presupposed this.
So switch to an algorithm that does not overread: It processes
four bytes at a time, but only if all of them are contained in
the side data.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
Andreas Rheinhardt %!s(int64=5) %!d(string=hai) anos
pai
achega
b8fe417c19
Modificáronse 1 ficheiros con 7 adicións e 5 borrados
  1. 7 5
      libavformat/framecrcenc.c

+ 7 - 5
libavformat/framecrcenc.c

@@ -23,6 +23,7 @@
 
 
 #include "libavutil/adler32.h"
 #include "libavutil/adler32.h"
 #include "libavutil/avstring.h"
 #include "libavutil/avstring.h"
+#include "libavutil/intreadwrite.h"
 #include "avformat.h"
 #include "avformat.h"
 #include "internal.h"
 #include "internal.h"
 
 
@@ -52,16 +53,17 @@ static int framecrc_write_packet(struct AVFormatContext *s, AVPacket *pkt)
     if (pkt->flags != AV_PKT_FLAG_KEY)
     if (pkt->flags != AV_PKT_FLAG_KEY)
         av_strlcatf(buf, sizeof(buf), ", F=0x%0X", pkt->flags);
         av_strlcatf(buf, sizeof(buf), ", F=0x%0X", pkt->flags);
     if (pkt->side_data_elems) {
     if (pkt->side_data_elems) {
-        int i, j;
+        int i;
         av_strlcatf(buf, sizeof(buf), ", S=%d", pkt->side_data_elems);
         av_strlcatf(buf, sizeof(buf), ", S=%d", pkt->side_data_elems);
 
 
         for (i=0; i<pkt->side_data_elems; i++) {
         for (i=0; i<pkt->side_data_elems; i++) {
+            const AVPacketSideData *const sd = &pkt->side_data[i];
             uint32_t side_data_crc = 0;
             uint32_t side_data_crc = 0;
             if (HAVE_BIGENDIAN && AV_PKT_DATA_PALETTE == pkt->side_data[i].type) {
             if (HAVE_BIGENDIAN && AV_PKT_DATA_PALETTE == pkt->side_data[i].type) {
-                for (j=0; j<pkt->side_data[i].size; j++) {
-                    side_data_crc = av_adler32_update(side_data_crc,
-                                                      pkt->side_data[i].data + (j^3),
-                                                      1);
+                for (int j = 0; j < sd->size / 4; j++) {
+                    uint8_t buf[4];
+                    AV_WL32(buf, AV_RB32(sd->data + 4 * j));
+                    side_data_crc = av_adler32_update(side_data_crc, buf, 4);
                 }
                 }
             } else {
             } else {
                 side_data_crc = av_adler32_update(0,
                 side_data_crc = av_adler32_update(0,