From 68b991e3ddef7145470fa1d49f483fd1681b61a1 Mon Sep 17 00:00:00 2001 From: Paul Brossier Date: Mon, 17 Dec 2018 16:41:01 +0100 Subject: [PATCH] [io] sink_flac: validate input sizes, avoid crash on null path and closing twice --- src/io/sink_flac.c | 49 ++++++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/src/io/sink_flac.c b/src/io/sink_flac.c index 2deffbc4..512120bf 100644 --- a/src/io/sink_flac.c +++ b/src/io/sink_flac.c @@ -34,7 +34,6 @@ #include #include -#include #include // strerror #include // errno @@ -78,7 +77,7 @@ uint_t aubio_sink_flac_close (aubio_sink_flac_t *s); 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 * new_aubio_sink_flac (const char_t *uri, { 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 @@ uint_t aubio_sink_flac_open(aubio_sink_flac_t *s) // 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,46 +262,43 @@ void aubio_sink_flac_do(aubio_sink_flac_t *s, fvec_t *write_data, 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]); } } } // 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, 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 aubio_sink_flac_close (aubio_sink_flac_t *s) { 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 @@ uint_t aubio_sink_flac_close (aubio_sink_flac_t *s) 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) -- 2.11.0