Skip to content
Snippets Groups Projects
Commit f6d5ec36 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont
Browse files

playlist: partly fix relative URL resolution

parent 73071861
No related branches found
No related tags found
No related merge requests found
......@@ -220,64 +220,77 @@ input_item_t * GetCurrentItem(demux_t *p_demux)
}
/**
* Find directory part of the path to the playlist file, in case of
* relative paths inside
* Computes the base URL.
*
* Rebuilds the base URL for the playlist.
*/
char *FindPrefix( demux_t *p_demux )
char *FindPrefix(demux_t *p_demux)
{
char *psz_url;
if( asprintf( &psz_url, "%s://%s", p_demux->psz_access,
p_demux->psz_location ) == -1 )
return NULL;
char *url;
char *psz_file = strrchr( psz_url, '/' );
assert( psz_file != NULL );
psz_file[1] = '\0';
return psz_url;
if (unlikely(asprintf(&url, "%s://%s", p_demux->psz_access,
p_demux->psz_location) == -1))
url = NULL;
return url;
}
/**
* Add the directory part of the playlist file to the start of the
* mrl, if the mrl is a relative file path
* Resolves a playlist location.
*
* Resolves a resource location within the playlist relative to the playlist
* base URL.
*/
char *ProcessMRL( const char *psz_mrl, const char *psz_prefix )
char *ProcessMRL(const char *str, const char *base)
{
/* Check for a protocol name.
* for URL, we should look for "://"
* for MRL (Media Resource Locator) ([[<access>][/<demux>]:][<source>]),
* we should look for ":", so we end up looking simply for ":"
* PB: on some file systems, ':' are valid characters though */
/* Simple cases first */
if( !psz_mrl || !*psz_mrl )
if (str == NULL)
return NULL;
/* Check if the line specifies an absolute path */
/* FIXME: that's wrong if the playlist is not a local file */
if( *psz_mrl == DIR_SEP_CHAR )
goto uri;
#if defined( _WIN32 ) || defined( __OS2__ )
/* Drive letter (this assumes URL scheme are not a single character) */
if( isalpha((unsigned char)psz_mrl[0]) && psz_mrl[1] == ':' )
goto uri;
#if (DIR_SEP_CHAR == '\\')
/* UNC path prefix? */
if (strncmp(str, "\\\\", 2) == 0
/* Drive letter prefix? */
|| (isalpha((unsigned char)str[0]) && str[1] == ':'))
/* Assume this an absolute file path - usually true */
return vlc_path2uri(str, NULL);
/* TODO: drive-relative path: if (str[0] == '\\') */
#endif
if( strstr( psz_mrl, "://" ) )
return strdup( psz_mrl );
/* This a relative path, prepend the prefix */
char *ret;
char *postfix = vlc_uri_encode( psz_mrl );
/* FIXME: postfix may not be encoded correctly (esp. slashes) */
if( postfix == NULL
|| asprintf( &ret, "%s%s", psz_prefix, postfix ) == -1 )
ret = NULL;
free( postfix );
return ret;
uri:
return vlc_path2uri( psz_mrl, NULL );
#ifdef HAVE_OPEN_MEMSTREAM
/* The base URL is always an URL: it is the URL of the playlist.
*
* However it is not always known if the input string is a valid URL, a
* broken URL or a local file path. As a rule, if it looks like a valid
* URL, it must be treated as such, since most playlist formats use URLs.
*
* There are a few corner cases file paths that look like an URL but whose
* URL representation does not match, notably when they contain a
* percentage sign, a colon, a hash or a question mark. Luckily, they are
* rather exceptional (and can be encoded as URL to make the playlist
* work properly).
*
* If the input is not a valid URL, then we try to fix it up. It works in
* all cases for URLs with incorrectly encoded segments, such as URLs with
* white spaces or non-ASCII Unicode code points. It also works in most
* cases where the input is a Unix-style file path, but not all.
* It fails miserably if the playlist character encoding is misdetected.
*/
char *rel = vlc_uri_fixup(str);
if (rel != NULL)
str = rel;
char *abs = vlc_uri_resolve(base, str);
free(rel);
return abs;
#else
const char *split = strrchr(base, '/');
char *abs;
assert(split != NULL);
if (asprintf(&abs, "%.*s/%s", (int)(split - base), base, str) == -1)
abs = NULL;
return abs;
#endif
}
/**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment