aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/aiff.c10
-rw-r--r--src/decoder_thread.c2
-rw-r--r--src/input/curl_input_plugin.c101
-rw-r--r--src/riff.c10
4 files changed, 69 insertions, 54 deletions
diff --git a/src/aiff.c b/src/aiff.c
index f77e86d2b..d4bec628b 100644
--- a/src/aiff.c
+++ b/src/aiff.c
@@ -84,6 +84,11 @@ aiff_seek_id3(FILE *file)
return 0;
size = GUINT32_FROM_BE(chunk.size);
+ if (size > G_MAXINT32)
+ /* too dangerous, bail out: possible integer
+ underflow when casting to off_t */
+ return 0;
+
if (size % 2 != 0)
/* pad byte */
++size;
@@ -92,11 +97,6 @@ aiff_seek_id3(FILE *file)
/* found it! */
return size;
- if ((off_t)size < 0)
- /* integer underflow after cast to signed
- type */
- return 0;
-
ret = fseek(file, size, SEEK_CUR);
if (ret != 0)
return 0;
diff --git a/src/decoder_thread.c b/src/decoder_thread.c
index be37896c1..9124db033 100644
--- a/src/decoder_thread.c
+++ b/src/decoder_thread.c
@@ -189,7 +189,7 @@ static void decoder_run_song(const struct song *song, const char *uri)
if (plugin == NULL) {
/* we already know our mp3Plugin supports streams, no
* need to check for stream{Types,DecodeFunc} */
- if ((plugin = decoder_plugin_from_name("mp3"))) {
+ if ((plugin = decoder_plugin_from_name("mad"))) {
ret = decoder_stream_decode(plugin, &decoder,
&input_stream);
}
diff --git a/src/input/curl_input_plugin.c b/src/input/curl_input_plugin.c
index a140556c5..b83bcd918 100644
--- a/src/input/curl_input_plugin.c
+++ b/src/input/curl_input_plugin.c
@@ -282,6 +282,42 @@ input_curl_select(struct input_curl *c)
return ret;
}
+static bool
+fill_buffer(struct input_stream *is)
+{
+ struct input_curl *c = is->data;
+ CURLMcode mcode = CURLM_CALL_MULTI_PERFORM;
+
+ while (!c->eof && g_queue_is_empty(c->buffers)) {
+ int running_handles;
+ bool bret;
+
+ if (mcode != CURLM_CALL_MULTI_PERFORM) {
+ /* if we're still here, there is no input yet
+ - wait for input */
+ int ret = input_curl_select(c);
+ if (ret <= 0)
+ /* no data yet or error */
+ return false;
+ }
+
+ mcode = curl_multi_perform(c->multi, &running_handles);
+ if (mcode != CURLM_OK && mcode != CURLM_CALL_MULTI_PERFORM) {
+ g_warning("curl_multi_perform() failed: %s\n",
+ curl_multi_strerror(mcode));
+ c->eof = true;
+ is->ready = true;
+ return false;
+ }
+
+ bret = input_curl_multi_info_read(is);
+ if (!bret)
+ return false;
+ }
+
+ return true;
+}
+
/**
* Mark a part of the buffer object as consumed.
*/
@@ -381,7 +417,7 @@ static size_t
input_curl_read(struct input_stream *is, void *ptr, size_t size)
{
struct input_curl *c = is->data;
- CURLMcode mcode = CURLM_CALL_MULTI_PERFORM;
+ bool success;
GQueue *rewind_buffers;
size_t nbytes = 0;
char *dest = ptr;
@@ -407,54 +443,33 @@ input_curl_read(struct input_stream *is, void *ptr, size_t size)
}
#endif
- /* fill the buffer */
-
- while (!c->eof && g_queue_is_empty(c->buffers)) {
- int running_handles;
- bool bret;
-
- if (mcode != CURLM_CALL_MULTI_PERFORM) {
- /* if we're still here, there is no input yet
- - wait for input */
- int ret = input_curl_select(c);
- if (ret <= 0)
- /* no data yet or error */
- return 0;
- }
-
- mcode = curl_multi_perform(c->multi, &running_handles);
- if (mcode != CURLM_OK && mcode != CURLM_CALL_MULTI_PERFORM) {
- g_warning("curl_multi_perform() failed: %s\n",
- curl_multi_strerror(mcode));
- c->eof = true;
- is->ready = true;
- return 0;
- }
+ do {
+ /* fill the buffer */
- bret = input_curl_multi_info_read(is);
- if (!bret)
+ success = fill_buffer(is);
+ if (!success)
return 0;
- }
- /* send buffer contents */
+ /* send buffer contents */
- if (c->rewind != NULL &&
- (!g_queue_is_empty(c->rewind) || is->offset == 0))
- /* at the beginning or already writing the rewind
- buffer list */
- rewind_buffers = c->rewind;
- else
- /* we don't need the rewind buffers anymore */
- rewind_buffers = NULL;
+ if (c->rewind != NULL &&
+ (!g_queue_is_empty(c->rewind) || is->offset == 0))
+ /* at the beginning or already writing the rewind
+ buffer list */
+ rewind_buffers = c->rewind;
+ else
+ /* we don't need the rewind buffers anymore */
+ rewind_buffers = NULL;
- while (size > 0 && !g_queue_is_empty(c->buffers)) {
- size_t copy = read_from_buffer(&c->icy_metadata, c->buffers,
- dest + nbytes, size,
- rewind_buffers);
+ while (size > 0 && !g_queue_is_empty(c->buffers)) {
+ size_t copy = read_from_buffer(&c->icy_metadata, c->buffers,
+ dest + nbytes, size,
+ rewind_buffers);
- nbytes += copy;
- size -= copy;
- }
+ nbytes += copy;
+ size -= copy;
+ }
+ } while (nbytes == 0);
if (icy_defined(&c->icy_metadata))
copy_icy_tag(c);
diff --git a/src/riff.c b/src/riff.c
index 7227fd3c8..a8ea9dd42 100644
--- a/src/riff.c
+++ b/src/riff.c
@@ -83,6 +83,11 @@ riff_seek_id3(FILE *file)
return 0;
size = GUINT32_FROM_LE(chunk.size);
+ if (size > G_MAXINT32)
+ /* too dangerous, bail out: possible integer
+ underflow when casting to off_t */
+ return 0;
+
if (size % 2 != 0)
/* pad byte */
++size;
@@ -91,11 +96,6 @@ riff_seek_id3(FILE *file)
/* found it! */
return size;
- if ((off_t)size < 0)
- /* integer underflow after cast to signed
- type */
- return 0;
-
ret = fseek(file, size, SEEK_CUR);
if (ret != 0)
return 0;