summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog2
-rw-r--r--src/input/input_file.c44
-rw-r--r--src/xine-engine/xine.c33
3 files changed, 33 insertions, 46 deletions
diff --git a/ChangeLog b/ChangeLog
index 54299baf0..784ea3dbd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -28,6 +28,8 @@ xine-lib (1.1.9) (unreleased)
* Enabled the WMV VC1 (ffmpeg) codec.
* Fixed a crash that happened when a video output was closed
* Made the Real demuxer recognise http references.
+ * Require correct URL encoding of '#'s which aren't separators.
+ * Don't decode %nn in raw filenames. [Bug 1784272]
xine-lib (1.1.8)
* Send a channel-changed event to the frontend when receiving the SYNC
diff --git a/src/input/input_file.c b/src/input/input_file.c
index abb689e39..f81103dcd 100644
--- a/src/input/input_file.c
+++ b/src/input/input_file.c
@@ -340,7 +340,7 @@ static int file_plugin_open (input_plugin_t *this_gen ) {
lprintf("file_plugin_open\n");
- if (strncasecmp (this->mrl, "file:", 5) == 0)
+ if (strncasecmp (this->mrl, "file:/", 6) == 0)
{
if (strncasecmp (this->mrl, "file://localhost/", 16) == 0)
filename = decode_uri(&(this->mrl[16]));
@@ -350,43 +350,27 @@ static int file_plugin_open (input_plugin_t *this_gen ) {
filename = decode_uri(&(this->mrl[5]));
}
else
- filename = decode_uri(this->mrl);
+ filename = strdup(this->mrl); /* NEVER unescape plain file names! */
this->fh = open (filename, O_RDONLY|O_BINARY);
-
- free(filename);
if (this->fh == -1) {
- /* try again without unescaping; such MRLs might be invalid,
- * but we are a nice software */
- if (strncasecmp (this->mrl, "file:", 5) == 0)
- {
- if (strncasecmp (this->mrl, "file://localhost/", 16) == 0)
- this->fh = open(&this->mrl[16], O_RDONLY|O_BINARY);
- else if (strncasecmp (this->mrl, "file://127.0.0.1/", 16) == 0)
- this->fh = open(&this->mrl[16], O_RDONLY|O_BINARY);
- else
- this->fh = open(&this->mrl[5], O_RDONLY|O_BINARY);
+ if (errno == EACCES) {
+ _x_message(this->stream, XINE_MSG_PERMISSION_ERROR, this->mrl, NULL);
+ xine_log (this->stream->xine, XINE_LOG_MSG,
+ _("input_file: Permission denied: >%s<\n"), this->mrl);
+ } else if (errno == ENOENT) {
+ _x_message(this->stream, XINE_MSG_FILE_NOT_FOUND, this->mrl, NULL);
+ xine_log (this->stream->xine, XINE_LOG_MSG,
+ _("input_file: File not found: >%s<\n"), this->mrl);
}
- else
- this->fh = open(this->mrl, O_RDONLY|O_BINARY);
-
- if (this->fh == -1) {
- if (errno == EACCES) {
- _x_message(this->stream, XINE_MSG_PERMISSION_ERROR, this->mrl, NULL);
- xine_log (this->stream->xine, XINE_LOG_MSG,
- _("input_file: Permission denied: >%s<\n"), this->mrl);
- return -1;
- } else if (errno == ENOENT) {
- _x_message(this->stream, XINE_MSG_FILE_NOT_FOUND, this->mrl, NULL);
- xine_log (this->stream->xine, XINE_LOG_MSG,
- _("input_file: File not found: >%s<\n"), this->mrl);
- }
- return -1;
- }
+ free(filename);
+ return -1;
}
+ free(filename);
+
#ifdef HAVE_MMAP
this->mmap_on = 0;
this->mmap_base = NULL;
diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c
index 097ce99ef..f3b59942d 100644
--- a/src/xine-engine/xine.c
+++ b/src/xine-engine/xine.c
@@ -35,6 +35,7 @@
#include <pthread.h>
#include <stdarg.h>
#include <stdio.h>
+#include <ctype.h>
#if defined (__linux__) || defined (__GLIBC__)
#include <endian.h>
#elif defined (__FreeBSD__)
@@ -779,9 +780,9 @@ void _x_flush_events_queues (xine_stream_t *stream) {
pthread_mutex_unlock (&stream->event_queues_lock);
}
-static int open_internal (xine_stream_t *stream, const char *mrl) {
+/*static*/ int open_internal (xine_stream_t *stream, const char *mrl) {
- const char *stream_setup;
+ const char *stream_setup = NULL;
int no_cache = 0;
if (!mrl) {
@@ -806,13 +807,19 @@ static int open_internal (xine_stream_t *stream, const char *mrl) {
* look for a stream_setup in MRL and try finding an input plugin
*/
- stream_setup = mrl;
- /* look for the next '#' or try the whole MRL, if none is found */
- while (*stream_setup &&
- (stream_setup = (strchr(stream_setup, '#') ? strchr(stream_setup, '#') : strlen(mrl) + mrl))) {
- char *input_source = (char *)malloc(stream_setup - mrl + 1);
- memcpy(input_source, mrl, stream_setup - mrl);
- input_source[stream_setup - mrl] = '\0';
+ if (isalpha (*mrl))
+ {
+ stream_setup = mrl + 1;
+ while (isalnum (*stream_setup) || *stream_setup == '+' || *stream_setup == '-' || *stream_setup == '.')
+ ++stream_setup;
+ if (stream_setup[0] == ':' && stream_setup[1] == '/')
+ stream_setup = strchr (mrl, '#');
+ else
+ stream_setup = NULL;
+ }
+
+ {
+ char *input_source = strndup (mrl, stream_setup ? stream_setup - mrl : strlen (mrl));
/*
* find an input plugin
@@ -831,7 +838,6 @@ static int open_internal (xine_stream_t *stream, const char *mrl) {
res = (stream->input_plugin->open) (stream->input_plugin);
switch(res) {
case 1: /* Open successfull */
- free(input_source);
break;
case -1: /* Open unsuccessfull, but correct plugin */
free(input_source);
@@ -844,14 +850,9 @@ static int open_internal (xine_stream_t *stream, const char *mrl) {
stream->input_plugin = NULL;
stream->err = XINE_ERROR_INPUT_FAILED;
}
- if ( res ) break;
}
free(input_source);
- /* if we fail when passing up to the first '#' to the input plugins,
- * maybe the user stated a (invalid) MRL, with a '#' belonging to the
- * input source -> look for the next '#' and try again */
- if (*stream_setup) stream_setup++;
}
if (!stream->input_plugin) {
@@ -861,7 +862,7 @@ static int open_internal (xine_stream_t *stream, const char *mrl) {
return 0;
}
- if (*stream_setup) {
+ if (stream_setup) {
while (stream_setup && *stream_setup && *(++stream_setup)) {
if (strncasecmp(stream_setup, "demux", 5) == 0) {