[vlc-commits] [Git][videolan/vlc][3.0.x] 2 commits: access: mms: add buffer remaining bytes function

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Wed Jul 22 01:01:02 UTC 2026



Jean-Baptiste Kempf pushed to branch 3.0.x at VideoLAN / VLC


Commits:
caf383c3 by François Cartegnie at 2026-07-22T02:53:41+02:00
access: mms: add buffer remaining bytes function

(adapted from commit 5a1cad239f66cecb437b35570142df9e17ca0a72)

- - - - -
a0c1f23c by François Cartegnie at 2026-07-22T02:53:41+02:00
access: mms: fix read overflow in parsing

refs #29987

(adapted from commit 7d7aa2d805b01b834c59c381532fb23cec66b74d)

- - - - -


3 changed files:

- modules/access/mms/asf.c
- modules/access/mms/buffer.c
- modules/access/mms/buffer.h


Changes:

=====================================
modules/access/mms/asf.c
=====================================
@@ -58,6 +58,8 @@ void  asf_HeaderParse ( asf_header_t *hdr,
     }
 
     var_buffer_initread( &buffer, p_header, i_header );
+    if( var_buffer_remain( &buffer ) < 30 )
+        return;
     var_buffer_getguid( &buffer, &guid );
 
     if( !guidcmp( &guid, &asf_object_header_guid ) )
