summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2016-07-06 16:28:53 +0200
committerErik de Castro Lopo <erikd@mega-nerd.com>2016-07-10 08:19:26 +1000
commit0a49fe7788ecab32a1238ecd45308afbbb580bec (patch)
treee7a3c32a97496727cf94867ff8b7a35116be601a
parent82797787358bb8246497d59afd8e1304de7c1682 (diff)
downloadflac-0a49fe7788ecab32a1238ecd45308afbbb580bec.tar.gz
stream_decoder: check state==ABORTED after process_single() for seek
FLAC__stream_decoder_process_single() ignores frame_sync_() errors, which means the caller cannot rely solely on the boolean return value, it is also required to check the new "state". After FLAC__stream_decoder_process_until_end_of_metadata(), state==SEARCH_FOR_FRAME_SYNC and last_frame.header.number_type==FRAME_NUMBER. When an application seeks at this time, but an I/O error occurs, then FLAC__stream_decoder_process_single() returns true, but no frame has been read yet, i.e. last_frame.header.number_type is still FRAME_NUMBER. This triggers the assertion in seek_to_absolute_sample_(): FLAC__ASSERT(decoder->private_->last_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); So what needs to be done is check for state==ABORTED after the FLAC__stream_decoder_process_single() call. This bug can be triggered remotely with the Music Player Daemon (https://www.musicpd.org/), and crashes the process. Signed-off-by: Erik de Castro Lopo <erikd@mega-nerd.com> Closes: https://github.com/xiph/flac/pull/12
-rw-r--r--src/libFLAC/stream_decoder.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/src/libFLAC/stream_decoder.c b/src/libFLAC/stream_decoder.c
index c626d7a3..fa0ef2ce 100644
--- a/src/libFLAC/stream_decoder.c
+++ b/src/libFLAC/stream_decoder.c
@@ -3134,7 +3134,8 @@ FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 s
* FLAC__stream_decoder_process_single() to return false.
*/
decoder->private_->unparseable_frame_count = 0;
- if(!FLAC__stream_decoder_process_single(decoder)) {
+ if(!FLAC__stream_decoder_process_single(decoder) ||
+ decoder->protected_->state == FLAC__STREAM_DECODER_ABORTED) {
decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
return false;
}
@@ -3261,7 +3262,8 @@ FLAC__bool seek_to_absolute_sample_ogg_(FLAC__StreamDecoder *decoder, FLAC__uint
did_a_seek = false;
decoder->private_->got_a_frame = false;
- if(!FLAC__stream_decoder_process_single(decoder)) {
+ if(!FLAC__stream_decoder_process_single(decoder) ||
+ decoder->protected_->state == FLAC__STREAM_DECODER_ABORTED) {
decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
return false;
}