[vlc-devel] [PATCH] podcast: accept "text/xml" mime type

Thomas Guillem thomas at gllm.fr
Thu Nov 2 11:24:57 CET 2017


Check for the "rss" node from the Open function in that case.

Fixes #18995
---

NEWS: do the "rss" node check only for the "text/xml" case. This still can fail
because of the 2048 peek but this doesn't introduce an useless check that can
fail for "application/rss+xml" mime type.

 modules/demux/playlist/playlist.c |  2 +-
 modules/demux/playlist/playlist.h |  1 +
 modules/demux/playlist/podcast.c  | 64 +++++++++++++++++++++++++++++++++------
 3 files changed, 56 insertions(+), 11 deletions(-)

diff --git a/modules/demux/playlist/playlist.c b/modules/demux/playlist/playlist.c
index 449d5fd5b7..e4105e11fc 100644
--- a/modules/demux/playlist/playlist.c
+++ b/modules/demux/playlist/playlist.c
@@ -90,7 +90,7 @@ vlc_module_begin ()
         set_description( N_("Podcast parser") )
         add_shortcut( "podcast" )
         set_capability( "stream_filter", 10 )
-        set_callbacks( Import_podcast, NULL )
+        set_callbacks( Import_podcast, Close_podcast )
     add_submodule ()
         set_description( N_("XSPF playlist import") )
         set_capability( "stream_filter", 10 )
diff --git a/modules/demux/playlist/playlist.h b/modules/demux/playlist/playlist.h
index d9a6d7c478..fe1f54cabf 100644
--- a/modules/demux/playlist/playlist.h
+++ b/modules/demux/playlist/playlist.h
@@ -36,6 +36,7 @@ int Import_B4S ( vlc_object_t * );
 int Import_DVB ( vlc_object_t * );
 
 int Import_podcast ( vlc_object_t * );
+void Close_podcast ( vlc_object_t * );
 
 int Import_xspf ( vlc_object_t * );
 void Close_xspf ( vlc_object_t * );
diff --git a/modules/demux/playlist/podcast.c b/modules/demux/playlist/podcast.c
index 8c47d5ab6f..f88d7ce06a 100644
--- a/modules/demux/playlist/podcast.c
+++ b/modules/demux/playlist/podcast.c
@@ -49,7 +49,53 @@ int Import_podcast( vlc_object_t *p_this )
     stream_t *p_demux = (stream_t *)p_this;
 
     CHECK_FILE(p_demux);
-    if( !stream_IsMimeType( p_demux->p_source, "application/rss+xml" ) )
+
+    if( stream_IsMimeType( p_demux->p_source, "application/xml" ) )
+        p_demux->p_sys = xml_ReaderCreate( p_demux, p_demux->p_source );
+    else if( stream_IsMimeType( p_demux->p_source, "text/xml" ) )
+    {
+        /* XML: check if the root node is "rss". Use a specific peeked
+         * probestream in order to not modify the source state while probing.
+         * */
+        uint8_t *p_peek;
+        ssize_t i_peek = vlc_stream_Peek( p_demux->p_source,
+                                          (const uint8_t **) &p_peek, 2048 );
+        if( unlikely( i_peek <= 0 ) )
+            return VLC_EGENERIC;
+
+        stream_t *p_probestream =
+            vlc_stream_MemoryNew( p_demux->p_source, p_peek, i_peek, true );
+        if( unlikely( !p_probestream ) )
+            return VLC_EGENERIC;
+
+        xml_reader_t *p_xml_reader = xml_ReaderCreate( p_demux, p_probestream );
+        if( !p_xml_reader )
+        {
+            vlc_stream_Delete( p_probestream );
+            return VLC_EGENERIC;
+        }
+
+        const char *node;
+        int ret;
+        if( ( ret = xml_ReaderNextNode( p_xml_reader, &node ) ) != XML_READER_STARTELEM
+         || strcmp( node, "rss" ) )
+        {
+            if( ret != XML_READER_STARTELEM )
+                msg_Err( p_demux, "invalid file (no root node)" );
+            else
+                msg_Err( p_demux, "invalid root node <%s>", node );
+            vlc_stream_Delete( p_probestream );
+            xml_ReaderDelete( p_xml_reader );
+            return VLC_EGENERIC;
+        }
+
+        p_demux->p_sys = xml_ReaderReset( p_xml_reader, p_demux->p_source );
+        vlc_stream_Delete( p_probestream );
+    }
+    else
+        return VLC_EGENERIC;
+
+    if( unlikely( !p_demux->p_sys ) )
         return VLC_EGENERIC;
 
     p_demux->pf_readdir = ReadDir;
@@ -65,7 +111,6 @@ static int ReadDir( stream_t *p_demux, input_item_node_t *p_subitems )
     bool b_item = false;
     bool b_image = false;
 
-    xml_reader_t *p_xml_reader;
     char *psz_elname = NULL;
     char *psz_item_mrl = NULL;
     char *psz_item_size = NULL;
@@ -84,10 +129,7 @@ static int ReadDir( stream_t *p_demux, input_item_node_t *p_subitems )
     input_item_t *p_input;
 
     input_item_t *p_current_input = GetCurrentItem(p_demux);
-
-    p_xml_reader = xml_ReaderCreate( p_demux, p_demux->p_source );
-    if( !p_xml_reader )
-        goto error;
+    xml_reader_t *p_xml_reader = p_demux->p_sys;
 
     /* xml */
     /* check root node */
@@ -313,7 +355,6 @@ static int ReadDir( stream_t *p_demux, input_item_node_t *p_subitems )
 
     free( psz_art_url );
     free( psz_elname );
-    xml_ReaderDelete( p_xml_reader );
 
     return VLC_SUCCESS;
 
@@ -332,12 +373,15 @@ error:
     free( psz_art_url );
     free( psz_elname );
 
-    if( p_xml_reader )
-        xml_ReaderDelete( p_xml_reader );
-
     return VLC_EGENERIC;
 }
 
+void Close_podcast( vlc_object_t *p_this )
+{
+    stream_t *p_demux = (stream_t *)p_this;
+    xml_ReaderDelete( p_demux->p_sys );
+}
+
 static mtime_t strTimeToMTime( const char *psz )
 {
     int h, m, s;
-- 
2.11.0



More information about the vlc-devel mailing list