mirror of
https://github.com/badaix/snapcast.git
synced 2025-05-19 20:16:15 +02:00
Fix crash when feeding invalid ranges into flac
This commit is contained in:
parent
1725cffc6e
commit
5d7aedeb31
5 changed files with 38 additions and 12 deletions
|
@ -28,7 +28,7 @@ using namespace std;
|
||||||
namespace encoder
|
namespace encoder
|
||||||
{
|
{
|
||||||
|
|
||||||
// static constexpr auto LOG_TAG = "FlacEnc";
|
static constexpr auto LOG_TAG = "FlacEnc";
|
||||||
|
|
||||||
FlacEncoder::FlacEncoder(const std::string& codecOptions) : Encoder(codecOptions), encoder_(nullptr), pcmBufferSize_(0), encodedSamples_(0), flacChunk_(nullptr)
|
FlacEncoder::FlacEncoder(const std::string& codecOptions) : Encoder(codecOptions), encoder_(nullptr), pcmBufferSize_(0), encodedSamples_(0), flacChunk_(nullptr)
|
||||||
{
|
{
|
||||||
|
@ -76,8 +76,8 @@ void FlacEncoder::encode(const msg::PcmChunk& chunk)
|
||||||
|
|
||||||
int samples = chunk.getSampleCount();
|
int samples = chunk.getSampleCount();
|
||||||
int frames = chunk.getFrameCount();
|
int frames = chunk.getFrameCount();
|
||||||
// LOG(INFO, LOG_TAG) << "payload: " << chunk->payloadSize << "\tframes: " << frames << "\tsamples: " << samples << "\tduration: " <<
|
// LOG(TRACE, LOG_TAG) << "payload: " << chunk.payloadSize << "\tframes: " << frames << "\tsamples: " << samples
|
||||||
// chunk->duration<chronos::msec>().count() << "\n";
|
// << "\tduration: " << chunk.duration<chronos::msec>().count() << ", format: " << chunk.format.toString() << "\n";
|
||||||
|
|
||||||
if (pcmBufferSize_ < samples)
|
if (pcmBufferSize_ < samples)
|
||||||
{
|
{
|
||||||
|
@ -85,23 +85,39 @@ void FlacEncoder::encode(const msg::PcmChunk& chunk)
|
||||||
pcmBuffer_ = static_cast<FLAC__int32*>(realloc(pcmBuffer_, pcmBufferSize_ * sizeof(FLAC__int32)));
|
pcmBuffer_ = static_cast<FLAC__int32*>(realloc(pcmBuffer_, pcmBufferSize_ * sizeof(FLAC__int32)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto clip = [](int32_t min, int32_t max, int32_t value) -> int32_t {
|
||||||
|
if (value < min)
|
||||||
|
return min;
|
||||||
|
if (value > max)
|
||||||
|
return max;
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
if (sampleFormat_.sampleSize() == 1)
|
if (sampleFormat_.sampleSize() == 1)
|
||||||
{
|
{
|
||||||
auto* buffer = reinterpret_cast<FLAC__int8*>(chunk.payload);
|
auto* buffer = reinterpret_cast<FLAC__int8*>(chunk.payload);
|
||||||
for (int i = 0; i < samples; i++)
|
for (int i = 0; i < samples; i++)
|
||||||
pcmBuffer_[i] = static_cast<FLAC__int32>(buffer[i]);
|
pcmBuffer_[i] = clip(-128, 127, static_cast<FLAC__int32>(buffer[i]));
|
||||||
}
|
}
|
||||||
else if (sampleFormat_.sampleSize() == 2)
|
else if (sampleFormat_.sampleSize() == 2)
|
||||||
{
|
{
|
||||||
auto* buffer = reinterpret_cast<FLAC__int16*>(chunk.payload);
|
auto* buffer = reinterpret_cast<FLAC__int16*>(chunk.payload);
|
||||||
for (int i = 0; i < samples; i++)
|
for (int i = 0; i < samples; i++)
|
||||||
pcmBuffer_[i] = static_cast<FLAC__int32>(buffer[i]);
|
pcmBuffer_[i] = clip(-32768, 32767, static_cast<FLAC__int32>(buffer[i]));
|
||||||
}
|
}
|
||||||
else if (sampleFormat_.sampleSize() == 4)
|
else if (sampleFormat_.sampleSize() == 4)
|
||||||
{
|
{
|
||||||
auto* buffer = reinterpret_cast<FLAC__int32*>(chunk.payload);
|
auto* buffer = reinterpret_cast<FLAC__int32*>(chunk.payload);
|
||||||
for (int i = 0; i < samples; i++)
|
if (sampleFormat_.bits() == 24)
|
||||||
pcmBuffer_[i] = buffer[i];
|
{
|
||||||
|
for (int i = 0; i < samples; i++)
|
||||||
|
pcmBuffer_[i] = clip(-8388608, 8388607, buffer[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < samples; i++)
|
||||||
|
pcmBuffer_[i] = buffer[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -150,20 +166,22 @@ FLAC__StreamEncoderWriteStatus write_callback(const FLAC__StreamEncoder* encoder
|
||||||
|
|
||||||
void FlacEncoder::initEncoder()
|
void FlacEncoder::initEncoder()
|
||||||
{
|
{
|
||||||
int quality(2);
|
int compression_level(2);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
quality = cpt::stoi(codecOptions_);
|
compression_level = cpt::stoi(codecOptions_);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
throw SnapException("Invalid codec option: \"" + codecOptions_ + "\"");
|
throw SnapException("Invalid codec option: \"" + codecOptions_ + "\"");
|
||||||
}
|
}
|
||||||
if ((quality < 0) || (quality > 8))
|
if ((compression_level < 0) || (compression_level > 8))
|
||||||
{
|
{
|
||||||
throw SnapException("compression level has to be between 0 and 8");
|
throw SnapException("compression level has to be between 0 and 8");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG(INFO, LOG_TAG) << "Init - compression level: " << compression_level << "\n";
|
||||||
|
|
||||||
FLAC__bool ok = 1;
|
FLAC__bool ok = 1;
|
||||||
FLAC__StreamEncoderInitStatus init_status;
|
FLAC__StreamEncoderInitStatus init_status;
|
||||||
FLAC__StreamMetadata_VorbisComment_Entry entry;
|
FLAC__StreamMetadata_VorbisComment_Entry entry;
|
||||||
|
@ -178,7 +196,7 @@ void FlacEncoder::initEncoder()
|
||||||
// latency:
|
// latency:
|
||||||
// 0-2: 1152 frames, ~26.1224ms
|
// 0-2: 1152 frames, ~26.1224ms
|
||||||
// 3-8: 4096 frames, ~92.8798ms
|
// 3-8: 4096 frames, ~92.8798ms
|
||||||
ok &= FLAC__stream_encoder_set_compression_level(encoder_, quality);
|
ok &= FLAC__stream_encoder_set_compression_level(encoder_, compression_level);
|
||||||
ok &= FLAC__stream_encoder_set_channels(encoder_, sampleFormat_.channels());
|
ok &= FLAC__stream_encoder_set_channels(encoder_, sampleFormat_.channels());
|
||||||
ok &= FLAC__stream_encoder_set_bits_per_sample(encoder_, sampleFormat_.bits());
|
ok &= FLAC__stream_encoder_set_bits_per_sample(encoder_, sampleFormat_.bits());
|
||||||
ok &= FLAC__stream_encoder_set_sample_rate(encoder_, sampleFormat_.rate());
|
ok &= FLAC__stream_encoder_set_sample_rate(encoder_, sampleFormat_.rate());
|
||||||
|
|
|
@ -17,11 +17,13 @@
|
||||||
***/
|
***/
|
||||||
|
|
||||||
#include "null_encoder.hpp"
|
#include "null_encoder.hpp"
|
||||||
|
#include "common/aixlog.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace encoder
|
namespace encoder
|
||||||
{
|
{
|
||||||
|
|
||||||
|
static constexpr auto LOG_TAG = "NullEnc";
|
||||||
|
|
||||||
NullEncoder::NullEncoder(const std::string& codecOptions) : Encoder(codecOptions)
|
NullEncoder::NullEncoder(const std::string& codecOptions) : Encoder(codecOptions)
|
||||||
{
|
{
|
||||||
|
@ -37,6 +39,7 @@ void NullEncoder::encode(const msg::PcmChunk& chunk)
|
||||||
|
|
||||||
void NullEncoder::initEncoder()
|
void NullEncoder::initEncoder()
|
||||||
{
|
{
|
||||||
|
LOG(INFO, LOG_TAG) << "Init\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -178,6 +178,8 @@ void OggEncoder::initEncoder()
|
||||||
throw SnapException("compression level has to be between -0.1 and 1.0");
|
throw SnapException("compression level has to be between -0.1 and 1.0");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG(INFO, LOG_TAG) << "Init - quality: " << quality << "\n";
|
||||||
|
|
||||||
/********** Encode setup ************/
|
/********** Encode setup ************/
|
||||||
vorbis_info_init(&vi_);
|
vorbis_info_init(&vi_);
|
||||||
|
|
||||||
|
|
|
@ -144,7 +144,7 @@ void OpusEncoder::initEncoder()
|
||||||
throw SnapException("Opus error parsing options: " + codecOptions_);
|
throw SnapException("Opus error parsing options: " + codecOptions_);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(INFO, LOG_TAG) << "Opus bitrate: " << bitrate << " bps, complexity: " << complexity << "\n";
|
LOG(INFO, LOG_TAG) << "Init - bitrate: " << bitrate << " bps, complexity: " << complexity << "\n";
|
||||||
|
|
||||||
int error;
|
int error;
|
||||||
enc_ = opus_encoder_create(sampleFormat_.rate(), sampleFormat_.channels(), OPUS_APPLICATION_RESTRICTED_LOWDELAY, &error);
|
enc_ = opus_encoder_create(sampleFormat_.rate(), sampleFormat_.channels(), OPUS_APPLICATION_RESTRICTED_LOWDELAY, &error);
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
***/
|
***/
|
||||||
|
|
||||||
#include "pcm_encoder.hpp"
|
#include "pcm_encoder.hpp"
|
||||||
|
#include "common/aixlog.hpp"
|
||||||
#include "common/endian.hpp"
|
#include "common/endian.hpp"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
@ -29,6 +30,7 @@ static constexpr auto ID_WAVE = 0x45564157;
|
||||||
static constexpr auto ID_FMT = 0x20746d66;
|
static constexpr auto ID_FMT = 0x20746d66;
|
||||||
static constexpr auto ID_DATA = 0x61746164;
|
static constexpr auto ID_DATA = 0x61746164;
|
||||||
|
|
||||||
|
static constexpr auto LOG_TAG = "PcmEnc";
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -57,6 +59,7 @@ void PcmEncoder::encode(const msg::PcmChunk& chunk)
|
||||||
|
|
||||||
void PcmEncoder::initEncoder()
|
void PcmEncoder::initEncoder()
|
||||||
{
|
{
|
||||||
|
LOG(INFO, LOG_TAG) << "Init\n";
|
||||||
headerChunk_->payloadSize = 44;
|
headerChunk_->payloadSize = 44;
|
||||||
headerChunk_->payload = static_cast<char*>(realloc(headerChunk_->payload, headerChunk_->payloadSize));
|
headerChunk_->payload = static_cast<char*>(realloc(headerChunk_->payload, headerChunk_->payloadSize));
|
||||||
char* payload = headerChunk_->payload;
|
char* payload = headerChunk_->payload;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue