From 6c485fa5b8b1cc60d809114baf6ef7d5e0e427ac Mon Sep 17 00:00:00 2001 From: Mike Brady Date: Tue, 2 Feb 2016 09:43:44 +0000 Subject: [PATCH] Make alac check allocated buffer size and make player check and discard bad audio frames. --- alac.c | 17 +++++++++++++++++ player.c | 36 ++++++++++++++++++++++-------------- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/alac.c b/alac.c index d5833c61..cf72781a 100644 --- a/alac.c +++ b/alac.c @@ -710,6 +710,7 @@ void alac_decode_frame(alac_file *alac, unsigned char *inbuffer, void *outbuffer, int *outputsize) { + int outbuffer_allocation_size = *outputsize; // initial value int channels; int32_t outputsamples = alac->setinfo_max_samples_per_frame; @@ -720,6 +721,11 @@ void alac_decode_frame(alac_file *alac, channels = readbits(alac, 3); *outputsize = outputsamples * alac->bytespersample; + if (*outputsize>outbuffer_allocation_size) { + fprintf(stderr, "FIXME: Not enough space if the output buffer for audio frame - E1.\n"); + *outputsize = 0; + return; + } switch(channels) { @@ -751,6 +757,12 @@ void alac_decode_frame(alac_file *alac, * as a 32bit integer */ outputsamples = readbits(alac, 32); *outputsize = outputsamples * alac->bytespersample; + if (*outputsize>outbuffer_allocation_size) { + fprintf(stderr, "FIXME: Not enough space if the output buffer for audio frame - E2.\n"); + *outputsize = 0; + return; + } + } readsamplesize = alac->setinfo_sample_size - (uncompressed_bytes * 8); @@ -928,6 +940,11 @@ void alac_decode_frame(alac_file *alac, * as a 32bit integer */ outputsamples = readbits(alac, 32); *outputsize = outputsamples * alac->bytespersample; + if (*outputsize>outbuffer_allocation_size) { + fprintf(stderr, "FIXME: Not enough space if the output buffer for audio frame - E3.\n"); + *outputsize = 0; + return; + } } readsamplesize = alac->setinfo_sample_size - (uncompressed_bytes * 8) + 1; diff --git a/player.c b/player.c index 1aaef023..a6b1f915 100644 --- a/player.c +++ b/player.c @@ -221,11 +221,12 @@ static inline int seq32_order(uint32_t a, uint32_t b) { return (C & 0x80000000) == 0; } -static void alac_decode(short *dest, uint8_t *buf, int len) { +static int alac_decode(short *dest, uint8_t *buf, int len) { unsigned char packet[MAX_PACKET]; unsigned char packetp[MAX_PACKET]; assert(len <= MAX_PACKET); - int outsize; + int reply = 0; //everything okay + int outsize=FRAME_BYTES(frame_size); // the size it should be if (encrypted) { unsigned char iv[16]; @@ -244,11 +245,13 @@ static void alac_decode(short *dest, uint8_t *buf, int len) { } if (outsize!=FRAME_BYTES(frame_size)) { if(outsizedata, data, len); - abuf->ready = 1; - abuf->timestamp = timestamp; - abuf->sequence_number = seqno; + if (alac_decode(abuf->data, data, len)==0) { + abuf->ready = 1; + abuf->timestamp = timestamp; + abuf->sequence_number = seqno; + } else { + debug(1,"Bad audio packet detected and discarded."); + abuf->ready = 0; + abuf->timestamp = 0; + abuf->sequence_number = 0; + } } // pthread_mutex_lock(&ab_mutex); @@ -893,13 +902,12 @@ typedef struct stats { // statistics for running averages } stats_t; static void *player_thread_func(void *arg) { - struct inter_threads_record itr; - itr.please_stop = 0; // this will be used to signal to the subsidiary threads + int threads_stop = 0; // create and start the timing, control and audio receiver threads pthread_t rtp_audio_thread, rtp_control_thread, rtp_timing_thread; - pthread_create(&rtp_audio_thread, NULL, &rtp_audio_receiver, (void *)&itr); - pthread_create(&rtp_control_thread, NULL, &rtp_control_receiver, (void *)&itr); - pthread_create(&rtp_timing_thread, NULL, &rtp_timing_receiver, (void *)&itr); + pthread_create(&rtp_audio_thread, NULL, &rtp_audio_receiver, (void *)&threads_stop); + pthread_create(&rtp_control_thread, NULL, &rtp_control_receiver, (void *)&threads_stop); + pthread_create(&rtp_timing_thread, NULL, &rtp_timing_receiver, (void *)&threads_stop); session_corrections = 0; play_segment_reference_frame = 0; // zero signals that we are not in a play segment @@ -1233,7 +1241,7 @@ static void *player_thread_func(void *arg) { free(silence); debug(1,"Shut down audio, control and timing threads"); // usleep(1000000); - itr.please_stop = 1; + threads_stop = 1; pthread_kill(rtp_audio_thread, SIGUSR1); pthread_kill(rtp_control_thread, SIGUSR1); pthread_kill(rtp_timing_thread, SIGUSR1);