summaryrefslogtreecommitdiffstats
path: root/stream
diff options
context:
space:
mode:
Diffstat (limited to 'stream')
-rw-r--r--stream/stream.c31
-rw-r--r--stream/stream.h2
-rw-r--r--stream/stream_dvd.c4
-rw-r--r--stream/stream_file.c4
4 files changed, 41 insertions, 0 deletions
diff --git a/stream/stream.c b/stream/stream.c
index a4d9238d46..4160e7267e 100644
--- a/stream/stream.c
+++ b/stream/stream.c
@@ -116,6 +116,37 @@ static const stream_info_t *const auto_open_streams[] = {
static int stream_seek_unbuffered(stream_t *s, int64_t newpos);
+static int from_hex(unsigned char c)
+{
+ if (c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ if (c >= 'A' && c <= 'F')
+ return c - 'A' + 10;
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ return -1;
+}
+
+// Replace escape sequences in an URL (or a part of an URL)
+void mp_url_unescape_inplace(char *buf)
+{
+ int len = strlen(buf);
+ int o = 0;
+ for (int i = 0; i < len; i++) {
+ unsigned char c = buf[i];
+ if (c == '%' && i + 2 < len) { //must have 2 more chars
+ int c1 = from_hex(buf[i + 1]);
+ int c2 = from_hex(buf[i + 2]);
+ if (c1 >= 0 && c2 >= 0) {
+ c = c1 * 16 + c2;
+ i = i + 2; //only skip next 2 chars if valid esc
+ }
+ }
+ buf[o++] = c;
+ }
+ buf[o++] = '\0';
+}
+
static const char *find_url_opt(struct stream *s, const char *opt)
{
for (int n = 0; s->info->url_options && s->info->url_options[n][0]; n++) {
diff --git a/stream/stream.h b/stream/stream.h
index 9800efbafd..e928a258b6 100644
--- a/stream/stream.h
+++ b/stream/stream.h
@@ -260,4 +260,6 @@ typedef struct {
int channels;
} stream_language_t;
+void mp_url_unescape_inplace(char *buf);
+
#endif /* MPLAYER_STREAM_H */
diff --git a/stream/stream_dvd.c b/stream/stream_dvd.c
index 624ea4c672..c9473c4b67 100644
--- a/stream/stream_dvd.c
+++ b/stream/stream_dvd.c
@@ -1050,6 +1050,10 @@ static int ifo_stream_open (stream_t *stream, int mode)
stream->priv = priv;
*priv = stream_priv_dflts;
+ // "file://" prefix -> decode URL-style escapes
+ if (strlen(stream->url) > strlen(stream->path))
+ mp_url_unescape_inplace(stream->path);
+
int len = strlen(stream->path);
if (len < 4 || strcasecmp (stream->path + len - 4, ".ifo"))
return STREAM_UNSUPPORTED;
diff --git a/stream/stream_file.c b/stream/stream_file.c
index dc85314f71..1e9f372ba4 100644
--- a/stream/stream_file.c
+++ b/stream/stream_file.c
@@ -125,6 +125,10 @@ static int open_f(stream_t *stream, int mode)
return STREAM_UNSUPPORTED;
}
+ // "file://" prefix -> decode URL-style escapes
+ if (strlen(stream->url) > strlen(stream->path))
+ mp_url_unescape_inplace(stream->path);
+
#if HAVE_DOS_PATHS
// extract '/' from '/x:/path'
if( filename[ 0 ] == '/' && filename[ 1 ] && filename[ 2 ] == ':' )