diff options
author | Darren Salt <linux@youmustbejoking.demon.co.uk> | 2009-01-05 14:50:58 +0000 |
---|---|---|
committer | Darren Salt <linux@youmustbejoking.demon.co.uk> | 2009-01-05 14:50:58 +0000 |
commit | 5347abe5764b0a0ff3ef1d357ce9934a425758fa (patch) | |
tree | 16114922f1fe3862535ef1898da393648522d48b /src | |
parent | 0907a74b5fa7b8b439f1f8f5db239c7586bfb12d (diff) | |
parent | 8f725b5644ac910294fbe28929ddc98cd1d2ad38 (diff) | |
download | xine-lib-5347abe5764b0a0ff3ef1d357ce9934a425758fa.tar.gz xine-lib-5347abe5764b0a0ff3ef1d357ce9934a425758fa.tar.bz2 |
Merge security fixes.
Diffstat (limited to 'src')
38 files changed, 319 insertions, 88 deletions
diff --git a/src/combined/ffmpeg/ff_audio_decoder.c b/src/combined/ffmpeg/ff_audio_decoder.c index 2a6c04dd3..a9f630506 100644 --- a/src/combined/ffmpeg/ff_audio_decoder.c +++ b/src/combined/ffmpeg/ff_audio_decoder.c @@ -249,6 +249,8 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) if (extradata + data_len > this->size) break; /* abort early - extradata length is bad */ + if (extradata > INT_MAX - data_len) + break;/*integer overflow*/ this->context->extradata_size = data_len; this->context->extradata = malloc(this->context->extradata_size + diff --git a/src/combined/ffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c index f4f7175fa..a1ab3696c 100644 --- a/src/combined/ffmpeg/ff_video_decoder.c +++ b/src/combined/ffmpeg/ff_video_decoder.c @@ -609,6 +609,10 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) { su = this->av_frame->data[1]; sv = this->av_frame->data[2]; + /* Some segfaults & heap corruption have been observed with img->height, + * so we use this->bih.biHeight instead (which is the displayed height) + */ + if (this->context->pix_fmt == PIX_FMT_YUV410P) { yuv9_to_yv12( @@ -629,7 +633,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) { img->pitches[2], /* width x height */ img->width, - img->height); + this->bih.biHeight); } else if (this->context->pix_fmt == PIX_FMT_YUV411P) { @@ -651,7 +655,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) { img->pitches[2], /* width x height */ img->width, - img->height); + this->bih.biHeight); } else if (this->context->pix_fmt == PIX_FMT_RGBA32) { @@ -659,7 +663,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) { uint32_t *argb_pixels; uint32_t argb; - for(y = 0; y < img->height; y++) { + for(y = 0; y < this->bih.biHeight; y++) { argb_pixels = (uint32_t *)sy; for(x = 0; x < img->width; x++) { uint8_t r, g, b; @@ -687,7 +691,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) { uint8_t *src; uint16_t pixel16; - for(y = 0; y < img->height; y++) { + for(y = 0; y < this->bih.biHeight; y++) { src = sy; for(x = 0; x < img->width; x++) { uint8_t r, g, b; @@ -716,7 +720,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) { uint8_t *src; uint16_t pixel16; - for(y = 0; y < img->height; y++) { + for(y = 0; y < this->bih.biHeight; y++) { src = sy; for(x = 0; x < img->width; x++) { uint8_t r, g, b; @@ -744,7 +748,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) { int x, plane_ptr = 0; uint8_t *src; - for(y = 0; y < img->height; y++) { + for(y = 0; y < this->bih.biHeight; y++) { src = sy; for(x = 0; x < img->width; x++) { uint8_t r, g, b; @@ -768,7 +772,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) { int x, plane_ptr = 0; uint8_t *src; - for(y = 0; y < img->height; y++) { + for(y = 0; y < this->bih.biHeight; y++) { src = sy; for(x = 0; x < img->width; x++) { uint8_t r, g, b; @@ -811,7 +815,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) { v_palette[x] = COMPUTE_V(r, g, b); } - for(y = 0; y < img->height; y++) { + for(y = 0; y < this->bih.biHeight; y++) { src = sy; for(x = 0; x < img->width; x++) { pixel = *src++; @@ -828,7 +832,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) { } else { - for (y=0; y<img->height; y++) { + for (y = 0; y < this->bih.biHeight; y++) { xine_fast_memcpy (dy, sy, img->width); dy += img->pitches[0]; @@ -836,7 +840,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) { sy += this->av_frame->linesize[0]; } - for (y=0; y<(img->height/2); y++) { + for (y = 0; y < this->bih.biHeight / 2; y++) { if (this->context->pix_fmt != PIX_FMT_YUV444P) { diff --git a/src/demuxers/demux_aac.c b/src/demuxers/demux_aac.c index b8e6ec5c4..68a684ffa 100644 --- a/src/demuxers/demux_aac.c +++ b/src/demuxers/demux_aac.c @@ -173,7 +173,7 @@ static int demux_aac_send_chunk(demux_plugin_t *this_gen) { buf->extra_info->input_time = (8*current_pos) / (bitrate/1000); bytes_read = this->input->read(this->input, buf->content, buf->max_size); - if (bytes_read == 0) { + if (bytes_read <= 0) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; return this->status; diff --git a/src/demuxers/demux_ac3.c b/src/demuxers/demux_ac3.c index 1acb12fcd..711bb0b45 100644 --- a/src/demuxers/demux_ac3.c +++ b/src/demuxers/demux_ac3.c @@ -311,13 +311,7 @@ static int demux_ac3_send_chunk (demux_plugin_t *this_gen) { this->frame_size); } - if (buf->size == 0) { - buf->free_buffer(buf); - this->status = DEMUX_FINISHED; - return this->status; - } - - if (buf->size == 0) { + if (buf->size <= 0) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; return this->status; diff --git a/src/demuxers/demux_asf.c b/src/demuxers/demux_asf.c index 9d4191633..d79782026 100644 --- a/src/demuxers/demux_asf.c +++ b/src/demuxers/demux_asf.c @@ -738,7 +738,10 @@ static void asf_send_buffer_nodefrag (demux_asf_t *this, asf_demux_stream_t *str bufsize = stream->fifo->buffer_pool_buf_size; buf = stream->fifo->buffer_pool_alloc (stream->fifo); - this->input->read (this->input, buf->content, bufsize); + if (this->input->read (this->input, buf->content, bufsize) != bufsize) { + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: input buffer starved\n"); + return ; + } lprintf ("data: %d %d %d %d\n", buf->content[0], buf->content[1], buf->content[2], buf->content[3]); @@ -817,7 +820,10 @@ static void asf_send_buffer_defrag (demux_asf_t *this, asf_demux_stream_t *strea if( stream->frag_offset + frag_len > DEFRAG_BUFSIZE ) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: buffer overflow on defrag!\n"); } else { - this->input->read (this->input, &stream->buffer[stream->frag_offset], frag_len); + if (this->input->read (this->input, &stream->buffer[stream->frag_offset], frag_len) != frag_len) { + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: input buffer starved\n"); + return ; + } stream->frag_offset += frag_len; } diff --git a/src/demuxers/demux_dts.c b/src/demuxers/demux_dts.c index 0606586cb..ed1f16d33 100644 --- a/src/demuxers/demux_dts.c +++ b/src/demuxers/demux_dts.c @@ -278,7 +278,7 @@ static int demux_dts_send_chunk (demux_plugin_t *this_gen) { this->frame_size); } - if (buf->size == 0) { + if (buf->size <= 0) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; return this->status; diff --git a/src/demuxers/demux_matroska.c b/src/demuxers/demux_matroska.c index ec75cb97a..086e0cc98 100644 --- a/src/demuxers/demux_matroska.c +++ b/src/demuxers/demux_matroska.c @@ -607,6 +607,8 @@ static void init_codec_xiph(demux_matroska_t *this, matroska_track_t *track) { int i; uint8_t *data; + if (track->codec_private_len < 3) + return; nb_lace = track->codec_private[0]; if (nb_lace != 2) return; @@ -614,6 +616,8 @@ static void init_codec_xiph(demux_matroska_t *this, matroska_track_t *track) { frame[0] = track->codec_private[1]; frame[1] = track->codec_private[2]; frame[2] = track->codec_private_len - frame[0] - frame[1] - 3; + if (frame[2] < 0) + return; data = track->codec_private + 3; for (i = 0; i < 3; i++) { @@ -1183,7 +1187,12 @@ static int parse_track_entry(demux_matroska_t *this, matroska_track_t *track) { break; case MATROSKA_ID_TR_CODECPRIVATE: { - char *codec_private = malloc (elem.len); + char *codec_private; + if (elem.len >= 0x80000000) + return 0; + codec_private = malloc (elem.len); + if (! codec_private) + return 0; lprintf("CodecPrivate\n"); if (!ebml_read_binary(ebml, &elem, codec_private)) { free(codec_private); @@ -1287,12 +1296,14 @@ static int parse_track_entry(demux_matroska_t *this, matroska_track_t *track) { if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_VFW_FOURCC)) { xine_bmiheader *bih; - lprintf("MATROSKA_CODEC_ID_V_VFW_FOURCC\n"); - bih = (xine_bmiheader*)track->codec_private; - _x_bmiheader_le2me(bih); + if (track->codec_private_len >= sizeof(xine_bmiheader)) { + lprintf("MATROSKA_CODEC_ID_V_VFW_FOURCC\n"); + bih = (xine_bmiheader*)track->codec_private; + _x_bmiheader_le2me(bih); - track->buf_type = _x_fourcc_to_buf_video(bih->biCompression); - init_codec = init_codec_video; + track->buf_type = _x_fourcc_to_buf_video(bih->biCompression); + init_codec = init_codec_video; + } } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_UNCOMPRESSED)) { } else if ((!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_MPEG4_SP)) || @@ -1301,6 +1312,9 @@ static int parse_track_entry(demux_matroska_t *this, matroska_track_t *track) { xine_bmiheader *bih; lprintf("MATROSKA_CODEC_ID_V_MPEG4_*\n"); + if (track->codec_private_len > 0x7fffffff - sizeof(xine_bmiheader)) + track->codec_private_len = 0x7fffffff - sizeof(xine_bmiheader); + /* create a bitmap info header struct for MPEG 4 */ bih = calloc(1, sizeof(xine_bmiheader) + track->codec_private_len); bih->biSize = sizeof(xine_bmiheader) + track->codec_private_len; @@ -1322,6 +1336,9 @@ static int parse_track_entry(demux_matroska_t *this, matroska_track_t *track) { xine_bmiheader *bih; lprintf("MATROSKA_CODEC_ID_V_MPEG4_AVC\n"); + if (track->codec_private_len > 0x7fffffff - sizeof(xine_bmiheader)) + track->codec_private_len = 0x7fffffff - sizeof(xine_bmiheader); + /* create a bitmap info header struct for h264 */ bih = calloc(1, sizeof(xine_bmiheader) + track->codec_private_len); bih->biSize = sizeof(xine_bmiheader) + track->codec_private_len; @@ -1398,11 +1415,13 @@ static int parse_track_entry(demux_matroska_t *this, matroska_track_t *track) { xine_waveformatex *wfh; lprintf("MATROSKA_CODEC_ID_A_ACM\n"); - wfh = (xine_waveformatex*)track->codec_private; - _x_waveformatex_le2me(wfh); + if (track->codec_private_len >= sizeof(xine_waveformatex)) { + wfh = (xine_waveformatex*)track->codec_private; + _x_waveformatex_le2me(wfh); - track->buf_type = _x_formattag_to_buf_audio(wfh->wFormatTag); - init_codec = init_codec_audio; + track->buf_type = _x_formattag_to_buf_audio(wfh->wFormatTag); + init_codec = init_codec_audio; + } } else if (!strncmp(track->codec_id, MATROSKA_CODEC_ID_A_AAC, sizeof(MATROSKA_CODEC_ID_A_AAC) - 1)) { lprintf("MATROSKA_CODEC_ID_A_AAC\n"); @@ -1483,9 +1502,14 @@ static int parse_track_entry(demux_matroska_t *this, matroska_track_t *track) { break; } - if (init_codec) + if (init_codec) { + if (! track->fifo) { + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + "demux_matroska: Error: fifo not set up for track of type type %" PRIu32 "\n", track->track_type); + return 0; + } init_codec(this, track); - + } } } @@ -1811,6 +1835,11 @@ static int read_block_data (demux_matroska_t *this, size_t len) { alloc_block_data(this, len); /* block datas */ + if (! this->block_data) { + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + "demux_matroska: memory allocation error\n"); + return 0; + } if (this->input->read(this->input, this->block_data, len) != len) { off_t pos = this->input->get_current_pos(this->input); xprintf(this->stream->xine, XINE_VERBOSITY_LOG, diff --git a/src/demuxers/demux_mng.c b/src/demuxers/demux_mng.c index 0fcdb24ff..d0d83ff80 100644 --- a/src/demuxers/demux_mng.c +++ b/src/demuxers/demux_mng.c @@ -104,7 +104,12 @@ static mng_bool mymng_close_stream(mng_handle mngh){ static mng_bool mymng_read_stream(mng_handle mngh, mng_ptr buffer, mng_uint32 size, mng_uint32 *bytesread){ demux_mng_t *this = (demux_mng_t*)mng_get_userdata(mngh); - *bytesread = this->input->read(this->input, buffer, size); + off_t n = this->input->read(this->input, buffer, size); + if (n < 0) { + *bytesread = 0; + return MNG_FALSE; + } + *bytesread = n; return MNG_TRUE; } @@ -112,6 +117,9 @@ static mng_bool mymng_read_stream(mng_handle mngh, mng_ptr buffer, mng_uint32 si static mng_bool mymng_process_header(mng_handle mngh, mng_uint32 width, mng_uint32 height){ demux_mng_t *this = (demux_mng_t*)mng_get_userdata(mngh); + if (width > 0x8000 || height > 0x8000) + return MNG_FALSE; + this->bih.biWidth = (width + 7) & ~7; this->bih.biHeight = height; this->left_edge = (this->bih.biWidth - width) / 2; diff --git a/src/demuxers/demux_mod.c b/src/demuxers/demux_mod.c index bffcf36d8..073927707 100644 --- a/src/demuxers/demux_mod.c +++ b/src/demuxers/demux_mod.c @@ -130,9 +130,16 @@ static int probe_mod_file(demux_mod_t *this) { /* returns 1 if the MOD file was opened successfully, 0 otherwise */ static int open_mod_file(demux_mod_t *this) { int total_read; + off_t input_length; /* Get size and create buffer */ - this->filesize = this->input->get_length(this->input); + input_length = this->input->get_length(this->input); + /* Avoid potential issues with signed variables and e.g. read() returning -1 */ + if (input_length > 0x7FFFFFFF || input_length < 0) { + xine_log(this->stream->xine, XINE_LOG_PLUGIN, "modplug - size overflow\n"); + return 0; + } + this->filesize = input_length; this->buffer = (char *)malloc(this->filesize); if(!this->buffer) { xine_log(this->stream->xine, XINE_LOG_PLUGIN, "modplug - allocation failure\n"); diff --git a/src/demuxers/demux_mpc.c b/src/demuxers/demux_mpc.c index 9b27e5954..220e1b8b6 100644 --- a/src/demuxers/demux_mpc.c +++ b/src/demuxers/demux_mpc.c @@ -209,7 +209,7 @@ static int demux_mpc_send_chunk(demux_plugin_t *this_gen) { /* Read data */ bytes_read = this->input->read(this->input, buf->content, bytes_to_read); - if(bytes_read == 0) { + if(bytes_read <= 0) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; return this->status; diff --git a/src/demuxers/demux_mpeg.c b/src/demuxers/demux_mpeg.c index fa167c70e..85b62f48e 100644 --- a/src/demuxers/demux_mpeg.c +++ b/src/demuxers/demux_mpeg.c @@ -279,6 +279,10 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, int64_t scr) if((this->dummy_space[0] & 0xE0) == 0x20) { buf = this->input->read_block (this->input, this->video_fifo, len-1); + if (! buf) { + this->status = DEMUX_FINISHED; + return; + } track = (this->dummy_space[0] & 0x1f); @@ -298,6 +302,10 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, int64_t scr) int spu_id = this->dummy_space[1] & 0x03; buf = this->input->read_block (this->input, this->video_fifo, len-1); + if (! buf) { + this->status = DEMUX_FINISHED; + return; + } buf->type = BUF_SPU_SVCD + spu_id; buf->pts = pts; @@ -318,6 +326,10 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, int64_t scr) if((this->dummy_space[0] & 0xfc) == 0x00) { buf = this->input->read_block (this->input, this->video_fifo, len-1); + if (! buf) { + this->status = DEMUX_FINISHED; + return; + } buf->type = BUF_SPU_CVD + (this->dummy_space[0] & 0x03); buf->pts = pts; @@ -376,6 +388,10 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, int64_t scr) i = this->input->read (this->input, this->dummy_space+1, 6); buf = this->input->read_block (this->input, this->video_fifo, len-7); + if (! buf) { + this->status = DEMUX_FINISHED; + return; + } buf->type = BUF_AUDIO_LPCM_BE + track; buf->decoder_flags |= BUF_FLAG_SPECIAL; @@ -920,7 +936,7 @@ static void demux_mpeg_resync (demux_mpeg_t *this, uint32_t buf) { if (pos == len) { len = this->input->read(this->input, dummy_buf, sizeof(dummy_buf)); pos = 0; - if (len == 0) { + if (len <= 0) { this->status = DEMUX_FINISHED; break; } diff --git a/src/demuxers/demux_mpeg_block.c b/src/demuxers/demux_mpeg_block.c index 3ecb88d04..4fa96faeb 100644 --- a/src/demuxers/demux_mpeg_block.c +++ b/src/demuxers/demux_mpeg_block.c @@ -1190,14 +1190,14 @@ static int demux_mpeg_detect_blocksize(demux_mpeg_block_t *this, input_plugin_t *input) { input->seek(input, 2048, SEEK_SET); - if (!input->read(input, this->scratch, 4)) + if (input->read(input, this->scratch, 4) != 4) return 0; if (this->scratch[0] || this->scratch[1] || (this->scratch[2] != 0x01) || (this->scratch[3] != 0xba)) { input->seek(input, 2324, SEEK_SET); - if (!input->read(input, this->scratch, 4)) + if (input->read(input, this->scratch, 4) != 4) return 0; if (this->scratch[0] || this->scratch[1] || (this->scratch[2] != 0x01) || (this->scratch[3] != 0xba)) @@ -1417,7 +1417,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str } input->seek(input, 0, SEEK_SET); - if (input->read(input, this->scratch, this->blocksize)) { + if (input->read(input, this->scratch, this->blocksize) == this->blocksize) { lprintf("open_plugin:read worked\n"); if (this->scratch[0] || this->scratch[1] diff --git a/src/demuxers/demux_mpeg_pes.c b/src/demuxers/demux_mpeg_pes.c index d9ac952d8..b7c0e7e6d 100644 --- a/src/demuxers/demux_mpeg_pes.c +++ b/src/demuxers/demux_mpeg_pes.c @@ -1686,7 +1686,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str if (((input->get_capabilities(input) & INPUT_CAP_SEEKABLE) != 0) ) { input->seek(input, 0, SEEK_SET); - if (input->read(input, (char *)this->scratch, 6)) { + if (input->read(input, (char *)this->scratch, 6) == 6) { lprintf("open_plugin:read worked\n"); if (this->scratch[0] || this->scratch[1] diff --git a/src/demuxers/demux_nsf.c b/src/demuxers/demux_nsf.c index 60d5049d9..926ea97e1 100644 --- a/src/demuxers/demux_nsf.c +++ b/src/demuxers/demux_nsf.c @@ -124,7 +124,7 @@ static int demux_nsf_send_chunk(demux_plugin_t *this_gen) { buf->type = BUF_AUDIO_NSF; bytes_read = this->input->read(this->input, buf->content, buf->max_size); - if (bytes_read == 0) { + if (bytes_read <= 0) { /* the file has been completely loaded, free the buffer and start * sending control buffers */ buf->free_buffer(buf); diff --git a/src/demuxers/demux_ogg.c b/src/demuxers/demux_ogg.c index 9e9de45aa..e3a9b20c4 100644 --- a/src/demuxers/demux_ogg.c +++ b/src/demuxers/demux_ogg.c @@ -237,7 +237,7 @@ static int read_ogg_packet (demux_ogg_t *this) { while (ogg_sync_pageout(&this->oy,&this->og)!=1) { buffer = ogg_sync_buffer(&this->oy, CHUNKSIZE); bytes = this->input->read(this->input, buffer, CHUNKSIZE); - if (bytes == 0) { + if (bytes <= 0) { if (total == 0) { lprintf("read_ogg_packet read nothing\n"); return 0; diff --git a/src/demuxers/demux_qt.c b/src/demuxers/demux_qt.c index 1fa9b4327..4ad71e958 100644 --- a/src/demuxers/demux_qt.c +++ b/src/demuxers/demux_qt.c @@ -738,6 +738,8 @@ static void parse_meta_atom(qt_info *info, unsigned char *meta_atom) { if (current_atom == ART_ATOM) { string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1; + if (string_size <= 0) + continue; info->artist = xine_xmalloc(string_size); if (info->artist) { strncpy(info->artist, &meta_atom[i + 20], string_size - 1); @@ -745,6 +747,8 @@ static void parse_meta_atom(qt_info *info, unsigned char *meta_atom) { } } else if (current_atom == NAM_ATOM) { string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1; + if (string_size <= 0) + continue; info->name = xine_xmalloc(string_size); if (info->name) { strncpy(info->name, &meta_atom[i + 20], string_size - 1); @@ -752,6 +756,8 @@ static void parse_meta_atom(qt_info *info, unsigned char *meta_atom) { } } else if (current_atom == ALB_ATOM) { string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1; + if (string_size <= 0) + continue; info->album = xine_xmalloc(string_size); if (info->album) { strncpy(info->album, &meta_atom[i + 20], string_size - 1); @@ -759,6 +765,8 @@ static void parse_meta_atom(qt_info *info, unsigned char *meta_atom) { } } else if (current_atom == GEN_ATOM) { string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1; + if (string_size <= 0) + continue; info->genre = xine_xmalloc(string_size); if (info->genre) { strncpy(info->genre, &meta_atom[i + 20], string_size - 1); @@ -766,6 +774,8 @@ static void parse_meta_atom(qt_info *info, unsigned char *meta_atom) { } } else if (current_atom == TOO_ATOM) { string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1; + if (string_size <= 0) + continue; info->comment = xine_xmalloc(string_size); if (info->comment) { strncpy(info->comment, &meta_atom[i + 20], string_size - 1); @@ -773,6 +783,8 @@ static void parse_meta_atom(qt_info *info, unsigned char *meta_atom) { } } else if (current_atom == WRT_ATOM) { string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1; + if (string_size <= 0) + continue; info->composer = xine_xmalloc(string_size); if (info->composer) { strncpy(info->composer, &meta_atom[i + 20], string_size - 1); @@ -780,6 +792,8 @@ static void parse_meta_atom(qt_info *info, unsigned char *meta_atom) { } } else if (current_atom == DAY_ATOM) { string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1; + if (string_size <= 0) + continue; info->year = xine_xmalloc(string_size); if (info->year) { strncpy(info->year, &meta_atom[i + 20], string_size - 1); @@ -947,6 +961,10 @@ static qt_error parse_trak_atom (qt_trak *trak, /* allocate space for each of the properties unions */ trak->stsd_atoms_count = _X_BE_32(&trak_atom[i + 8]); + if (trak->stsd_atoms_count <= 0) { + last_error = QT_HEADER_TROUBLE; + goto free_trak; + } trak->stsd_atoms = calloc(trak->stsd_atoms_count, sizeof(properties_t)); if (!trak->stsd_atoms) { last_error = QT_NO_MEMORY; @@ -958,6 +976,10 @@ static qt_error parse_trak_atom (qt_trak *trak, for (k = 0; k < trak->stsd_atoms_count; k++) { current_stsd_atom_size = _X_BE_32(&trak_atom[atom_pos - 4]); + if (current_stsd_atom_size < 4) { + last_error = QT_HEADER_TROUBLE; + goto free_trak; + } if (trak->type == MEDIA_VIDEO) { @@ -1575,13 +1597,16 @@ static qt_error parse_reference_atom (reference_t *ref, qt_atom current_atom; unsigned int current_atom_size; + if (ref_atom_size >= 0x80000000) + return QT_NOT_A_VALID_FILE; + /* initialize reference atom */ ref->url = NULL; ref->data_rate = 0; ref->qtim_version = 0; /* traverse through the atom looking for the key atoms */ - for (i = ATOM_PREAMBLE_SIZE; i < ref_atom_size - 4; i++) { + for (i = ATOM_PREAMBLE_SIZE; i + 4 < ref_atom_size; i++) { current_atom_size = _X_BE_32(&ref_atom[i - 4]); current_atom = _X_BE_32(&ref_atom[i]); @@ -1590,7 +1615,7 @@ static qt_error parse_reference_atom (reference_t *ref, size_t string_size = _X_BE_32(&ref_atom[i + 12]); size_t url_offset = 0; - if (string_size >= current_atom_size || i + string_size >= ref_atom_size) + if (string_size >= current_atom_size || string_size >= ref_atom_size - i) return QT_NOT_A_VALID_FILE; /* if the URL starts with "http://", copy it */ @@ -1598,6 +1623,8 @@ static qt_error parse_reference_atom (reference_t *ref, memcmp(&ref_atom[i + 16], "rtsp://", 7) && base_mrl ) url_offset = strlen(base_mrl); + if (url_offset >= 0x80000000) + return QT_NOT_A_VALID_FILE; /* otherwise, append relative URL to base MRL */ string_size += url_offset; @@ -2181,7 +2208,7 @@ static qt_error open_qt_file(qt_info *info, input_plugin_t *input, } /* check if moov is compressed */ - if (_X_BE_32(&moov_atom[12]) == CMOV_ATOM) { + if (_X_BE_32(&moov_atom[12]) == CMOV_ATOM && moov_atom_size >= 0x28) { info->compressed_header = 1; diff --git a/src/demuxers/demux_real.c b/src/demuxers/demux_real.c index aa4dfc26b..0df9a426e 100644 --- a/src/demuxers/demux_real.c +++ b/src/demuxers/demux_real.c @@ -318,9 +318,15 @@ static void real_free_mdpr (mdpr_t *mdpr) { } static void real_parse_audio_specific_data (demux_real_t *this, - real_stream_t * stream, - uint8_t * data) + real_stream_t * stream) { + if (stream->mdpr->type_specific_len < 46) { + xprintf (this->stream->xine, XINE_VERBOSITY_LOG, + "demux_real: audio data size smaller than header length!\n"); + return; + } + + uint8_t * data = stream->mdpr->type_specific_data; const uint32_t coded_frame_size = _X_BE_32 (data+24); const uint16_t codec_data_length = _X_BE_16 (data+40); const uint16_t coded_frame_size2 = _X_BE_16 (data+42); @@ -359,9 +365,14 @@ static void real_parse_audio_specific_data (demux_real_t *this, * stream->frame_size = stream->w / stream->sps * stream->h * stream->sps; * but it looks pointless? the compiler will probably optimise it away, I suppose? */ - stream->frame_size = stream->w * stream->h; + if (stream->w < 32768 && stream->h < 32768) { + stream->frame_size = stream->w * stream->h; + stream->frame_buffer = calloc(stream->frame_size, 1); + } else { + stream->frame_size = 0; + stream->frame_buffer = NULL; + } - stream->frame_buffer = calloc(stream->frame_size, 1); stream->frame_num_bytes = 0; stream->sub_packet_cnt = 0; @@ -430,9 +441,14 @@ static void real_parse_headers (demux_real_t *this) { case MDPR_TAG: case CONT_TAG: { + if (chunk_size < PREAMBLE_SIZE+1) { + this->status = DEMUX_FINISHED; + return; + } chunk_size -= PREAMBLE_SIZE; uint8_t *const chunk_buffer = malloc(chunk_size); - if (this->input->read(this->input, chunk_buffer, chunk_size) != + if (! chunk_buffer || + this->input->read(this->input, chunk_buffer, chunk_size) != chunk_size) { free (chunk_buffer); this->status = DEMUX_FINISHED; @@ -487,7 +503,8 @@ static void real_parse_headers (demux_real_t *this) { this->audio_streams[this->num_audio_streams].index = NULL; this->audio_streams[this->num_audio_streams].mdpr = mdpr; this->num_audio_streams++; - } else if(_X_BE_32(mdpr->type_specific_data) == RA_TAG) { + } else if(_X_BE_32(mdpr->type_specific_data) == RA_TAG && + mdpr->type_specific_len >= 6) { if(this->num_audio_streams == MAX_AUDIO_STREAMS) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: maximum number of audio stream exceeded\n"); @@ -498,26 +515,30 @@ static void real_parse_headers (demux_real_t *this) { lprintf("audio version %d detected\n", version); - char *fourcc_ptr = NULL; + char *fourcc_ptr = "\0\0\0"; switch(version) { case 3: /* Version 3 header stores fourcc after meta info - cheat by reading backwards from the * end of the header instead of having to parse it all */ - fourcc_ptr = mdpr->type_specific_data + mdpr->type_specific_len - 5; + if (mdpr->type_specific_len >= 5) + fourcc_ptr = mdpr->type_specific_data + mdpr->type_specific_len - 5; break; case 4: { - const uint8_t len = *(mdpr->type_specific_data + 56); - fourcc_ptr = mdpr->type_specific_data + 58 + len; + if (mdpr->type_specific_len >= 57) { + const uint8_t len = *(mdpr->type_specific_data + 56); + if (mdpr->type_specific_len >= 62 + len) + fourcc_ptr = mdpr->type_specific_data + 58 + len; + } } break; case 5: - fourcc_ptr = mdpr->type_specific_data + 66; + if (mdpr->type_specific_len >= 70) + fourcc_ptr = mdpr->type_specific_data + 66; break; default: lprintf("unsupported audio header version %d\n", version); goto unknown; } - lprintf("fourcc = %.4s\n", fourcc_ptr); const uint32_t fourcc = _X_ME_32(fourcc_ptr); @@ -528,11 +549,11 @@ static void real_parse_headers (demux_real_t *this) { this->audio_streams[this->num_audio_streams].mdpr = mdpr; real_parse_audio_specific_data (this, - &this->audio_streams[this->num_audio_streams], - mdpr->type_specific_data); + &this->audio_streams[this->num_audio_streams]); this->num_audio_streams++; - } else if(_X_BE_32(mdpr->type_specific_data + 4) == VIDO_TAG) { + } else if(_X_BE_32(mdpr->type_specific_data + 4) == VIDO_TAG && + mdpr->type_specific_len >= 34) { if(this->num_video_streams == MAX_VIDEO_STREAMS) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, diff --git a/src/demuxers/demux_realaudio.c b/src/demuxers/demux_realaudio.c index 1c39c6208..44449667c 100644 --- a/src/demuxers/demux_realaudio.c +++ b/src/demuxers/demux_realaudio.c @@ -202,11 +202,19 @@ static int open_ra_file(demux_ra_t *this) { this->h = _X_BE_16 (this->header+40); this->cfs = _X_BE_32 (this->header+24); - this->frame_len = this->w * this->h; - this->frame_size = this->frame_len * sps; - - this->frame_buffer = calloc(this->frame_size, 1); - _x_assert(this->frame_buffer != NULL); + if (this->w < 0x8000 && this->h < 0x8000) { + uint64_t fs; + this->frame_len = this->w * this->h; + fs = (uint64_t) this->frame_len * sps; + if (fs < 0x80000000) { + this->frame_size = fs; + this->frame_buffer = calloc(this->frame_size, 1); + } + } + if (! this->frame_buffer) { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_realaudio: malloc failed\n"); + return 0; + } if (this->audio_type == BUF_AUDIO_28_8 || this->audio_type == BUF_AUDIO_SIPRO) this->block_align = this->cfs; diff --git a/src/demuxers/demux_shn.c b/src/demuxers/demux_shn.c index 4d932305c..ccc34b57f 100644 --- a/src/demuxers/demux_shn.c +++ b/src/demuxers/demux_shn.c @@ -88,7 +88,7 @@ static int demux_shn_send_chunk(demux_plugin_t *this_gen) { buf->pts = 0; bytes_read = this->input->read(this->input, buf->content, buf->max_size); - if (bytes_read == 0) { + if (bytes_read <= 0) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; return this->status; diff --git a/src/demuxers/demux_slave.c b/src/demuxers/demux_slave.c index 28a89a973..abb4d01e5 100644 --- a/src/demuxers/demux_slave.c +++ b/src/demuxers/demux_slave.c @@ -90,10 +90,11 @@ static int demux_slave_next (demux_slave_t *this) { /* fill the scratch buffer */ n = this->input->read(this->input, &this->scratch[this->scratch_used], SCRATCH_SIZE - this->scratch_used); - this->scratch_used += n; + if (n > 0) + this->scratch_used += n; this->scratch[this->scratch_used] = '\0'; - if( !n ) { + if (n <= 0) { lprintf("connection closed\n"); this->status = DEMUX_FINISHED; return 0; diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index 55e06c033..98de1f9ea 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -1576,7 +1576,7 @@ static unsigned char * demux_synchronise(demux_ts_t* this) { do { read_length = this->input->read(this->input, this->buf, PKT_SIZE * NPKT_PER_READ); - if (read_length % PKT_SIZE) { + if (read_length < 0 || read_length % PKT_SIZE) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: read returned %d bytes (not a multiple of %d!)\n", read_length, PKT_SIZE); diff --git a/src/demuxers/demux_tta.c b/src/demuxers/demux_tta.c index 68305a444..de50ac63d 100644 --- a/src/demuxers/demux_tta.c +++ b/src/demuxers/demux_tta.c @@ -126,6 +126,10 @@ static int demux_tta_send_chunk(demux_plugin_t *this_gen) { /* buf->extra_info->input_time = this->current_sample / this->samplerate; */ bytes_read = this->input->read(this->input, buf->content, ( bytes_to_read > buf->max_size ) ? buf->max_size : bytes_to_read); + if (bytes_read < 0) { + this->status = DEMUX_FINISHED; + break; + } buf->size = bytes_read; diff --git a/src/demuxers/demux_vox.c b/src/demuxers/demux_vox.c index d646a756f..1b34106ad 100644 --- a/src/demuxers/demux_vox.c +++ b/src/demuxers/demux_vox.c @@ -77,7 +77,7 @@ static int demux_vox_send_chunk (demux_plugin_t *this_gen) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_DIALOGIC_IMA; bytes_read = this->input->read(this->input, buf->content, buf->max_size); - if (bytes_read == 0) { + if (bytes_read <= 0) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; return this->status; diff --git a/src/demuxers/demux_yuv_frames.c b/src/demuxers/demux_yuv_frames.c index c5ca363ed..089207f58 100644 --- a/src/demuxers/demux_yuv_frames.c +++ b/src/demuxers/demux_yuv_frames.c @@ -126,13 +126,19 @@ static void demux_yuv_frames_send_headers (demux_plugin_t *this_gen){ if(_x_stream_info_get(this->stream, XINE_STREAM_INFO_HAS_AUDIO)) { buf = this->input->read_block(this->input, this->audio_fifo, 0); - this->audio_fifo->put(this->audio_fifo, buf); + if (buf) + this->audio_fifo->put(this->audio_fifo, buf); + else + this->status = DEMUX_FINISHED; } if(_x_stream_info_get(this->stream, XINE_STREAM_INFO_HAS_VIDEO)) { buf = this->input->read_block(this->input, this->video_fifo, 0); - this->video_fifo->put(this->video_fifo, buf); + if (buf) + this->video_fifo->put(this->video_fifo, buf); + else + this->status = DEMUX_FINISHED; } this->status = DEMUX_OK; diff --git a/src/input/input_dvb.c b/src/input/input_dvb.c index d4f4c342f..4a1e71a38 100644 --- a/src/input/input_dvb.c +++ b/src/input/input_dvb.c @@ -2602,6 +2602,10 @@ static buf_element_t *dvb_plugin_read_block (input_plugin_t *this_gen, buf_element_t *buf = fifo->buffer_pool_alloc (fifo); int total_bytes; + if (todo < 0 || todo > buf->size) { + buf->free_buffer (buf); + return NULL; + } buf->content = buf->mem; buf->type = BUF_DEMUX_BLOCK; diff --git a/src/input/input_dvd.c b/src/input/input_dvd.c index a845d7628..ff3000e5d 100644 --- a/src/input/input_dvd.c +++ b/src/input/input_dvd.c @@ -850,6 +850,9 @@ static buf_element_t *dvd_plugin_read_block (input_plugin_t *this_gen, static off_t dvd_plugin_read (input_plugin_t *this_gen, char *ch_buf, off_t len) { /* dvd_input_plugin_t *this = (dvd_input_plugin_t*)this_gen; */ + if (len < 4) + return -1; + /* FIXME: Tricking the demux_mpeg_block plugin */ ch_buf[0] = 0; ch_buf[1] = 0; diff --git a/src/input/input_file.c b/src/input/input_file.c index 774f6b081..690913aa4 100644 --- a/src/input/input_file.c +++ b/src/input/input_file.c @@ -145,6 +145,9 @@ static int check_mmap_file(file_input_plugin_t *this) { static off_t file_plugin_read (input_plugin_t *this_gen, char *buf, off_t len) { file_input_plugin_t *this = (file_input_plugin_t *) this_gen; + if (len < 0) + return -1; + #ifdef HAVE_MMAP if ( check_mmap_file(this) ) { off_t l = len; @@ -166,6 +169,11 @@ static buf_element_t *file_plugin_read_block (input_plugin_t *this_gen, fifo_buf file_input_plugin_t *this = (file_input_plugin_t *) this_gen; buf_element_t *buf = fifo->buffer_pool_alloc (fifo); + if (todo < 0 || todo > buf->size) { + buf->free_buffer (buf); + return NULL; + } + buf->type = BUF_DEMUX_BLOCK; #ifdef HAVE_MMAP diff --git a/src/input/input_gnome_vfs.c b/src/input/input_gnome_vfs.c index 0848b9206..ec025f7b5 100644 --- a/src/input/input_gnome_vfs.c +++ b/src/input/input_gnome_vfs.c @@ -121,6 +121,11 @@ gnomevfs_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t total_bytes; buf_element_t *buf = fifo->buffer_pool_alloc (fifo); + if (todo < 0 || todo > buf->size) { + buf->free_buffer (buf); + return NULL; + } + buf->content = buf->mem; buf->type = BUF_DEMUX_BLOCK; diff --git a/src/input/input_http.c b/src/input/input_http.c index 169a0d384..3cb745656 100644 --- a/src/input/input_http.c +++ b/src/input/input_http.c @@ -421,6 +421,9 @@ static off_t http_plugin_read (input_plugin_t *this_gen, num_bytes = 0; + if (nlen < 0) + return -1; + if (this->curpos < this->preview_size) { if (nlen > (this->preview_size - this->curpos)) @@ -437,7 +440,7 @@ static off_t http_plugin_read (input_plugin_t *this_gen, n = nlen - num_bytes; - if (n) { + if (n > 0) { int read_bytes; read_bytes = http_plugin_read_int (this, &buf[num_bytes], n); @@ -503,6 +506,11 @@ static buf_element_t *http_plugin_read_block (input_plugin_t *this_gen, fifo_buf off_t total_bytes; buf_element_t *buf = fifo->buffer_pool_alloc (fifo); + if (todo < 0 || todo > buf->size) { + buf->free_buffer (buf); + return NULL; + } + buf->content = buf->mem; buf->type = BUF_DEMUX_BLOCK; @@ -554,7 +562,7 @@ static off_t http_plugin_seek(input_plugin_t *this_gen, off_t offset, int origin if ((origin == SEEK_CUR) && (offset >= 0)) { for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) { - if( !this_gen->read (this_gen, this->seek_buf, BUFSIZE) ) + if( this_gen->read (this_gen, this->seek_buf, BUFSIZE) <= 0 ) return this->curpos; } @@ -576,7 +584,7 @@ static off_t http_plugin_seek(input_plugin_t *this_gen, off_t offset, int origin offset -= this->curpos; for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) { - if( !this_gen->read (this_gen, this->seek_buf, BUFSIZE) ) + if( this_gen->read (this_gen, this->seek_buf, BUFSIZE) <= 0 ) return this->curpos; } @@ -996,6 +1004,7 @@ static int http_plugin_open (input_plugin_t *this_gen ) { this->preview_size = http_plugin_read_int (this, this->preview, MAX_PREVIEW_SIZE); } if (this->preview_size < 0) { + this->preview_size = 0; xine_log (this->stream->xine, XINE_LOG_MSG, _("input_http: read error %d\n"), errno); return -12; } diff --git a/src/input/input_mms.c b/src/input/input_mms.c index 158b40448..d5cc0a2ac 100644 --- a/src/input/input_mms.c +++ b/src/input/input_mms.c @@ -122,6 +122,11 @@ static buf_element_t *mms_plugin_read_block (input_plugin_t *this_gen, lprintf ("mms_plugin_read_block: %"PRId64" bytes...\n", todo); + if (todo < 0 || todo > buf->size) { + buf->free_buffer (buf); + return NULL; + } + buf->content = buf->mem; buf->type = BUF_DEMUX_BLOCK; diff --git a/src/input/input_net.c b/src/input/input_net.c index 391f33a60..719203ff9 100644 --- a/src/input/input_net.c +++ b/src/input/input_net.c @@ -253,6 +253,9 @@ static off_t net_plugin_read (input_plugin_t *this_gen, lprintf("reading %" PRIdMAX " bytes...\n", (intmax_t)len); + if (len < 0) + return -1; + total=0; if (this->curpos < this->preview_size) { n = this->preview_size - this->curpos; @@ -288,6 +291,11 @@ static buf_element_t *net_plugin_read_block (input_plugin_t *this_gen, buf_element_t *buf = fifo->buffer_pool_alloc (fifo); off_t total_bytes; + if (todo < 0 || todo > buf->size) { + buf->free_buffer (buf); + return NULL; + } + buf->content = buf->mem; buf->type = BUF_DEMUX_BLOCK; @@ -331,7 +339,7 @@ static off_t net_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin if ((origin == SEEK_CUR) && (offset >= 0)) { for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) { - if( !this_gen->read (this_gen, this->seek_buf, BUFSIZE) ) + if( this_gen->read (this_gen, this->seek_buf, BUFSIZE) <= 0 ) return this->curpos; } @@ -353,7 +361,7 @@ static off_t net_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin offset -= this->curpos; for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) { - if( !this_gen->read (this_gen, this->seek_buf, BUFSIZE) ) + if( this_gen->read (this_gen, this->seek_buf, BUFSIZE) <= 0 ) return this->curpos; } diff --git a/src/input/input_pnm.c b/src/input/input_pnm.c index 669d24d28..af2b8add2 100644 --- a/src/input/input_pnm.c +++ b/src/input/input_pnm.c @@ -83,7 +83,8 @@ static off_t pnm_plugin_read (input_plugin_t *this_gen, lprintf ("pnm_plugin_read: %"PRId64" bytes ...\n", len); n = pnm_read (this->pnm, buf, len); - this->curpos += n; + if (n >= 0) + this->curpos += n; return n; } @@ -96,6 +97,11 @@ static buf_element_t *pnm_plugin_read_block (input_plugin_t *this_gen, lprintf ("pnm_plugin_read_block: %"PRId64" bytes...\n", todo); + if (todo < 0 || todo > buf->size) { + buf->free_buffer (buf); + return NULL; + } + buf->content = buf->mem; buf->type = BUF_DEMUX_BLOCK; @@ -123,10 +129,16 @@ static off_t pnm_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin if ((origin == SEEK_CUR) && (offset >= 0)) { for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) { - this->curpos += pnm_plugin_read (this_gen, this->scratch, BUFSIZE); + off_t n = pnm_plugin_read (this_gen, this->scratch, BUFSIZE); + if (n <= 0) + return this->curpos; + this->curpos += n; } - this->curpos += pnm_plugin_read (this_gen, this->scratch, offset); + off_t n = pnm_plugin_read (this_gen, this->scratch, offset); + if (n <= 0) + return this->curpos; + this->curpos += n; } return this->curpos; diff --git a/src/input/input_pvr.c b/src/input/input_pvr.c index 009c76939..18d29f6be 100644 --- a/src/input/input_pvr.c +++ b/src/input/input_pvr.c @@ -424,6 +424,9 @@ static uint32_t pvr_plugin_get_capabilities (input_plugin_t *this_gen) { static off_t pvr_plugin_read (input_plugin_t *this_gen, char *buf, off_t len) { /*pvr_input_plugin_t *this = (pvr_input_plugin_t *) this_gen;*/ + if (len < 4) + return -1; + /* FIXME: Tricking the demux_mpeg_block plugin */ buf[0] = 0; buf[1] = 0; @@ -1199,6 +1202,9 @@ static buf_element_t *pvr_plugin_read_block (input_plugin_t *this_gen, fifo_buff buf_element_t *buf; int speed = _x_get_speed(this->stream); + if (todo < 0 || todo > buf->size) + return NULL; + if( !this->pvr_running ) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_pvr: thread died, aborting\n"); return NULL; diff --git a/src/input/input_rtp.c b/src/input/input_rtp.c index 66fcba87e..8d07eb6cf 100644 --- a/src/input/input_rtp.c +++ b/src/input/input_rtp.c @@ -453,6 +453,9 @@ static off_t rtp_plugin_read (input_plugin_t *this_gen, struct timespec timeout; off_t copied = 0; + if (length < 0) + return -1; + while(length > 0) { off_t n; @@ -524,6 +527,10 @@ static buf_element_t *rtp_plugin_read_block (input_plugin_t *this_gen, buf_element_t *buf = fifo->buffer_pool_alloc (fifo); int total_bytes; + if (todo < 0 || todo > buf->size) { + buf->free_buffer (buf); + return NULL; + } buf->content = buf->mem; buf->type = BUF_DEMUX_BLOCK; @@ -609,11 +616,14 @@ static int rtp_plugin_get_optional_data (input_plugin_t *this_gen, if (data_type == INPUT_OPTIONAL_DATA_PREVIEW) { if (!this->preview_read_done) { this->preview_size = rtp_plugin_read(this_gen, this->preview, MAX_PREVIEW_SIZE); + if (this->preview_size < 0) + this->preview_size = 0; lprintf("Preview data length = %d\n", this->preview_size); this->preview_read_done = 1; } - memcpy(data, this->preview, this->preview_size); + if (this->preview_size) + memcpy(data, this->preview, this->preview_size); return this->preview_size; } else { diff --git a/src/input/input_rtsp.c b/src/input/input_rtsp.c index 110c4d4b6..bfe8fdf85 100644 --- a/src/input/input_rtsp.c +++ b/src/input/input_rtsp.c @@ -84,7 +84,8 @@ static off_t rtsp_plugin_read (input_plugin_t *this_gen, lprintf ("rtsp_plugin_read: %"PRId64" bytes ...\n", len); n = rtsp_session_read (this->rtsp, buf, len); - this->curpos += n; + if (n > 0) + this->curpos += n; return n; } @@ -97,6 +98,11 @@ static buf_element_t *rtsp_plugin_read_block (input_plugin_t *this_gen, lprintf ("rtsp_plugin_read_block: %"PRId64" bytes...\n", todo); + if (todo < 0 || todo > buf->size) { + buf->free_buffer (buf); + return NULL; + } + buf->content = buf->mem; buf->type = BUF_DEMUX_BLOCK; @@ -123,10 +129,16 @@ static off_t rtsp_plugin_seek (input_plugin_t *this_gen, off_t offset, int origi if ((origin == SEEK_CUR) && (offset >= 0)) { for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) { - this->curpos += rtsp_plugin_read (this_gen, this->scratch, BUFSIZE); + off_t n = rtsp_plugin_read (this_gen, this->scratch, BUFSIZE); + if (n <= 0) + return this->curpos; + this->curpos += n; } - this->curpos += rtsp_plugin_read (this_gen, this->scratch, offset); + off_t n = rtsp_plugin_read (this_gen, this->scratch, offset); + if (n <= 0) + return this->curpos; + this->curpos += n; } return this->curpos; diff --git a/src/input/input_smb.c b/src/input/input_smb.c index 3d495f04e..4d7e9a94a 100644 --- a/src/input/input_smb.c +++ b/src/input/input_smb.c @@ -69,6 +69,8 @@ smb_plugin_read (input_plugin_t *this_gen, char *buf, off_t len) smb_input_t *this = (smb_input_t *) this_gen; off_t n, num_bytes; + if (len < 0) + return -1; num_bytes = 0; while (num_bytes < len) @@ -89,6 +91,11 @@ smb_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t total_bytes; buf_element_t *buf = fifo->buffer_pool_alloc (fifo); + if (todo < 0 || todo > buf->size) { + buf->free_buffer (buf); + return NULL; + } + buf->content = buf->mem; buf->type = BUF_DEMUX_BLOCK; diff --git a/src/input/input_stdin_fifo.c b/src/input/input_stdin_fifo.c index 0ae841b4b..4acd825a5 100644 --- a/src/input/input_stdin_fifo.c +++ b/src/input/input_stdin_fifo.c @@ -85,6 +85,8 @@ static off_t stdin_plugin_read (input_plugin_t *this_gen, off_t n, total; lprintf ("reading %"PRId64" bytes...\n", len); + if (len < 0) + return -1; total=0; if (this->curpos < this->preview_size) { @@ -121,6 +123,11 @@ static buf_element_t *stdin_plugin_read_block (input_plugin_t *this_gen, fifo_bu /* stdin_input_plugin_t *this = (stdin_input_plugin_t *) this_gen; */ buf_element_t *buf = fifo->buffer_pool_alloc (fifo); + if (todo < 0 || todo > buf->size) { + buf->free_buffer (buf); + return NULL; + } + buf->content = buf->mem; buf->type = BUF_DEMUX_BLOCK; @@ -146,7 +153,7 @@ static off_t stdin_plugin_seek (input_plugin_t *this_gen, off_t offset, int orig if ((origin == SEEK_CUR) && (offset >= 0)) { for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) { - if( !this_gen->read (this_gen, this->seek_buf, BUFSIZE) ) + if( this_gen->read (this_gen, this->seek_buf, BUFSIZE) <= 0 ) return this->curpos; } @@ -168,7 +175,7 @@ static off_t stdin_plugin_seek (input_plugin_t *this_gen, off_t offset, int orig offset -= this->curpos; for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) { - if( !this_gen->read (this_gen, this->seek_buf, BUFSIZE) ) + if( this_gen->read (this_gen, this->seek_buf, BUFSIZE) <= 0 ) return this->curpos; } @@ -270,6 +277,8 @@ static int stdin_plugin_open (input_plugin_t *this_gen ) { this->preview_size = stdin_plugin_read (&this->input_plugin, this->preview, MAX_PREVIEW_SIZE); + if (this->preview_size < 0) + this->preview_size = 0; this->curpos = 0; return 1; diff --git a/src/libsputext/demux_sputext.c b/src/libsputext/demux_sputext.c index 3e9efb079..198c30498 100644 --- a/src/libsputext/demux_sputext.c +++ b/src/libsputext/demux_sputext.c @@ -147,7 +147,7 @@ static inline void trail_space(char *s) { static char *read_line_from_input(demux_sputext_t *this, char *line, off_t len) { off_t nread = 0; - if ((len - this->buflen) > 512) { + if ((len - this->buflen) > 512 && len < SUB_BUFSIZE) { if((nread = this->input->read(this->input, &this->buf[this->buflen], len - this->buflen)) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "read failed.\n"); |