ref: 68b991e3ddef7145470fa1d49f483fd1681b61a1
parent: 0440778835a24d6016baecf937520999ec0d287d
author: Paul Brossier <piem@piem.org>
date: Mon Dec 17 11:41:01 EST 2018
[io] sink_flac: validate input sizes, avoid crash on null path and closing twice
--- a/src/io/sink_flac.c
+++ b/src/io/sink_flac.c
@@ -34,7 +34,6 @@
#include <FLAC/metadata.h>
#include <FLAC/stream_encoder.h>
-#include <vorbis/vorbisenc.h>
#include <string.h> // strerror
#include <errno.h> // errno
@@ -78,7 +77,7 @@
void del_aubio_sink_flac (aubio_sink_flac_t *s);
#if 0
-static void aubio_sink_vorbis_callback(const FLAC__StreamEncoder* encoder,
+static void aubio_sink_flac_callback(const FLAC__StreamEncoder* encoder,
FLAC__uint64 bytes_written, FLAC__uint64 samples_written,
unsigned frames_writtten, unsigned total_frames_estimate,
void *client_data);
@@ -89,6 +88,11 @@
{
aubio_sink_flac_t * s = AUBIO_NEW(aubio_sink_flac_t);
+ if (!uri) {
+ AUBIO_ERROR("sink_flac: Aborted opening null path\n");
+ goto failure;
+ }
+
s->path = AUBIO_ARRAY(char_t, strnlen(uri, PATH_MAX) + 1);
strncpy(s->path, uri, strnlen(uri, PATH_MAX) + 1);
s->path[strnlen(uri, PATH_MAX)] = '\0';
@@ -195,7 +199,7 @@
// initialize encoder
init_status = FLAC__stream_encoder_init_file(s->encoder, s->path,
NULL, NULL);
- //aubio_sink_vorbis_callback, s);
+ //aubio_sink_flac_callback, s);
if (init_status == FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_SAMPLE_RATE) {
AUBIO_ERR("sink_flac: failed initilizing encoder for %s"
" (invalid samplerate %d)\n", s->path, s->samplerate);
@@ -258,16 +262,14 @@
uint_t write)
{
uint_t c, v;
+ uint_t length = aubio_sink_validate_input_length("sink_flac", s->path,
+ MAX_WRITE_SIZE, write_data->length, write);
// fill buffer
if (!write) {
return;
- } else if (write > MAX_WRITE_SIZE) {
- AUBIO_ERR("sink_flac: max_write request %dm asked for %d,"
- " failed writing to %s\n", write, MAX_WRITE_SIZE, s->path);
- return;
} else {
for (c = 0; c < s->channels; c++) {
- for (v = 0; v < write; v++) {
+ for (v = 0; v < length; v++) {
s->buffer[v * s->channels + c] = FLOAT_TO_SHORT(write_data->data[v]);
}
}
@@ -274,7 +276,7 @@
}
// send to encoder
FLAC__stream_encoder_process_interleaved(s->encoder,
- (const FLAC__int32*)s->buffer, write);
+ (const FLAC__int32*)s->buffer, length);
}
void aubio_sink_flac_do_multi(aubio_sink_flac_t *s, fmat_t *write_data,
@@ -281,23 +283,22 @@
uint_t write)
{
uint_t c, v;
- uint_t channels = MIN(s->channels, write_data->height);
+ uint_t channels = aubio_sink_validate_input_channels("sink_flac", s->path,
+ s->channels, write_data->height);
+ uint_t length = aubio_sink_validate_input_length("sink_flac", s->path,
+ MAX_WRITE_SIZE, write_data->length, write);
// fill buffer
if (!write) {
return;
- } else if (write > MAX_WRITE_SIZE) {
- AUBIO_ERR("sink_flac: max_write request %dm asked for %d,"
- " failed writing to %s\n", write, MAX_WRITE_SIZE, s->path);
- return;
} else {
for (c = 0; c < channels; c++) {
- for (v = 0; v < write; v++) {
+ for (v = 0; v < length; v++) {
s->buffer[v * s->channels + c] = FLOAT_TO_SHORT(write_data->data[c][v]);
}
}
// send to encoder
FLAC__stream_encoder_process_interleaved(s->encoder,
- (const FLAC__int32*)s->buffer, write);
+ (const FLAC__int32*)s->buffer, length);
}
}
@@ -305,6 +306,8 @@
{
uint_t ret = AUBIO_OK;
+ if (!s->fid) return AUBIO_FAIL;
+
if (s->encoder) {
// mark the end of stream
if (!FLAC__stream_encoder_finish(s->encoder)) {
@@ -324,18 +327,18 @@
FLAC__metadata_object_delete(s->metadata[1]);
}
- if (s->fid) {
- if (fclose(s->fid)) {
- AUBIO_ERR("sink_flac: Error closing file %s (%s)\n",
- s->path, strerror(errno));
- ret &= AUBIO_FAIL;
- }
+ if (s->fid && fclose(s->fid)) {
+ AUBIO_ERR("sink_flac: Error closing file %s (%s)\n",
+ s->path, strerror(errno));
+ ret &= AUBIO_FAIL;
}
+ s->fid = NULL;
+
return ret;
}
#if 0
-static void aubio_sink_vorbis_callback(const FLAC__StreamEncoder* encoder UNUSED,
+static void aubio_sink_flac_callback(const FLAC__StreamEncoder* encoder UNUSED,
FLAC__uint64 bytes_written, FLAC__uint64 samples_written,
unsigned frames_written, unsigned total_frames_estimate,
void *client_data UNUSED)