@@ -68,11 +70,19 @@ void  asf_HeaderParse ( asf_header_t *hdr,
 
     for( ;; )
     {
+        if( var_buffer_remain( &buffer ) < 24 )
+            return;
+
         var_buffer_getguid( &buffer, &guid );
         i_size = var_buffer_get64( &buffer );
+        if( i_size < 24 || (uint64_t)var_buffer_remain( &buffer ) < i_size - 24 )
+            return;
 
         if( guidcmp( &guid, &asf_object_file_properties_guid ) )
         {
+            const int object_size = 24 + 16 + 8 + 8 + 8 + 8+8+8+4 + 4;
+            if( i_size < object_size )
+                return;
             var_buffer_getmemory( &buffer, NULL, 16 );
             hdr->i_file_size            = var_buffer_get64( &buffer );
             var_buffer_getmemory( &buffer, NULL, 8 );
@@ -80,18 +90,22 @@ void  asf_HeaderParse ( asf_header_t *hdr,
             var_buffer_getmemory( &buffer, NULL, 8+8+8+4);
             hdr->i_min_data_packet_size = var_buffer_get32( &buffer );
 
-            var_buffer_getmemory( &buffer, NULL, i_size - 24 - 16 - 8 - 8 - 8 - 8-8-8-4 - 4);
+            var_buffer_getmemory( &buffer, NULL, i_size - object_size );
         }
         else if( guidcmp( &guid, &asf_object_header_extension_guid ) )
         {
+            if( i_size < 46 )
+                return;
             /* Enter it */
             var_buffer_getmemory( &buffer, NULL, 46 - 24 );
         }
         else if( guidcmp( &guid, &asf_object_extended_stream_properties_guid ) )
         {
+            if( i_size < 88 )
+                return;
             /* Grrrrrr */
-            int16_t i_count1, i_count2;
-            int i_subsize;
+            uint16_t i_count1, i_count2;
+            uint64_t i_subsize;
 
             var_buffer_getmemory( &buffer, NULL, 84 - 24 );
 
@@ -99,12 +113,17 @@ void  asf_HeaderParse ( asf_header_t *hdr,
             i_count2 = var_buffer_get16( &buffer );
 
             i_subsize = 88;
+
             for( int i = 0; i < i_count1; i++ )
             {
-                int i_len;
+                uint64_t i_len;
 
+                if( i_size - i_subsize < 2 + 2 )
+                    return;
                 var_buffer_get16( &buffer );
                 i_len = var_buffer_get16( &buffer );
+                if( i_size - i_subsize < 2 + 2 + i_len )
+                    return;
                 var_buffer_getmemory( &buffer, NULL, i_len );
 
                 i_subsize += 4 + i_len;
@@ -112,12 +131,17 @@ void  asf_HeaderParse ( asf_header_t *hdr,
 
             for( int i = 0; i < i_count2; i++ )
             {
-                int i_len;
+                if( i_size - i_subsize < 16 + 2 + 4 )
+                    return;
+
+                uint64_t i_len;
                 var_buffer_getmemory( &buffer, NULL, 16 + 2 );
                 i_len = var_buffer_get32( &buffer );
+                if( i_size - i_subsize < i_len + 16 + 2 + 4 )
+                    return;
                 var_buffer_getmemory( &buffer, NULL, i_len );
 
-                i_subsize += 16 + 6 + i_len;
+                i_subsize += 16 + 2 + 4 + i_len;
             }
 
             if( i_size - i_subsize <= 24 )
@@ -129,6 +153,10 @@ void  asf_HeaderParse ( asf_header_t *hdr,
         }
         else if( guidcmp( &guid, &asf_object_stream_properties_guid ) )
         {
+            const int object_size = 24 + 32 + 16 + 1;
+            if( i_size < object_size )
+                return;
+
             int     i_stream_id;
             guid_t  stream_type;
 
@@ -136,7 +164,7 @@ void  asf_HeaderParse ( asf_header_t *hdr,
             var_buffer_getmemory( &buffer, NULL, 32 );
 
             i_stream_id = var_buffer_get8( &buffer ) & 0x7f;
-            var_buffer_getmemory( &buffer, NULL, i_size - 24 - 32 - 16 - 1);
+            var_buffer_getmemory( &buffer, NULL, i_size - object_size );
 
             if( guidcmp( &stream_type, &asf_object_stream_type_video ) )
             {
@@ -153,12 +181,15 @@ void  asf_HeaderParse ( asf_header_t *hdr,
         }
         else if ( guidcmp( &guid, &asf_object_stream_bitrate_properties ) )
         {
+            if( i_size < 24 + 2 + 6 )
+                return;
+
             int     i_count;
             uint8_t i_stream_id;
 
             i_count = var_buffer_get16( &buffer );
             i_size -= 2;
-            while( i_count > 0 )
+            while( i_count > 0 && i_size >= (24 + 6) )
             {
                 i_stream_id = var_buffer_get16( &buffer )&0x7f;
                 hdr->stream[i_stream_id].i_bitrate =  var_buffer_get32( &buffer );


=====================================
modules/access/mms/buffer.c
=====================================
@@ -208,7 +208,7 @@ int var_buffer_getmemory ( var_buffer_t *p_buf, void *p_mem, int64_t i_mem )
     return( i_copy );
 }
 
-int var_buffer_readempty( var_buffer_t *p_buf )
+int var_buffer_readempty( const var_buffer_t *p_buf )
 {
     return( ( p_buf->i_data >= p_buf->i_size ) ? 1 : 0 );
 }
@@ -222,3 +222,10 @@ void var_buffer_getguid( var_buffer_t *p_buf, guid_t *p_guid )
     for( int i = 0; i < 8; i++ )
         p_guid->Data4[i] = var_buffer_get8( p_buf );
 }
+
+int var_buffer_remain( const var_buffer_t *p_buf )
+{
+    if( var_buffer_readempty( p_buf ) )
+        return 0;
+    return p_buf->i_size - p_buf->i_data;
+}


=====================================
modules/access/mms/buffer.h
=====================================
@@ -53,7 +53,8 @@ uint16_t  var_buffer_get16( var_buffer_t *p_buf );
 uint32_t  var_buffer_get32( var_buffer_t *p_buf );
 uint64_t  var_buffer_get64( var_buffer_t *p_buf );
 int       var_buffer_getmemory ( var_buffer_t *p_buf, void *p_mem, int64_t i_mem );
-int       var_buffer_readempty( var_buffer_t *p_buf );
+int       var_buffer_readempty( const var_buffer_t *p_buf );
 void      var_buffer_getguid( var_buffer_t *p_buf, guid_t *p_guid );
+int       var_buffer_remain( const var_buffer_t *p_buf );
 
 #endif



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/33fd789ea97a6001b6765ff936fce587898e3c76...a0c1f23c161d6e8c050c3709c680ed6f74cc6be9

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/33fd789ea97a6001b6765ff936fce587898e3c76...a0c1f23c161d6e8c050c3709c680ed6f74cc6be9
You're receiving this email because of your account on code.videolan.org. Manage all notifications: https://code.videolan.org/-/profile/notifications | Help: https://code.videolan.org/help




More information about the vlc-commits mailing list