Commit a34c4c52 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Use hash instead of arobas for seekpoint (fix #5022)

Instead of ignoring the URI anchor (if present), the input now parses
it for start and stop seek points. This is non-standard - anchors are
normally names found in HTML document. But at least, it does not
interfere with parsing real-world URLs (see the bug #5022 for example).

Also contrary to stream output chain, the hash symbol should be free of
shell quoting issues when used this.
parent 8693bcb2
...@@ -85,7 +85,7 @@ static void UpdateGenericFromAccess( input_thread_t * ); ...@@ -85,7 +85,7 @@ static void UpdateGenericFromAccess( input_thread_t * );
static int UpdateTitleSeekpointFromDemux( input_thread_t * ); static int UpdateTitleSeekpointFromDemux( input_thread_t * );
static void UpdateGenericFromDemux( input_thread_t * ); static void UpdateGenericFromDemux( input_thread_t * );
static void MRLSections( char *, int *, int *, int *, int *); static void MRLSections( const char *, int *, int *, int *, int *);
static input_source_t *InputSourceNew( input_thread_t *); static input_source_t *InputSourceNew( input_thread_t *);
static int InputSourceInit( input_thread_t *, input_source_t *, static int InputSourceInit( input_thread_t *, input_source_t *,
...@@ -2356,9 +2356,7 @@ static int InputSourceInit( input_thread_t *p_input, ...@@ -2356,9 +2356,7 @@ static int InputSourceInit( input_thread_t *p_input,
input_source_t *in, const char *psz_mrl, input_source_t *in, const char *psz_mrl,
const char *psz_forced_demux, bool b_in_can_fail ) const char *psz_forced_demux, bool b_in_can_fail )
{ {
const char *psz_access; const char *psz_access, *psz_demux, *psz_path, *psz_anchor;
const char *psz_demux;
char *psz_path;
char *psz_var_demux = NULL; char *psz_var_demux = NULL;
double f_fps; double f_fps;
...@@ -2369,22 +2367,15 @@ static int InputSourceInit( input_thread_t *p_input, ...@@ -2369,22 +2367,15 @@ static int InputSourceInit( input_thread_t *p_input,
goto error; goto error;
/* Split uri */ /* Split uri */
input_SplitMRL( &psz_access, &psz_demux, &psz_path, psz_dup ); input_SplitMRL( &psz_access, &psz_demux, &psz_path, &psz_anchor, psz_dup );
msg_Dbg( p_input, "`%s' gives access `%s' demux `%s' path `%s'", msg_Dbg( p_input, "`%s' gives access `%s' demux `%s' path `%s'",
psz_mrl, psz_access, psz_demux, psz_path ); psz_mrl, psz_access, psz_demux, psz_path );
if( !p_input->b_preparsing ) if( !p_input->b_preparsing )
{ {
/* Hack to allow udp://@:port syntax */ /* Find optional titles and seekpoints */
if( !psz_access || MRLSections( psz_anchor, &in->i_title_start, &in->i_title_end,
(strncmp( psz_access, "udp", 3 ) && &in->i_seekpoint_start, &in->i_seekpoint_end );
strncmp( psz_access, "rtp", 3 )) )
{
/* Find optional titles and seekpoints */
MRLSections( psz_path, &in->i_title_start, &in->i_title_end,
&in->i_seekpoint_start, &in->i_seekpoint_end );
}
if( psz_forced_demux && *psz_forced_demux ) if( psz_forced_demux && *psz_forced_demux )
{ {
psz_demux = psz_forced_demux; psz_demux = psz_forced_demux;
...@@ -3032,52 +3023,57 @@ static void input_ChangeState( input_thread_t *p_input, int i_state ) ...@@ -3032,52 +3023,57 @@ static void input_ChangeState( input_thread_t *p_input, int i_state )
* MRLSplit: parse the access, demux and url part of the * MRLSplit: parse the access, demux and url part of the
* Media Resource Locator. * Media Resource Locator.
*****************************************************************************/ *****************************************************************************/
void input_SplitMRL( const char **ppsz_access, const char **ppsz_demux, void input_SplitMRL( const char **access, const char **demux,
char **ppsz_path, char *psz_dup ) const char **path, const char **anchor, char *buf )
{ {
char *p; char *p;
/* Separate <path> from <access>[/<demux>]:// */ /* Separate <path> from <access>[/<demux>]:// */
p = strstr( psz_dup, "://" ); p = strstr( buf, "://" );
if( p != NULL ) if( p != NULL )
{ {
*p = '\0'; *p = '\0';
p += 3; /* skips "://" */ p += 3; /* skips "://" */
*ppsz_path = p; *path = p;
/* Remove HTML anchor if present (not supported). /* Remove HTML anchor if present (not supported).
* The hash symbol itself should be URI-encoded. */ * The hash symbol itself should be URI-encoded. */
p = strchr( p, '#' ); p = strchr( p, '#' );
if( p ) if( p != NULL )
*p = '\0'; {
*(p++) = '\0';
*anchor = p;
}
else
*anchor = "";
} }
else else
{ {
#ifndef NDEBUG #ifndef NDEBUG
fprintf( stderr, "%s(\"%s\") probably not a valid URI!\n", __func__, fprintf( stderr, "%s(\"%s\") probably not a valid URI!\n", __func__,
psz_dup ); buf );
#endif #endif
/* Note: this is a valid non const pointer to "": */ /* Note: this is a valid non const pointer to "": */
*ppsz_path = psz_dup + strlen( psz_dup ); *path = buf + strlen( buf );
} }
/* Separate access from demux */ /* Separate access from demux */
p = strchr( psz_dup, '/' ); p = strchr( buf, '/' );
if( p != NULL ) if( p != NULL )
{ {
*(p++) = '\0'; *(p++) = '\0';
if( p[0] == '$' ) if( p[0] == '$' )
p++; p++;
*ppsz_demux = p; *demux = p;
} }
else else
*ppsz_demux = ""; *demux = "";
/* We really don't want module name substitution here! */ /* We really don't want module name substitution here! */
p = psz_dup; p = buf;
if( p[0] == '$' ) if( p[0] == '$' )
p++; p++;
*ppsz_access = p; *access = p;
} }
static const char *MRLSeekPoint( const char *str, int *title, int *chapter ) static const char *MRLSeekPoint( const char *str, int *title, int *chapter )
...@@ -3111,18 +3107,12 @@ static const char *MRLSeekPoint( const char *str, int *title, int *chapter ) ...@@ -3111,18 +3107,12 @@ static const char *MRLSeekPoint( const char *str, int *title, int *chapter )
* Syntax: * Syntax:
* [url][@[title_start][:chapter_start][-[title_end][:chapter_end]]] * [url][@[title_start][:chapter_start][-[title_end][:chapter_end]]]
*****************************************************************************/ *****************************************************************************/
static void MRLSections( char *psz_source, static void MRLSections( const char *p,
int *pi_title_start, int *pi_title_end, int *pi_title_start, int *pi_title_end,
int *pi_chapter_start, int *pi_chapter_end ) int *pi_chapter_start, int *pi_chapter_end )
{ {
*pi_title_start = *pi_title_end = *pi_chapter_start = *pi_chapter_end = -1; *pi_title_start = *pi_title_end = *pi_chapter_start = *pi_chapter_end = -1;
/* Start by parsing titles and chapters */
char *psz = strrchr( psz_source, '@' );
if( psz == NULL )
return;
const char *p = psz + 1;
int title_start, chapter_start, title_end, chapter_end; int title_start, chapter_start, title_end, chapter_end;
if( *p != '-' ) if( *p != '-' )
...@@ -3142,7 +3132,6 @@ static void MRLSections( char *psz_source, ...@@ -3142,7 +3132,6 @@ static void MRLSections( char *psz_source,
*pi_title_end = title_end; *pi_title_end = title_end;
*pi_chapter_start = chapter_start; *pi_chapter_start = chapter_start;
*pi_chapter_end = chapter_end; *pi_chapter_end = chapter_end;
*psz = '\0';
} }
/***************************************************************************** /*****************************************************************************
......
...@@ -244,6 +244,7 @@ char **subtitles_Detect( input_thread_t *, char* path, const char *fname ); ...@@ -244,6 +244,7 @@ char **subtitles_Detect( input_thread_t *, char* path, const char *fname );
int subtitles_Filter( const char *); int subtitles_Filter( const char *);
/* input.c */ /* input.c */
void input_SplitMRL( const char **, const char **, char **, char * ); void input_SplitMRL( const char **, const char **, const char **,
const char **, char * );
#endif #endif
...@@ -247,8 +247,7 @@ void stream_CommonDelete( stream_t *s ) ...@@ -247,8 +247,7 @@ void stream_CommonDelete( stream_t *s )
****************************************************************************/ ****************************************************************************/
stream_t *stream_UrlNew( vlc_object_t *p_parent, const char *psz_url ) stream_t *stream_UrlNew( vlc_object_t *p_parent, const char *psz_url )
{ {
const char *psz_access, *psz_demux; const char *psz_access, *psz_demux, *psz_path, *psz_anchor;
char *psz_path;
access_t *p_access; access_t *p_access;
stream_t *p_res; stream_t *p_res;
...@@ -257,7 +256,7 @@ stream_t *stream_UrlNew( vlc_object_t *p_parent, const char *psz_url ) ...@@ -257,7 +256,7 @@ stream_t *stream_UrlNew( vlc_object_t *p_parent, const char *psz_url )
char psz_dup[strlen( psz_url ) + 1]; char psz_dup[strlen( psz_url ) + 1];
strcpy( psz_dup, psz_url ); strcpy( psz_dup, psz_url );
input_SplitMRL( &psz_access, &psz_demux, &psz_path, psz_dup ); input_SplitMRL( &psz_access, &psz_demux, &psz_path, &psz_anchor, psz_dup );
/* Now try a real access */ /* Now try a real access */
p_access = access_New( p_parent, NULL, psz_access, psz_demux, psz_path ); p_access = access_New( p_parent, NULL, psz_access, psz_demux, psz_path );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment