[vlc-devel] [PATCH 2/3] input/input: input_SubtitleFile2Uri: handle URIs

Filip Roséen filip at atch.se
Thu Jan 12 19:34:41 CET 2017


The previous implementation assumed that the data passed was a local
path, which limited the usability of the function (effectively
preventing subtitles passed as URIs from being added).

These changes allow both local paths and URIs to be handled by the
function, effectively making sure that file://... are subject to
transformation (while leaving other entities untouched).

The function has also been renamed in order to better reflect the
implementation.

refs #17657
---
 src/input/input.c | 95 +++++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 74 insertions(+), 21 deletions(-)

diff --git a/src/input/input.c b/src/input/input.c
index 35529286bd..d0b9f208b2 100644
--- a/src/input/input.c
+++ b/src/input/input.c
@@ -107,7 +107,7 @@ static void AppendAttachment( int *pi_attachment, input_attachment_t ***ppp_atta
 
 static int input_SlaveSourceAdd( input_thread_t *, enum slave_type,
                                  const char *, unsigned );
-static char *input_SubtitleFile2Uri( input_thread_t *, const char * );
+static char *input_GetSubtitleURI( input_thread_t *, const char *, bool );
 static void input_ChangeState( input_thread_t *p_input, int i_state ); /* TODO fix name */
 
 #undef input_Create
@@ -1052,7 +1052,7 @@ static void LoadSlaves( input_thread_t *p_input )
     if( psz_subtitle != NULL )
     {
         msg_Dbg( p_input, "forced subtitle: %s", psz_subtitle );
-        char *psz_uri = input_SubtitleFile2Uri( p_input, psz_subtitle );
+        char *psz_uri = input_GetSubtitleURI( p_input, psz_subtitle, false );
         free( psz_subtitle );
         psz_subtitle = NULL;
         if( psz_uri != NULL )
@@ -2053,7 +2053,7 @@ static bool Control( input_thread_t *p_input,
         case INPUT_CONTROL_ADD_SUBTITLE:
             if( val.psz_string )
             {
-                char *psz_uri = input_SubtitleFile2Uri( p_input, val.psz_string );
+                char *psz_uri = input_GetSubtitleURI( p_input, val.psz_string, false );
                 if( psz_uri != NULL )
                 {
                     input_SlaveSourceAdd( p_input, SLAVE_TYPE_SPU, psz_uri,
@@ -3168,35 +3168,88 @@ static int input_SlaveSourceAdd( input_thread_t *p_input,
     return VLC_SUCCESS;
 }
 
-static char *input_SubtitleFile2Uri( input_thread_t *p_input,
-                                     const char *psz_subtitle )
+static char *input_GetSubtitleURI( input_thread_t *p_input,
+                                   const char *psz_subtitle,
+                                   bool b_strict_extensions )
 {
-    /* if we are provided a subtitle.sub file,
-     * see if we don't have a subtitle.idx and use it instead */
-    char *psz_idxpath = NULL;
-    char *psz_extension = strrchr( psz_subtitle, '.');
-    if( psz_extension && strcmp( psz_extension, ".sub" ) == 0 )
-    {
-        psz_idxpath = strdup( psz_subtitle );
-        if( psz_idxpath )
+    struct {
+        bool is_uri;
+        bool is_local;
+        bool has_query;
+        char* psz_result;
+
+    } info = { false, false, false, NULL };
+
+    { /* decide whether input is a local path or not */
+        vlc_url_t url;
+
+        if( vlc_UrlParse( &url, psz_subtitle ) || url.psz_protocol == NULL )
         {
+            info.is_local = true;
+            info.psz_result = vlc_path2uri( psz_subtitle, NULL );
+        }
+        else
+        {
+            info.is_uri = true;
+            info.is_local = !strcasecmp( url.psz_protocol, "file" );
+            info.has_query = url.psz_option != NULL;
+
+            info.psz_result = vlc_uri_compose( &url );
+        }
+
+        vlc_UrlClean( &url );
+    }
+
+
+    if( info.psz_result == NULL )
+        goto invalid;
+
+
+    if( b_strict_extensions )
+    {
+        if( info.has_query )
+            goto invalid;
+
+        if( subtitles_Filter( info.psz_result ) == 0 )
+            goto invalid;
+    }
+
+
+    if( info.is_local )
+    {
+        char const* psz_ext = strrchr( info.psz_result, '.' );
+
+        if( psz_ext && strcasecmp( psz_ext, ".sub" ) == 0 )
+        {
+            char* psz_probe = vlc_uri2path( info.psz_result );
             struct stat st;
 
-            psz_extension = psz_extension - psz_subtitle + psz_idxpath;
-            strcpy( psz_extension, ".idx" );
+            if( unlikely( !psz_probe ) )
+                goto invalid;
+
+            /* replace the extension */
+            strcpy( strrchr( psz_probe, '.' ), ".idx" );
 
-            if( !vlc_stat( psz_idxpath, &st ) && S_ISREG( st.st_mode ) )
+            /* check if file exists */
+            if( vlc_stat( psz_probe, &st ) == VLC_SUCCESS &&
+                S_ISREG( st.st_mode ) )
             {
                 msg_Dbg( p_input, "using %s as subtitle file instead of %s",
-                         psz_idxpath, psz_subtitle );
-                psz_subtitle = psz_idxpath;
+                                  psz_probe, info.psz_result );
+
+                /* change the extension of result */
+                strcpy( strrchr( info.psz_result, '.' ), ".idx" );
             }
+
+            free( psz_probe );
         }
     }
 
-    char *psz_uri = vlc_path2uri( psz_subtitle, NULL );
-    free( psz_idxpath );
-    return psz_uri;
+    return info.psz_result;
+
+invalid:
+    free( info.psz_result );
+    return NULL;
 }
 
 /*****************************************************************************
-- 
2.11.0



More information about the vlc-devel mailing list