[vlc-devel] [PATCH] added handling of wrong MIME boundary separator to mjpeg demux

Sergey Radionov rsatom at gmail.com
Thu Aug 30 05:18:44 CEST 2012


---
 modules/demux/mjpeg.c |   94 ++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 89 insertions(+), 5 deletions(-)

diff --git a/modules/demux/mjpeg.c b/modules/demux/mjpeg.c
index a057db3..f5bd1dd 100644
--- a/modules/demux/mjpeg.c
+++ b/modules/demux/mjpeg.c
@@ -200,10 +200,10 @@ static bool CheckMimeHeader( demux_t *p_demux, int *p_header_size )
             char *content_type = stream_ContentType( p_demux->s );
             if ( content_type == NULL )
                 return false;
-            const char* boundary = strstr( content_type, "boundary=--" );
+            const char* boundary = strstr( content_type, "boundary=" );
             if ( boundary != NULL )
             {
-                p_sys->psz_separator = strdup( boundary + strlen( "boundary=--" ) );
+                p_sys->psz_separator = strdup( boundary + strlen("boundary=") );
                 msg_Dbg( p_demux, "Video boundary extracted from Content-Type: %s", p_sys->psz_separator );
                 free( content_type );
                 /* Skip to HTTP header parsing as there's no boundary to extract
@@ -223,7 +223,8 @@ static bool CheckMimeHeader( demux_t *p_demux, int *p_header_size )
     }
     else
     {
-        i_pos = *p_sys->p_peek == '-' ? 2 : 4;
+        i_pos = *p_sys->p_peek == '-' ? 0 : 2;//skip "\r\n" if exist
+        int i_pos_save = i_pos;//to allow restore after missing "\r\n"...
         psz_line = GetLine( p_demux, &i_pos );
         if( NULL == psz_line )
         {
@@ -235,13 +236,92 @@ static bool CheckMimeHeader( demux_t *p_demux, int *p_header_size )
         /* Read the separator and remember it if not yet stored */
         if( p_sys->psz_separator == NULL )
         {
-            p_sys->psz_separator = psz_line;
+            char *content_type = stream_ContentType( p_demux->s );
+            char* boundary = NULL;
+            if ( content_type != NULL )
+            {
+                boundary = strstr( content_type, "boundary=" );
+                if( boundary ) boundary += strlen("boundary=");
+            }
+
+            //some vendors add "--" at boundary begin and end in ContentType declaration,
+            //and don't add additional "--" in the body - it's incorrect...
+            //some other vendors, forget to add "\r\n" after boundary - it's incorrect too...
+            //and some else vendors, forget to add "\r\n" and forget to add "--" both
+            //(or add excess "--" to ContentType, which is the same)...
+
+            size_t boundary_len = boundary ? strlen(boundary) : 0;
+            //if used boundary without additional "--"
+            //(i.e. used same string was declared in ContentType), then
+            if( boundary && !strncmp( psz_line, boundary, boundary_len ) )
+            {
+                //if boundary identical to psz_line, then
+                if( *(psz_line + boundary_len) == '\0' )
+                {
+                    //just use whole line as separator
+                    p_sys->psz_separator = psz_line;
+                }
+                else
+                {
+                    //restore buffer position to right place
+                    i_pos = i_pos_save + boundary_len;
+                    p_sys->psz_separator = strdup( boundary );
+                    free( psz_line );
+                    psz_line = NULL;
+
+                    if( !p_sys->psz_separator )
+                    {
+                        free( content_type );
+                        *p_header_size = -4;
+                        return false;
+                    }
+                }
+            }
+
+            //if used boundary with additional "--"
+            if( !p_sys->psz_separator && boundary &&
+                !strncmp( psz_line + strlen("--"), boundary, boundary_len ) )
+            {
+                char* s = psz_line + strlen("--") + boundary_len;
+                if( !strncmp( s , "--", 2 ) ) //skip "--" if boundary is last
+                    s += 2;
+
+                //"\r\n" is forgotten
+                if ( *s != '\0' )
+                {
+                    //restore buffer position to right place
+                    i_pos = i_pos_save + boundary_len;
+                }
+
+                p_sys->psz_separator = strdup( boundary );
+                free( psz_line );
+                psz_line = NULL;
+
+                if( !p_sys->psz_separator )
+                {
+                    free( content_type );
+                    *p_header_size = -4;
+                    return false;
+                }
+            }
+
+            if( !p_sys->psz_separator )
+            {
+                //separator was not found, then just use whole line
+                //FIXME: don't sure it's right
+                p_sys->psz_separator = psz_line;
+            }
+
             msg_Dbg( p_demux, "Multipart MIME detected, using separator: %s",
                      p_sys->psz_separator );
+
+            free( content_type );
         }
         else
         {
-            if( strcmp( psz_line, p_sys->psz_separator ) )
+            size_t separator_len = strlen(p_sys->psz_separator);
+            if( strncmp( psz_line + strlen("--"), p_sys->psz_separator, separator_len ) &&
+                strncmp( psz_line, p_sys->psz_separator, separator_len ) )
             {
                 msg_Warn( p_demux, "separator %s does not match %s", psz_line,
                           p_sys->psz_separator );
@@ -527,7 +607,11 @@ static int MimeDemux( demux_t *p_demux )
             }
         }
 
+        //some vendors use as separator same string which was defined in ContentType
+        //without additional "--"
         if( !strncmp( p_sys->psz_separator, (char *)(p_sys->p_peek + i + 2),
+                      strlen( p_sys->psz_separator ) ) ||
+            !strncmp( p_sys->psz_separator, (char *)(p_sys->p_peek + i),
                       strlen( p_sys->psz_separator ) ) )
         {
             break;
-- 
1.7.7.1.msysgit.0




More information about the vlc-devel mailing list