[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