[vlc-devel] [PATCH 14/21] input/input: fix-up of helper-function MRLSections

Filip Roséen filip at atch.se
Sun Jul 31 22:42:23 CEST 2016


MRLSections has been around for a long time and it was sure in need of
a minor clean-up, not only to make the implementation easier to reason
about but also to make it more robustness.

The function now returns an error-code signaling whether parsing was
successful or not, as well as making sure that every byte present in
the passed data-string is consumed in order for it to be successful.
---
 src/input/input.c | 87 +++++++++++++++++++++++--------------------------------
 1 file changed, 37 insertions(+), 50 deletions(-)

diff --git a/src/input/input.c b/src/input/input.c
index e8a6844..0da797c 100644
--- a/src/input/input.c
+++ b/src/input/input.c
@@ -35,6 +35,7 @@
 #include <assert.h>
 #include <math.h>
 #include <sys/stat.h>
+#include <stdio.h>
 
 #include "input_internal.h"
 #include "event.h"
@@ -74,7 +75,7 @@ static int  UpdateTitleSeekpointFromDemux( input_thread_t * );
 static void UpdateGenericFromDemux( input_thread_t * );
 static void UpdateTitleListfromDemux( input_thread_t * );
 
-static void MRLSections( const char *, int *, int *, int *, int *);
+static int MRLSections( const char *, input_source_t* );
 
 static input_source_t *InputSourceNew( input_thread_t *, const char *,
                                        const char *psz_forced_demux,
@@ -2229,8 +2230,10 @@ static input_source_t *InputSourceNew( input_thread_t *p_input,
              psz_mrl, psz_access, psz_demux, psz_path );
 
     /* Find optional titles and seekpoints */
-    MRLSections( psz_anchor, &in->i_title_start, &in->i_title_end,
-                 &in->i_seekpoint_start, &in->i_seekpoint_end );
+    in->i_title_start = in->i_title_end =
+        in->i_seekpoint_start = in->i_seekpoint_end = -1;
+
+    MRLSections( psz_anchor, in );
 
     if( p_input->p->master == NULL /* XXX ugly */)
     {   /* On master stream only, use input-list */
@@ -2818,65 +2821,49 @@ void input_SplitMRL( const char **access, const char **demux,
     *access = p;
 }
 
-static const char *MRLSeekPoint( const char *str, int *title, int *chapter )
+/*****************************************************************************
+ * MRLSections: parse title and seekpoint info from the passe
+ *
+ * Syntax:
+ * [url][#[title_start][:chapter_start][-[title_end][:chapter_end]]]
+ *****************************************************************************/
+
+static int MRLSeekPoint( const char *data, int *title, int *chapter )
 {
-    char *end;
-    unsigned long u;
+    int consumed;
 
-    /* Look for the title */
-    u = strtoul( str, &end, 0 );
-    *title = (str == end || u > (unsigned long)INT_MAX) ? -1 : (int)u;
-    str = end;
+    if( sscanf( data, "%d%n:%d%n", title, &consumed, chapter, &consumed ) < 1 )
+      return VLC_EGENERIC;
 
-    /* Look for the chapter */
-    if( *str == ':' )
-    {
-        str++;
-        u = strtoul( str, &end, 0 );
-        *chapter = (str == end || u > (unsigned long)INT_MAX) ? -1 : (int)u;
-        str = end;
-    }
-    else
-        *chapter = -1;
+    if( strlen( data ) != (size_t)consumed )
+        return VLC_EGENERIC;
 
-    return str;
+    return VLC_SUCCESS;
 }
 
-
-/*****************************************************************************
- * MRLSections: parse title and seekpoint info from the Media Resource Locator.
- *
- * Syntax:
- * [url][@[title_start][:chapter_start][-[title_end][:chapter_end]]]
- *****************************************************************************/
-static void MRLSections( const char *p,
-                         int *pi_title_start, int *pi_title_end,
-                         int *pi_chapter_start, int *pi_chapter_end )
+static int MRLSections( const char* data, input_source_t* in )
 {
-    *pi_title_start = *pi_title_end = *pi_chapter_start = *pi_chapter_end = -1;
+    char start[64], end[64];
+    int tell;
+    int ret = VLC_SUCCESS;
 
-    int title_start, chapter_start, title_end, chapter_end;
-
-    if( !p )
-        return;
+    switch( sscanf( data, "%63[^-]%n-%64s%n", start, &tell, end, &tell ) )
+    {
+        case 2:
+            ret |= MRLSeekPoint( end, &in->i_title_end, &in->i_seekpoint_end );
 
-    if( *p != '-' )
-        p = MRLSeekPoint( p, &title_start, &chapter_start );
-    else
-        title_start = chapter_start = -1;
+        case 1:
+            ret |= MRLSeekPoint( start, &in->i_title_start, &in->i_seekpoint_start );
+            break;
 
-    if( *p == '-' )
-        p = MRLSeekPoint( p + 1, &title_end, &chapter_end );
-    else
-        title_end = chapter_end = -1;
+        default:
+            return VLC_EGENERIC;
+    }
 
-    if( *p ) /* syntax error */
-        return;
+    if( strlen( data ) != (size_t)tell )
+        return VLC_EGENERIC;
 
-    *pi_title_start = title_start;
-    *pi_title_end = title_end;
-    *pi_chapter_start = chapter_start;
-    *pi_chapter_end = chapter_end;
+    return ret;
 }
 
 static int input_SlaveSourceAdd( input_thread_t *p_input,
-- 
2.9.2



More information about the vlc-devel mailing list