From 6e082873647cc7b80112f925b52fa4f35c84ff64 Mon Sep 17 00:00:00 2001 From: dcoppa Date: Tue, 30 Oct 2012 16:59:23 +0000 Subject: [PATCH] player: Recover from AAC decoding error Decoding errors are usually not fatal, so we can recover by skipping the broken frame. This also fixes invalid memory reads caused by sampleSizeCurr >= sampleSizeN. (upstream git commit dd6c620b53272e2eb4b091a835cd250309f04cad) --- audio/pianobar/Makefile | 4 +- audio/pianobar/patches/patch-src_player_c | 74 +++++++++++++++++++++++ 2 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 audio/pianobar/patches/patch-src_player_c diff --git a/audio/pianobar/Makefile b/audio/pianobar/Makefile index b8cc659a687..e36a3fabb98 100644 --- a/audio/pianobar/Makefile +++ b/audio/pianobar/Makefile @@ -1,11 +1,11 @@ -# $OpenBSD: Makefile,v 1.46 2012/09/23 10:18:21 dcoppa Exp $ +# $OpenBSD: Makefile,v 1.47 2012/10/30 16:59:23 dcoppa Exp $ SHARED_ONLY = Yes COMMENT = console client for pandora DISTNAME = pianobar-2012.09.07 -REVISION = 0 +REVISION = 1 EXTRACT_SUFX = .tar.bz2 CATEGORIES = audio diff --git a/audio/pianobar/patches/patch-src_player_c b/audio/pianobar/patches/patch-src_player_c new file mode 100644 index 00000000000..c8cc25c664d --- /dev/null +++ b/audio/pianobar/patches/patch-src_player_c @@ -0,0 +1,74 @@ +$OpenBSD: patch-src_player_c,v 1.13 2012/10/30 16:59:23 dcoppa Exp $ + +commit dd6c620b53272e2eb4b091a835cd250309f04cad +Author: Lars-Dominik Braun +Date: Sun Oct 28 18:24:50 2012 +0100 + + player: Recover from AAC decoding error + + Decoding errors are usually not fatal, so we can recover by skipping the + broken frame. This also fixes invalid memory reads caused by + sampleSizeCurr >= sampleSizeN. See issue #304. + +--- src/player.c.orig Tue Oct 30 17:45:04 2012 ++++ src/player.c Tue Oct 30 17:45:34 2012 +@@ -28,6 +28,7 @@ THE SOFTWARE. + #include + #include + #include ++#include + #include + + #include "player.h" +@@ -135,17 +136,31 @@ static WaitressCbReturn_t BarPlayerAACCb (void *ptr, s + NeAACDecFrameInfo frameInfo; + size_t i; + +- while ((player->bufferFilled - player->bufferRead) > +- player->sampleSize[player->sampleSizeCurr]) { ++ while (player->sampleSizeCurr < player->sampleSizeN && ++ (player->bufferFilled - player->bufferRead) >= ++ player->sampleSize[player->sampleSizeCurr]) { ++ /* going through this loop can take up to a few seconds => ++ * allow earlier thread abort */ ++ QUIT_PAUSE_CHECK; ++ + /* decode frame */ + aacDecoded = NeAACDecDecode(player->aacHandle, &frameInfo, +- player->buffer + player->bufferRead, ++ &player->buffer[player->bufferRead], + player->sampleSize[player->sampleSizeCurr]); ++ player->bufferRead += player->sampleSize[player->sampleSizeCurr]; ++ ++player->sampleSizeCurr; ++ + if (frameInfo.error != 0) { ++ /* skip this frame, songPlayed will be slightly off if this ++ * happens */ + BarUiMsg (player->settings, MSG_ERR, "Decoding error: %s\n", + NeAACDecGetErrorMessage (frameInfo.error)); +- break; ++ continue; + } ++ /* assuming data in stsz atom is correct */ ++ assert (frameInfo.bytesconsumed == ++ player->sampleSize[player->sampleSizeCurr-1]); ++ + for (i = 0; i < frameInfo.samples; i++) { + aacDecoded[i] = applyReplayGain (aacDecoded[i], player->scale); + } +@@ -157,11 +172,10 @@ static WaitressCbReturn_t BarPlayerAACCb (void *ptr, s + (unsigned long long int) BAR_PLAYER_MS_TO_S_FACTOR / + (unsigned long long int) player->samplerate / + (unsigned long long int) player->channels; +- player->bufferRead += frameInfo.bytesconsumed; +- player->sampleSizeCurr++; +- /* going through this loop can take up to a few seconds => +- * allow earlier thread abort */ +- QUIT_PAUSE_CHECK; ++ } ++ if (player->sampleSizeCurr >= player->sampleSizeN) { ++ /* no more frames, drop data */ ++ player->bufferRead = player->bufferFilled; + } + } else { + if (player->mode == PLAYER_INITIALIZED) {