[vlc-commits] demux: ts/ps: check marked bits and fixed headers

Francois Cartegnie git at videolan.org
Mon Dec 12 15:00:47 CET 2016


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Mon Dec 12 14:39:03 2016 +0100| [e9938d680f006a023871cb4cb89f0a58e180bc14] | committer: Francois Cartegnie

demux: ts/ps: check marked bits and fixed headers

refs #17773

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

 modules/demux/mpeg/pes.h         | 32 ++++++++++++++++++++++----------
 modules/demux/mpeg/ps.h          |  6 ++++--
 modules/demux/mpeg/ts_hotfixes.c |  8 ++++----
 3 files changed, 30 insertions(+), 16 deletions(-)

diff --git a/modules/demux/mpeg/pes.h b/modules/demux/mpeg/pes.h
index 9a2cc34..7ad420a 100644
--- a/modules/demux/mpeg/pes.h
+++ b/modules/demux/mpeg/pes.h
@@ -20,13 +20,21 @@
 #ifndef VLC_MPEG_PES_H
 #define VLC_MPEG_PES_H
 
-static inline mtime_t ExtractPESTimestamp( const uint8_t *p_data )
+static inline bool ExtractPESTimestamp( const uint8_t *p_data, uint8_t i_flags, mtime_t *ret )
 {
-    return ((mtime_t)(p_data[ 0]&0x0e ) << 29)|
+    i_flags = (i_flags << 4) | 0x01; /* check marker bits, and i_flags = b 0010, 0011 or 0001 */
+    if((p_data[0] & 0xF1) != i_flags ||
+       (p_data[2] & 0x01) != 0x01 ||
+       (p_data[4] & 0x01) != 0x01)
+        return false;
+
+
+    *ret =  ((mtime_t)(p_data[ 0]&0x0e ) << 29)|
              (mtime_t)(p_data[1] << 22)|
             ((mtime_t)(p_data[2]&0xfe) << 14)|
              (mtime_t)(p_data[3] << 7)|
              (mtime_t)(p_data[4] >> 1);
+    return true;
 }
 
 /* PS SCR timestamp as defined in H222 2.5.3.2 */
@@ -78,20 +86,24 @@ static int ParsePESHeader( vlc_object_t *p_object, const uint8_t *p_header, size
 
             if( p_header[7]&0x80 )    /* has pts */
             {
-                if( i_header < 9 + 5 )
+                if( i_header < 9 + 5 ||
+                   !ExtractPESTimestamp( &p_header[9], p_header[7] >> 6, pi_pts ) )
                     return VLC_EGENERIC;
-                *pi_pts = ExtractPESTimestamp( &p_header[9] );
 
                 if( p_header[7]&0x40 )    /* has dts */
                 {
-                    if( i_header < 14 + 5 )
+                    if( i_header < 14 + 5 ||
+                       !ExtractPESTimestamp( &p_header[14], 0x01, pi_dts ) )
                         return VLC_EGENERIC;
-                    *pi_dts = ExtractPESTimestamp( &p_header[14] );
                 }
             }
         }
         else
         {
+            /* FIXME?: WTH do we have undocumented MPEG1 packet stuff here ?
+               This code path should not be valid, but seems some ppl did
+               put MPEG1 packets into PS or TS.
+               Non spec reference for packet format on http://andrewduncan.net/mpeg/mpeg-1.html */
             i_skip = 6;
 
             if( pb_pes_scambling )
@@ -120,15 +132,15 @@ static int ParsePESHeader( vlc_object_t *p_object, const uint8_t *p_header, size
 
             if(  p_header[i_skip]&0x20 )
             {
-                if( i_header < i_skip + 5 )
+                if( i_header < i_skip + 5  ||
+                   !ExtractPESTimestamp( &p_header[i_skip], p_header[i_skip] >> 4, pi_pts ) )
                     return VLC_EGENERIC;
-                *pi_pts = ExtractPESTimestamp( &p_header[i_skip] );
 
                 if( p_header[i_skip]&0x10 )    /* has dts */
                 {
-                    if( i_header < i_skip + 10 )
+                    if( i_header < i_skip + 10 ||
+                       !ExtractPESTimestamp( &p_header[i_skip+5], 0x01, pi_dts ) )
                         return VLC_EGENERIC;
-                    *pi_dts = ExtractPESTimestamp( &p_header[i_skip+5] );
                     i_skip += 10;
                 }
                 else
diff --git a/modules/demux/mpeg/ps.h b/modules/demux/mpeg/ps.h
index 4b43230..6eee287 100644
--- a/modules/demux/mpeg/ps.h
+++ b/modules/demux/mpeg/ps.h
@@ -372,9 +372,11 @@ static inline int ps_pkt_parse_pack( block_t *p_pkt, int64_t *pi_scr,
         *pi_scr = FROM_SCALE_NZ( ExtractPackHeaderTimestamp( &p[4] ) );
         *pi_mux_rate = ( p[10] << 14 )|( p[11] << 6 )|( p[12] >> 2);
     }
-    else if( p_pkt->i_buffer >= 12 && (p[4] >> 4) == 0x02 )
+    else if( p_pkt->i_buffer >= 12 && (p[4] >> 4) == 0x02 ) /* MPEG-1 Pack SCR, same bits as PES/PTS */
     {
-        *pi_scr = FROM_SCALE_NZ( ExtractPESTimestamp( &p[4] ) );
+        if(!ExtractPESTimestamp( &p[4], 0x02, pi_scr ))
+            return VLC_EGENERIC;
+        *pi_scr = FROM_SCALE_NZ( *pi_scr );
         *pi_mux_rate = ( ( p[9]&0x7f )<< 15 )|( p[10] << 7 )|( p[11] >> 1);
     }
     else
diff --git a/modules/demux/mpeg/ts_hotfixes.c b/modules/demux/mpeg/ts_hotfixes.c
index c485b1b..3cdec5f 100644
--- a/modules/demux/mpeg/ts_hotfixes.c
+++ b/modules/demux/mpeg/ts_hotfixes.c
@@ -87,16 +87,16 @@ void ProbePES( demux_t *p_demux, ts_pid_t *pid, const uint8_t *p_pesstart, size_
     if( p_pes[7] & 0x80 ) // PTS
     {
         i_pesextoffset += 5;
-        if ( i_data < i_pesextoffset )
+        if ( i_data < i_pesextoffset ||
+            !ExtractPESTimestamp( &p_pes[9], p_pes[7] >> 6, &i_dts ) )
             return;
-        i_dts = ExtractPESTimestamp( &p_pes[9] );
     }
     if( p_pes[7] & 0x40 ) // DTS
     {
         i_pesextoffset += 5;
-        if ( i_data < i_pesextoffset )
+        if ( i_data < i_pesextoffset ||
+            !ExtractPESTimestamp( &p_pes[14], 0x01, &i_dts ) )
             return;
-        i_dts = ExtractPESTimestamp( &p_pes[14] );
     }
     if( p_pes[7] & 0x20 ) // ESCR
         i_pesextoffset += 6;



More information about the vlc-commits mailing list