audio: Fix crash in the flac fuzzer test
When pushing decoded samples into `fifo_`, the fuzzer test will get a crash as in the reported link in chromium. When the client get the error from the errorcallback, we will stop the decode process. Also, the single decode process will be called only when the `fifo_` is empty. BUG=chromium:1465739, b/293889978 Test: Manual Change-Id: I5da73421ae2e0d6889a2c7c2fb8c078d375fdb9e Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4735554 Commit-Queue: Hongyu Long <hongyulong@chromium.org> Reviewed-by: Dale Curtis <dalecurtis@chromium.org> Cr-Commit-Position: refs/heads/main@{#1181664}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
516f322ba7
commit
c67d4c5ed5
media/audio
@ -70,7 +70,8 @@ bool FlacAudioHandler::AtEnd() const {
|
||||
auto state = FLAC__stream_decoder_get_state(decoder_.get());
|
||||
return state ==
|
||||
FLAC__StreamDecoderState::FLAC__STREAM_DECODER_END_OF_STREAM ||
|
||||
state == FLAC__StreamDecoderState::FLAC__STREAM_DECODER_ABORTED;
|
||||
state == FLAC__StreamDecoderState::FLAC__STREAM_DECODER_ABORTED ||
|
||||
has_error_;
|
||||
}
|
||||
|
||||
bool FlacAudioHandler::CopyTo(AudioBus* bus, size_t* frames_written) {
|
||||
@ -86,17 +87,25 @@ bool FlacAudioHandler::CopyTo(AudioBus* bus, size_t* frames_written) {
|
||||
DCHECK_EQ(bus->frames(), kDefaultFrameCount);
|
||||
DCHECK_EQ(bus->channels(), num_channels_);
|
||||
|
||||
while (!AtEnd() && fifo_->frames() < bus->frames()) {
|
||||
if (!FLAC__stream_decoder_process_single(decoder_.get())) {
|
||||
return false;
|
||||
// Records the number of frames copied into `bus`.
|
||||
int frames_copied = 0;
|
||||
|
||||
do {
|
||||
if (fifo_->frames() == 0 && !AtEnd()) {
|
||||
if (!FLAC__stream_decoder_process_single(decoder_.get())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const int frames = std::min(bus->frames(), fifo_->frames());
|
||||
fifo_->Consume(/*destination=*/bus, /*start_frame=*/0,
|
||||
/*frames_to_consume=*/frames);
|
||||
if (fifo_->frames() > 0) {
|
||||
const int frames =
|
||||
std::min(bus->frames() - frames_copied, fifo_->frames());
|
||||
fifo_->Consume(bus, frames_copied, frames);
|
||||
frames_copied += frames;
|
||||
}
|
||||
} while (!AtEnd() && frames_copied < bus->frames());
|
||||
|
||||
*frames_written = frames;
|
||||
*frames_written = frames_copied;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -106,6 +115,7 @@ void FlacAudioHandler::Reset() {
|
||||
fifo_->Clear();
|
||||
}
|
||||
cursor_ = 0;
|
||||
has_error_ = false;
|
||||
}
|
||||
|
||||
FLAC__StreamDecoderReadStatus FlacAudioHandler::ReadCallback(
|
||||
@ -138,6 +148,7 @@ void FlacAudioHandler::ErrorCallback(const FLAC__StreamDecoder* decoder,
|
||||
void* client_data) {
|
||||
LOG(ERROR) << "Got an error callback: "
|
||||
<< FLAC__StreamDecoderErrorStatusString[status];
|
||||
reinterpret_cast<FlacAudioHandler*>(client_data)->ErrorCallbackInternal();
|
||||
}
|
||||
|
||||
FLAC__StreamDecoderReadStatus FlacAudioHandler::ReadCallbackInternal(
|
||||
@ -168,6 +179,10 @@ FLAC__StreamDecoderReadStatus FlacAudioHandler::ReadCallbackInternal(
|
||||
FLAC__StreamDecoderWriteStatus FlacAudioHandler::WriteCallbackInternal(
|
||||
const FLAC__Frame* frame,
|
||||
const FLAC__int32* const buffer[]) {
|
||||
if (has_error_) {
|
||||
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
|
||||
}
|
||||
|
||||
// Get the number of channels and the number of samples per channel.
|
||||
const int num_channels = frame->header.channels;
|
||||
const int num_samples = frame->header.blocksize;
|
||||
@ -180,7 +195,7 @@ FLAC__StreamDecoderWriteStatus FlacAudioHandler::WriteCallbackInternal(
|
||||
// Discard the packet if there are more than the number of `max_blocksize`
|
||||
// frames.
|
||||
if (num_samples > bus_->frames()) {
|
||||
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
|
||||
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
|
||||
}
|
||||
|
||||
for (int ch = 0; ch < num_channels; ++ch) {
|
||||
@ -248,6 +263,10 @@ void FlacAudioHandler::MetaCallbackInternal(
|
||||
bus_ = AudioBus::Create(num_channels_, max_blocksize);
|
||||
}
|
||||
|
||||
void FlacAudioHandler::ErrorCallbackInternal() {
|
||||
has_error_ = true;
|
||||
}
|
||||
|
||||
bool FlacAudioHandler::AreParamsValid() const {
|
||||
return (num_channels_ > 0 &&
|
||||
num_channels_ <= static_cast<int>(limits::kMaxChannels)) &&
|
||||
|
@ -72,6 +72,7 @@ class MEDIA_EXPORT FlacAudioHandler : public AudioHandler {
|
||||
const FLAC__Frame* frame,
|
||||
const FLAC__int32* const buffer[]);
|
||||
void MetaCallbackInternal(const FLAC__StreamMetadata* metadata);
|
||||
void ErrorCallbackInternal();
|
||||
|
||||
// Check if the metadata fecthed in `MetaCallback()` is valid or not. This
|
||||
// function will check the `num_channels_`, `bits_per_sample_`, `sample_rate_`
|
||||
@ -97,6 +98,9 @@ class MEDIA_EXPORT FlacAudioHandler : public AudioHandler {
|
||||
|
||||
// Equal to the total number of samples per channel.
|
||||
uint64_t total_frames_ = 0u;
|
||||
|
||||
// Set to true if the error callback is called.
|
||||
bool has_error_ = false;
|
||||
};
|
||||
|
||||
} // namespace media
|
||||
|
Reference in New Issue
Block a user