X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=spxdec_filter.c;h=644d287aaf6a4daba32dd023c9770691aa3f4d24;hp=41b66c519f9509d3837355854be95e8760f79648;hb=224ab3f14af8e08a8a7159160eccea75be30ffd1;hpb=92f089b820b45a5dbdc5b4f69d596105d5acba68 diff --git a/spxdec_filter.c b/spxdec_filter.c index 41b66c51..644d287a 100644 --- a/spxdec_filter.c +++ b/spxdec_filter.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2002-2006 Jean-Marc Valin - * Copyright (C) 2010-2011 Andre Noll + * Copyright (C) 2010 Andre Noll * * Licensed under the GPL v2. For licencing details see COPYING. */ @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include @@ -76,7 +75,7 @@ struct private_spxdec_data { int lookahead; /** The state information about the current stream. */ ogg_stream_state os; - /** Whether \a os initialized. */ + /** Whether \a os is initialized. */ bool stream_init; }; @@ -129,7 +128,14 @@ static int speexdec_init(struct filter_node *fn) #define le_short(s) ((short) (s)) #endif +/** + * Size of the output buffer. + * + * Valid streams have frame sizes in the range from 160 to 640. To avoid buffer + * overflows, we bail out if the decoder reports a value bigger than this. + */ #define MAX_FRAME_SIZE 2000 + /* Copy Ogg packet to Speex bitstream */ static int speexdec_write_frames(int packet_no, struct private_spxdec_data *psd, int skip_samples, @@ -140,7 +146,14 @@ static int speexdec_write_frames(int packet_no, for (j = 0; j != psd->shi.nframes; j++) { short output[MAX_FRAME_SIZE], *btr_output; int skip = skip_samples + psd->lookahead, skip_idx = 0; - int samples, new_frame_size = psd->shi.frame_size; + int samples, this_frame_size, + new_frame_size = psd->shi.frame_size; + + if (speex_decoder_ctl(psd->shi.state, SPEEX_GET_FRAME_SIZE, + &this_frame_size) == 0) { + if (this_frame_size > MAX_FRAME_SIZE) + return -E_SPX_DECODE_OVERFLOW; + }; if (speex_decode_int(psd->shi.state, &psd->bits, output) < 0) return -E_SPX_DECODE; @@ -239,9 +252,9 @@ static int compute_skip_samples(ogg_page *og, struct private_spxdec_data *psd) return ret; } -static void speexdec_post_select(__a_unused struct sched *s, struct task *t) +static int speexdec_post_select(__a_unused struct sched *s, void *context) { - struct filter_node *fn = container_of(t, struct filter_node, task); + struct filter_node *fn = context; struct private_spxdec_data *psd = fn->private_data; struct btr_node *btrn = fn->btrn; int ret, ns; @@ -250,7 +263,6 @@ static void speexdec_post_select(__a_unused struct sched *s, struct task *t) size_t nbytes; next_buffer: - t->error = 0; ret = ns = btr_node_status(btrn, fn->min_iqs, BTR_NT_INTERNAL); btr_merge(btrn, fn->min_iqs); if (!psd->shi.state) { @@ -291,10 +303,9 @@ next_buffer: goto next_buffer; ret = ns; fail: - if (ret < 0) { - t->error = ret; - btr_remove_node(btrn); - } + if (ret < 0) + btr_remove_node(&fn->btrn); + return ret; } /**