summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarren Salt <linux@youmustbejoking.demon.co.uk>2009-01-05 23:40:10 +0000
committerDarren Salt <linux@youmustbejoking.demon.co.uk>2009-01-05 23:40:10 +0000
commit85f173cd5b12d5a53a94a2616c498cdae68fec2a (patch)
tree655dbc4dcb7e2950bde6492c66e2572d53873c6e
parent92d532f070f578c4f7f0df3daadf05497be1ed10 (diff)
parent5347abe5764b0a0ff3ef1d357ce9934a425758fa (diff)
downloadxine-lib-85f173cd5b12d5a53a94a2616c498cdae68fec2a.tar.gz
xine-lib-85f173cd5b12d5a53a94a2616c498cdae68fec2a.tar.bz2
Merge security fixes from 1.1.
--HG-- rename : src/demuxers/demux_nsf.c => src/combined/nsf_demuxer.c rename : src/demuxers/demux_ogg.c => src/combined/xine_ogg_demuxer.c rename : src/libsputext/demux_sputext.c => src/spu_dec/sputext_demuxer.c
-rw-r--r--ChangeLog18
-rw-r--r--misc/cdda_server.c11
-rw-r--r--src/combined/ffmpeg/ff_audio_decoder.c2
-rw-r--r--src/combined/ffmpeg/ff_video_decoder.c24
-rw-r--r--src/combined/nsf_demuxer.c2
-rw-r--r--src/combined/xine_ogg_demuxer.c2
-rw-r--r--src/demuxers/demux_aac.c2
-rw-r--r--src/demuxers/demux_ac3.c8
-rw-r--r--src/demuxers/demux_asf.c10
-rw-r--r--src/demuxers/demux_dts.c2
-rw-r--r--src/demuxers/demux_matroska.c46
-rw-r--r--src/demuxers/demux_mng.c10
-rw-r--r--src/demuxers/demux_mod.c9
-rw-r--r--src/demuxers/demux_mpc.c2
-rw-r--r--src/demuxers/demux_mpeg.c18
-rw-r--r--src/demuxers/demux_mpeg_block.c6
-rw-r--r--src/demuxers/demux_mpeg_pes.c2
-rw-r--r--src/demuxers/demux_qt.c15
-rw-r--r--src/demuxers/demux_real.c51
-rw-r--r--src/demuxers/demux_realaudio.c18
-rw-r--r--src/demuxers/demux_shn.c2
-rw-r--r--src/demuxers/demux_slave.c5
-rw-r--r--src/demuxers/demux_ts.c2
-rw-r--r--src/demuxers/demux_tta.c4
-rw-r--r--src/demuxers/demux_vox.c2
-rw-r--r--src/demuxers/demux_yuv_frames.c10
-rw-r--r--src/input/input_dvb.c4
-rw-r--r--src/input/input_dvd.c3
-rw-r--r--src/input/input_file.c8
-rw-r--r--src/input/input_gnome_vfs.c5
-rw-r--r--src/input/input_http.c15
-rw-r--r--src/input/input_mms.c5
-rw-r--r--src/input/input_net.c12
-rw-r--r--src/input/input_pnm.c18
-rw-r--r--src/input/input_pvr.c3
-rw-r--r--src/input/input_rtp.c12
-rw-r--r--src/input/input_rtsp.c18
-rw-r--r--src/input/input_smb.c7
-rw-r--r--src/input/input_stdin_fifo.c13
-rw-r--r--src/spu_dec/sputext_demuxer.c2
40 files changed, 316 insertions, 92 deletions
diff --git a/ChangeLog b/ChangeLog
index 15d925c23..45c6e5798 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -69,6 +69,17 @@ xine-lib (1.1.90) (Unreleased)
colour controls, zooming, colour keying.
xine-lib (1.1.16) 2008-??-??
+ * Security fixes:
+ - Heap overflow in Quicktime atom parsing. (CVE-2008-5234)
+ - Multiple buffer overflows. (CVE-2008-5236)
+ - Multiple integer overflows. (CVE-2008-5237)
+ - Unchecked or incompletely-checked read function results. (CVE-2008-5239)
+ - Unchecked malloc using untrusted values. (CVE-2008-5240)
+ - Buffer indexing using untrusted or unchecked values. (CVE-2008-5243)
+ - Integer overflows in the ffmpeg audio decoder and the CDDA server.
+ - Heap buffer overflow in the ffmpeg video decoder.
+ - Avoid segfault on invalid track type in Matroska files.
+ - Avoid underflow (compressed atoms) in the Qt demuxer.
* Fix reported compilation failures (with C++ programs).
* Fix CDDB access in 64-bit builds.
* Fix seeking FLV clips that don't specify the movie length in the headers.
@@ -97,10 +108,16 @@ xine-lib (1.1.15) 2008-08-14
(CVE-2008-3231)
This includes a libfaad update from the 1.2 branch.
- Delay V4L video frame preallocation until we know how large they'll be.
+ (CVE-2008-5245)
- Fix an exploitable ID3 heap buffer overflow.
+ (CVE-2008-5234, vector 2)
- Check for possible buffer overflow attempts in the Real demuxer.
+ (CVE-2008-5235)
- Use size_t for data length variables where there may be int overflows.
- Add some checks for memory allocation failures.
+ (CVE-2008-5233)
+ - Fix crashes with MP3 files with metadata consisting only of separators.
+ (CVE-2008-5248)
* Use external ffmpeg and libfaad by default.
* V4L: Don't segfault if asked for an input that doesn't exist.
* Recognise AMR audio (normally found in 3GP files).
@@ -110,7 +127,6 @@ xine-lib (1.1.15) 2008-08-14
others, there would be no problem.
* V4L: only try and set the tuner if we're going to use it. Setting the tuner
when using baseband video (CVBS, S-Video) breaks the input.
- * Fix crashes with MP3 files with metadata consisting only of separators.
xine-lib (1.1.14) 2008-06-29
* DVB changes:
diff --git a/misc/cdda_server.c b/misc/cdda_server.c
index 553ec0a8a..0e2817db3 100644
--- a/misc/cdda_server.c
+++ b/misc/cdda_server.c
@@ -480,6 +480,12 @@ static int process_commands( int socket )
sscanf(cmd,"%*s %d %d", &start_frame, &num_frames);
+ if (num_frames > INT_MAX / CD_RAW_FRAME_SIZE)
+ {
+ printf ("fatal error: integer overflow\n");
+ exit (1);
+ }
+
n = num_frames * CD_RAW_FRAME_SIZE;
buf = malloc( n );
if( !buf )
@@ -556,6 +562,11 @@ static int process_commands( int socket )
char *buf;
sscanf(cmd,"%*s %d %d", &blocks, &flags);
+ if (blocks > INT_MAX / DVD_BLOCK_SIZE)
+ {
+ printf ("fatal error: integer overflow\n");
+ exit (1);
+ }
n = blocks * DVD_BLOCK_SIZE;
buf = malloc( n );
diff --git a/src/combined/ffmpeg/ff_audio_decoder.c b/src/combined/ffmpeg/ff_audio_decoder.c
index a3c61b097..38b393506 100644
--- a/src/combined/ffmpeg/ff_audio_decoder.c
+++ b/src/combined/ffmpeg/ff_audio_decoder.c
@@ -248,6 +248,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 eca73d982..885e0ec18 100644
--- a/src/combined/ffmpeg/ff_video_decoder.c
+++ b/src/combined/ffmpeg/ff_video_decoder.c
@@ -608,6 +608,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(
@@ -628,7 +632,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) {
@@ -650,7 +654,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) {
@@ -658,7 +662,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;
@@ -686,7 +690,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;
@@ -715,7 +719,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;
@@ -743,7 +747,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;
@@ -767,7 +771,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;
@@ -810,7 +814,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++;
@@ -827,7 +831,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];
@@ -835,7 +839,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/combined/nsf_demuxer.c b/src/combined/nsf_demuxer.c
index 8ee816c99..059a91ff4 100644
--- a/src/combined/nsf_demuxer.c
+++ b/src/combined/nsf_demuxer.c
@@ -125,7 +125,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/combined/xine_ogg_demuxer.c b/src/combined/xine_ogg_demuxer.c
index 036d2f0fc..5ec30c00d 100644
--- a/src/combined/xine_ogg_demuxer.c
+++ b/src/combined/xine_ogg_demuxer.c
@@ -240,7 +240,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_aac.c b/src/demuxers/demux_aac.c
index 4076cc2e0..18dbda6c2 100644
--- a/src/demuxers/demux_aac.c
+++ b/src/demuxers/demux_aac.c
@@ -168,7 +168,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 8d0dc452c..be6f02806 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 ff2d1e6a8..9d0447ce5 100644
--- a/src/demuxers/demux_asf.c
+++ b/src/demuxers/demux_asf.c
@@ -734,7 +734,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]);
@@ -813,7 +816,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 e16d78f64..6943ed660 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 18fb23f55..92776f973 100644
--- a/src/demuxers/demux_matroska.c
+++ b/src/demuxers/demux_matroska.c
@@ -1183,7 +1183,12 @@ static int parse_track_entry(demux_matroska_t *this, matroska_track_t *track) {
break;
case MATROSKA_ID_TR_CODECPRIVATE: {
- uint8_t *codec_private = malloc (elem.len);
+ uint8_t *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,14 +1292,16 @@ 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);
- if (!track->buf_type)
- _x_report_video_fourcc (this->stream->xine, LOG_MODULE, bih->biCompression);
- init_codec = init_codec_video;
+ track->buf_type = _x_fourcc_to_buf_video(bih->biCompression);
+ if (!track->buf_type)
+ _x_report_video_fourcc (this->stream->xine, LOG_MODULE, 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)) ||
@@ -1400,13 +1407,15 @@ 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);
- if (!track->buf_type)
- _x_report_audio_format_tag (this->stream->xine, LOG_MODULE, wfh->wFormatTag);
- init_codec = init_codec_audio;
+ track->buf_type = _x_formattag_to_buf_audio(wfh->wFormatTag);
+ if (!track->buf_type)
+ _x_report_audio_format_tag (this->stream->xine, LOG_MODULE, 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");
@@ -1487,9 +1496,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);
-
+ }
}
}
diff --git a/src/demuxers/demux_mng.c b/src/demuxers/demux_mng.c
index 499811d54..0dbdf21a5 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 ab5157531..fbb20dca3 100644
--- a/src/demuxers/demux_mod.c
+++ b/src/demuxers/demux_mod.c
@@ -127,9 +127,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 b5516bad5..428ed884c 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 2c47a71a0..3640fc516 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 f8002ef9c..db98a34cc 100644
--- a/src/demuxers/demux_mpeg_block.c
+++ b/src/demuxers/demux_mpeg_block.c
@@ -1195,14 +1195,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))
@@ -1422,7 +1422,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 0fd62197b..02004e4df 100644
--- a/src/demuxers/demux_mpeg_pes.c
+++ b/src/demuxers/demux_mpeg_pes.c
@@ -1691,7 +1691,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_qt.c b/src/demuxers/demux_qt.c
index 5a9b0d88b..972395533 100644
--- a/src/demuxers/demux_qt.c
+++ b/src/demuxers/demux_qt.c
@@ -1000,7 +1000,11 @@ 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]);
- trak->stsd_atoms = xine_xcalloc(trak->stsd_atoms_count, sizeof(properties_t));
+ 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;
goto free_trak;
@@ -1011,6 +1015,10 @@ static qt_error parse_trak_atom (qt_trak *trak,
for (k = 0; k < trak->stsd_atoms_count; k++) {
const uint32_t 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) {
/* for palette traversal */
@@ -1632,6 +1640,9 @@ static qt_error parse_reference_atom (reference_t *ref,
int i, j;
const unsigned int ref_atom_size = _X_BE_32(&ref_atom[0]);
+ if (ref_atom_size >= 0x80000000)
+ return QT_NOT_A_VALID_FILE;
+
/* initialize reference atom */
ref->url = NULL;
ref->data_rate = 0;
@@ -2246,7 +2257,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 5a3a463ae..376eb63b2 100644
--- a/src/demuxers/demux_real.c
+++ b/src/demuxers/demux_real.c
@@ -312,9 +312,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);
@@ -353,9 +359,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;
@@ -424,9 +435,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;
@@ -481,7 +497,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");
@@ -492,26 +509,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);
@@ -525,11 +546,11 @@ static void real_parse_headers (demux_real_t *this) {
_x_report_audio_format_tag (this->stream->xine, LOG_MODULE, fourcc);
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 75c20d61f..4d04f0b90 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 d72a999fd..a874deba6 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 25fd1ab63..cd90cbee0 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 a058bacac..0575bcff3 100644
--- a/src/demuxers/demux_ts.c
+++ b/src/demuxers/demux_ts.c
@@ -1562,7 +1562,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 4d22481c8..ce6ddb23a 100644
--- a/src/demuxers/demux_tta.c
+++ b/src/demuxers/demux_tta.c
@@ -125,6 +125,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 12de83ac9..8fb3cb61f 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 454541f06..0288c00fb 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 ac8de3680..4b8b47e43 100644
--- a/src/input/input_dvb.c
+++ b/src/input/input_dvb.c
@@ -2590,6 +2590,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 58e7dbb8b..0e5078099 100644
--- a/src/input/input_dvd.c
+++ b/src/input/input_dvd.c
@@ -851,6 +851,9 @@ static off_t dvd_plugin_read (input_plugin_t *this_gen, void *buf_gen, off_t len
/* dvd_input_plugin_t *this = (dvd_input_plugin_t*)this_gen; */
char *ch_buf = (char *)buf_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 31c682ad7..387b8c4ea 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, void *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 7fb2d8b00..cb0c88877 100644
--- a/src/input/input_gnome_vfs.c
+++ b/src/input/input_gnome_vfs.c
@@ -122,6 +122,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 83d4bdff1..3b87e003d 100644
--- a/src/input/input_http.c
+++ b/src/input/input_http.c
@@ -389,6 +389,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))
@@ -405,7 +408,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);
@@ -471,6 +474,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;
@@ -522,7 +530,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;
}
@@ -544,7 +552,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;
}
@@ -970,6 +978,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 136307c80..3d06653ea 100644
--- a/src/input/input_mms.c
+++ b/src/input/input_mms.c
@@ -123,6 +123,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 4b74d705d..964995bf6 100644
--- a/src/input/input_net.c
+++ b/src/input/input_net.c
@@ -254,6 +254,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;
@@ -289,6 +292,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;
@@ -332,7 +340,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;
}
@@ -354,7 +362,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 66d8a9196..afb64e3f5 100644
--- a/src/input/input_pnm.c
+++ b/src/input/input_pnm.c
@@ -84,7 +84,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;
}
@@ -97,6 +98,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;
@@ -124,10 +130,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 17c251c40..0f2bee57e 100644
--- a/src/input/input_pvr.c
+++ b/src/input/input_pvr.c
@@ -425,6 +425,9 @@ static off_t pvr_plugin_read (input_plugin_t *this_gen, void *buf_gen, off_t len
/*pvr_input_plugin_t *this = (pvr_input_plugin_t *) this_gen;*/
char *buf = (char *)buf_gen;
+ if (len < 4)
+ return -1;
+
/* FIXME: Tricking the demux_mpeg_block plugin */
buf[0] = 0;
buf[1] = 0;
diff --git a/src/input/input_rtp.c b/src/input/input_rtp.c
index 2c9de54d4..4d1fb43a9 100644
--- a/src/input/input_rtp.c
+++ b/src/input/input_rtp.c
@@ -454,6 +454,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;
@@ -525,6 +528,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;
@@ -610,11 +617,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 3fbd7631f..0522f555b 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 9d6f3d9a6..b7c864f50 100644
--- a/src/input/input_smb.c
+++ b/src/input/input_smb.c
@@ -70,6 +70,8 @@ smb_plugin_read (input_plugin_t *this_gen, void *buf_gen, off_t len)
char *buf = (char *)buf_gen;
off_t n, num_bytes;
+ if (len < 0)
+ return -1;
num_bytes = 0;
while (num_bytes < len)
@@ -90,6 +92,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 648f17438..2797568b6 100644
--- a/src/input/input_stdin_fifo.c
+++ b/src/input/input_stdin_fifo.c
@@ -86,6 +86,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) {
@@ -122,6 +124,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;
@@ -147,7 +154,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;
}
@@ -169,7 +176,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;
}
@@ -271,6 +278,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/spu_dec/sputext_demuxer.c b/src/spu_dec/sputext_demuxer.c
index fe259381c..20c0499da 100644
--- a/src/spu_dec/sputext_demuxer.c
+++ b/src/spu_dec/sputext_demuxer.c
@@ -149,7 +149,7 @@ static char *read_line_from_input(demux_sputext_t *this, char *line, off_t len)
char *s;
int linelen;
- 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");