aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2012-03-19 19:51:19 +0100
committerMax Kellermann <max@duempel.org>2012-03-19 23:17:56 +0100
commit4f500149af0d4e50938b5c93b6c16a5de4e43685 (patch)
tree9ac329245b982c05324095051a1858c6bfacb103 /src
parent103832742d4ef2b6bb86d287b8557ab3e64dba21 (diff)
downloadmpd-4f500149af0d4e50938b5c93b6c16a5de4e43685.tar.gz
mpd-4f500149af0d4e50938b5c93b6c16a5de4e43685.tar.xz
mpd-4f500149af0d4e50938b5c93b6c16a5de4e43685.zip
text_input_stream: detect end-of-file
Fixes endless loop when the last line of a text file was not terminated (bug 3470).
Diffstat (limited to 'src')
-rw-r--r--src/text_input_stream.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/src/text_input_stream.c b/src/text_input_stream.c
index 29fb6dce6..6d0436d41 100644
--- a/src/text_input_stream.c
+++ b/src/text_input_stream.c
@@ -24,6 +24,7 @@
#include <glib.h>
+#include <assert.h>
#include <string.h>
struct text_input_stream {
@@ -67,7 +68,12 @@ text_input_stream_read(struct text_input_stream *tis)
do {
dest = fifo_buffer_write(tis->buffer, &length);
- if (dest != NULL) {
+ if (dest != NULL && length >= 2) {
+ /* reserve one byte for the null terminator if
+ the last line is not terminated by a
+ newline character */
+ --length;
+
nbytes = input_stream_read(tis->is, dest, length,
&error);
if (nbytes > 0)
@@ -77,13 +83,22 @@ text_input_stream_read(struct text_input_stream *tis)
g_error_free(error);
return NULL;
}
- }
+ } else
+ nbytes = 0;
src = fifo_buffer_read(tis->buffer, &length);
if (src == NULL)
return NULL;
p = memchr(src, '\n', length);
+ if (p == NULL && nbytes == 0) {
+ /* end of file (or line too long): terminate
+ the current line */
+ dest = fifo_buffer_write(tis->buffer, &nbytes);
+ assert(dest != NULL);
+ *(char *)dest = '\n';
+ fifo_buffer_append(tis->buffer, 1);
+ }
} while (p == NULL);
length = p - src + 1;