[vlc-commits] packetizer: flac: allow to parse smaller than max header sized blocks

Francois Cartegnie git at videolan.org
Mon Apr 27 20:32:39 CEST 2020


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Mon Apr 27 19:23:49 2020 +0200| [0337ab24f41197f9ab5b7c7e8fe4c4b248e23609] | committer: Francois Cartegnie

packetizer: flac: allow to parse smaller than max header sized blocks

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=0337ab24f41197f9ab5b7c7e8fe4c4b248e23609
---

 modules/demux/flac.c      |  6 ++++--
 modules/packetizer/flac.c |  4 ++--
 modules/packetizer/flac.h | 29 +++++++++++++++++++++++++----
 3 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/modules/demux/flac.c b/modules/demux/flac.c
index 8b1c118047..d63495577c 100644
--- a/modules/demux/flac.c
+++ b/modules/demux/flac.c
@@ -37,6 +37,7 @@
 #include <vlc_charset.h>              /* EnsureUTF8 */
 
 #include <assert.h>
+#include <limits.h>
 #include "xiph_metadata.h"            /* vorbis comments */
 #include "../packetizer/flac.h"
 
@@ -224,10 +225,11 @@ static block_t *GetPacketizedBlock( decoder_t *p_packetizer,
     block_t *p_block = p_packetizer->pf_packetize( p_packetizer, pp_current_block );
     if( p_block )
     {
-        if( p_block->i_buffer >= FLAC_HEADER_SIZE_MAX )
+        if( p_block->i_buffer >= FLAC_HEADER_SIZE_MIN && p_block->i_buffer < INT_MAX )
         {
             struct flac_header_info headerinfo = { .i_pts = VLC_TICK_INVALID };
-            int i_ret = FLAC_ParseSyncInfo( p_block->p_buffer, streaminfo, NULL, &headerinfo );
+            int i_ret = FLAC_ParseSyncInfo( p_block->p_buffer, p_block->i_buffer,
+                                            streaminfo, NULL, &headerinfo );
             assert( i_ret != 0 ); /* Same as packetizer */
             /* Use Frame PTS, not the interpolated one */
             p_block->i_dts = p_block->i_pts = headerinfo.i_pts;
diff --git a/modules/packetizer/flac.c b/modules/packetizer/flac.c
index 0cdfe908f5..d58ee189f2 100644
--- a/modules/packetizer/flac.c
+++ b/modules/packetizer/flac.c
@@ -366,7 +366,7 @@ static block_t *Packetize(decoder_t *p_dec, block_t **pp_block)
             return NULL; /* Need more data */
 
         /* Check if frame is valid and get frame info */
-        int i_ret = FLAC_ParseSyncInfo(p_header,
+        int i_ret = FLAC_ParseSyncInfo(p_header, FLAC_HEADER_SIZE_MAX,
                              p_sys->b_stream_info ? &p_sys->stream_info : NULL,
                              flac_crc8, &p_sys->headerinfo);
         if (!i_ret) {
@@ -413,7 +413,7 @@ static block_t *Packetize(decoder_t *p_dec, block_t **pp_block)
 
         struct flac_header_info dummy;
         /* Check if frame is valid and get frame info */
-        if(FLAC_ParseSyncInfo(nextheader,
+        if(FLAC_ParseSyncInfo(nextheader, FLAC_HEADER_SIZE_MAX,
                               p_sys->b_stream_info ? &p_sys->stream_info : NULL,
                               NULL, &dummy) == 0)
         {
diff --git a/modules/packetizer/flac.h b/modules/packetizer/flac.h
index 870a30cdf6..2ee0100724 100644
--- a/modules/packetizer/flac.h
+++ b/modules/packetizer/flac.h
@@ -19,6 +19,7 @@
  *****************************************************************************/
 #include <vlc_common.h>
 
+#define FLAC_HEADER_SIZE_MIN 9
 #define FLAC_HEADER_SIZE_MAX 16
 #define FLAC_STREAMINFO_SIZE 34
 #define FLAC_FRAME_SIZE_MIN ((48+(8 + 4 + 1*4)+FLAC_HEADER_SIZE_MAX)/8)
@@ -64,13 +65,16 @@ static inline void FLAC_ParseStreamInfo( const uint8_t *p_buf,
 }
 
 /* Will return INT64_MAX for an invalid utf-8 sequence */
-static inline int64_t read_utf8(const uint8_t *p_buf, int *pi_read)
+static inline int64_t read_utf8(const uint8_t *p_buf, unsigned i_buf, int *pi_read)
 {
     /* Max coding bits is 56 - 8 */
     /* Value max precision is 36 bits */
     int64_t i_result = 0;
     unsigned i;
 
+    if(i_buf < 1)
+        return INT64_MAX;
+
     if (!(p_buf[0] & 0x80)) { /* 0xxxxxxx */
         i_result = p_buf[0];
         i = 0;
@@ -96,6 +100,9 @@ static inline int64_t read_utf8(const uint8_t *p_buf, int *pi_read)
         return INT64_MAX;
     }
 
+    if(i_buf < i + 1)
+        return INT64_MAX;
+
     for (unsigned j = 1; j <= i; j++) {
         if (!(p_buf[j] & 0x80) || (p_buf[j] & 0x40)) { /* 10xxxxxx */
             return INT64_MAX;
@@ -114,13 +121,16 @@ static inline int64_t read_utf8(const uint8_t *p_buf, int *pi_read)
  * - pf_crc8 can be NULL to skip crc check
  * Returns: 1 on success, 0 on failure, and -1 if could be incorrect
  *****************************************************************************/
-static inline int FLAC_ParseSyncInfo(const uint8_t *p_buf,
+static inline int FLAC_ParseSyncInfo(const uint8_t *p_buf, unsigned i_buf,
                                      const struct flac_stream_info *stream_info,
                                      uint8_t(*pf_crc8)(const uint8_t *, size_t),
                                      struct flac_header_info *h)
 {
     bool b_guessing = false;
 
+    if(unlikely(i_buf < FLAC_HEADER_SIZE_MIN))
+        return 0;
+
     /* Check syncword */
     if (p_buf[0] != 0xFF || (p_buf[1] & 0xFE) != 0xF8)
         return 0;
@@ -205,11 +215,13 @@ static inline int FLAC_ParseSyncInfo(const uint8_t *p_buf,
         return 0;
 
     /* End of fixed size header */
-    int i_header = 4;
+    unsigned i_header = 4;
+
+    /* > FLAC_HEADER_SIZE_MIN checks start here */
 
     /* Check Sample/Frame number */
     int i_read;
-    int64_t i_fsnumber = read_utf8(&p_buf[i_header++], &i_read);
+    int64_t i_fsnumber = read_utf8(&p_buf[i_header++], i_buf - 4, &i_read);
     if ( i_fsnumber == INT64_MAX )
         return 0;
 
@@ -217,6 +229,8 @@ static inline int FLAC_ParseSyncInfo(const uint8_t *p_buf,
 
     /* Read blocksize */
     if (blocksize_hint) {
+        if(i_header == i_buf)
+            return 0;
         blocksize = p_buf[i_header++];
         if (blocksize_hint == 7) {
             blocksize <<= 8;
@@ -227,8 +241,12 @@ static inline int FLAC_ParseSyncInfo(const uint8_t *p_buf,
 
     /* Read sample rate */
     if (samplerate == 0) {
+        if(i_header == i_buf)
+            return 0;
         samplerate = p_buf[i_header++];
         if (samplerate_hint != 12) { /* 16 bits */
+            if(i_header == i_buf)
+                return 0;
             samplerate <<= 8;
             samplerate |= p_buf[i_header++];
         }
@@ -242,6 +260,9 @@ static inline int FLAC_ParseSyncInfo(const uint8_t *p_buf,
     if ( !samplerate )
         return 0;
 
+    if(i_header == i_buf) /* no crc space */
+        return 0;
+
     /* Check the CRC-8 byte */
     if (pf_crc8 &&
         pf_crc8(p_buf, i_header) != p_buf[i_header])



More information about the vlc-commits mailing list