diff --git a/NEWS b/NEWS
index ece0b896b..5d3fa1236 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,7 @@ ver 0.17.3 (2012/??/??)
   - ffmpeg: support planar audio
 * playlist:
   - cue: fix memory leak
+  - cue: fix CUE files with only one track
 
 ver 0.17.2 (2012/09/30)
 * protocol:
diff --git a/src/cue/cue_parser.c b/src/cue/cue_parser.c
index 4031d6c42..9ccc3bcdd 100644
--- a/src/cue/cue_parser.c
+++ b/src/cue/cue_parser.c
@@ -80,6 +80,13 @@ struct cue_parser {
 	 * start time of the current song.
 	 */
 	bool last_updated;
+
+	/**
+	 * Tracks whether cue_parser_finish() has been called.  If
+	 * true, then all remaining (partial) results will be
+	 * delivered by cue_parser_get().
+	 */
+	bool end;
 };
 
 struct cue_parser *
@@ -92,6 +99,7 @@ cue_parser_new(void)
 	parser->current = NULL;
 	parser->previous = NULL;
 	parser->finished = NULL;
+	parser->end = false;
 	return parser;
 }
 
@@ -223,10 +231,32 @@ cue_parse_position(const char *p)
 	return minutes * 60000 + seconds * 1000 + frames * 1000 / 75;
 }
 
+/**
+ * Commit the current song.  It will be moved to "previous", so the
+ * next song may soon edit its end time (using the next song's start
+ * time).
+ */
+static void
+cue_parser_commit(struct cue_parser *parser)
+{
+	/* the caller of this library must call cue_parser_get() often
+	   enough */
+	assert(parser->finished == NULL);
+	assert(!parser->end);
+
+	if (parser->current == NULL)
+		return;
+
+	parser->finished = parser->previous;
+	parser->previous = parser->current;
+	parser->current = NULL;
+}
+
 static void
 cue_parser_feed2(struct cue_parser *parser, char *p)
 {
 	assert(parser != NULL);
+	assert(!parser->end);
 	assert(p != NULL);
 
 	const char *command = cue_next_token(&p);
@@ -257,7 +287,7 @@ cue_parser_feed2(struct cue_parser *parser, char *p)
 		else if (parser->state == TRACK)
 			cue_add_tag(parser->current->tag, TAG_TITLE, p);
 	} else if (strcmp(command, "FILE") == 0) {
-		cue_parser_finish(parser);
+		cue_parser_commit(parser);
 
 		const char *filename = cue_next_value(&p);
 		if (filename == NULL)
@@ -280,7 +310,7 @@ cue_parser_feed2(struct cue_parser *parser, char *p)
 	} else if (parser->state == IGNORE_FILE) {
 		return;
 	} else if (strcmp(command, "TRACK") == 0) {
-		cue_parser_finish(parser);
+		cue_parser_commit(parser);
 
 		const char *nr = cue_next_token(&p);
 		if (nr == NULL)
@@ -332,6 +362,7 @@ void
 cue_parser_feed(struct cue_parser *parser, const char *line)
 {
 	assert(parser != NULL);
+	assert(!parser->end);
 	assert(line != NULL);
 
 	char *allocated = g_strdup(line);
@@ -342,12 +373,12 @@ cue_parser_feed(struct cue_parser *parser, const char *line)
 void
 cue_parser_finish(struct cue_parser *parser)
 {
-	if (parser->finished != NULL)
-		song_free(parser->finished);
+	if (parser->end)
+		/* has already been called, ignore */
+		return;
 
-	parser->finished = parser->previous;
-	parser->previous = parser->current;
-	parser->current = NULL;
+	cue_parser_commit(parser);
+	parser->end = true;
 }
 
 struct song *
@@ -355,6 +386,15 @@ cue_parser_get(struct cue_parser *parser)
 {
 	assert(parser != NULL);
 
+	if (parser->finished == NULL && parser->end) {
+		/* cue_parser_finish() has been called already:
+		   deliver all remaining (partial) results */
+		assert(parser->current == NULL);
+
+		parser->finished = parser->previous;
+		parser->previous = NULL;
+	}
+
 	struct song *song = parser->finished;
 	parser->finished = NULL;
 	return song;