summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarren Salt <linux@youmustbejoking.demon.co.uk>2008-03-29 14:04:36 +0000
committerDarren Salt <linux@youmustbejoking.demon.co.uk>2008-03-29 14:04:36 +0000
commit7b644dec0138210a5a21e0de086cff9d816439c9 (patch)
treeaca3bb5e465787b2163ffe73ca8cb109abba61c0
parent427bd5660454820ab4de3c569b1f4727977c23ef (diff)
parentfce031eb887d7bb72acde81396f84b384aefd765 (diff)
downloadxine-lib-7b644dec0138210a5a21e0de086cff9d816439c9.tar.gz
xine-lib-7b644dec0138210a5a21e0de086cff9d816439c9.tar.bz2
Merge from 1.1.
--HG-- rename : src/libxineadec/xine_lpcm_decoder.c => src/audio_dec/xine_lpcm_decoder.c
-rw-r--r--ChangeLog3
-rw-r--r--src/audio_dec/xine_lpcm_decoder.c26
-rw-r--r--src/demuxers/demux_4xm.c2
-rw-r--r--src/demuxers/demux_aiff.c35
-rw-r--r--src/demuxers/demux_avi.c10
-rw-r--r--src/demuxers/demux_flac.c2
-rw-r--r--src/demuxers/demux_iff.c10
-rw-r--r--src/demuxers/demux_ipmovie.c5
-rw-r--r--src/demuxers/demux_qt.c29
-rw-r--r--src/demuxers/demux_realaudio.c2
-rw-r--r--src/demuxers/demux_wav.c2
11 files changed, 113 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index 49cbe6179..cbbc8d8ec 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -71,6 +71,9 @@ xine-lib (1.1.11.1) 2008-??-??
possibly execute arbitrary code. (CVE-2008-1482)
* Added a few more memory allocation checks to the above demuxers.
* WAV file playback fix: don't assume that the first chunk is "fmt ".
+ * Don't try to play partial 24-bit AIFF frames (decoder would lose data).
+ * Fixed AIFF comment chunk handling and sample rate reading.
+ * LPCM fixes: input over-reading, conversion of 24-bit samples.
xine-lib (1.1.11) 2008-03-19
* Security fixes:
diff --git a/src/audio_dec/xine_lpcm_decoder.c b/src/audio_dec/xine_lpcm_decoder.c
index e84b112f4..83043cec9 100644
--- a/src/audio_dec/xine_lpcm_decoder.c
+++ b/src/audio_dec/xine_lpcm_decoder.c
@@ -192,18 +192,34 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
uint8_t *d = (uint8_t *)audio_buffer->mem;
int n = buf->size;
- while (n >= 0) {
+ while (n >= 3) {
if ( stream_be ) {
- *d++ = s[0];
- *d++ = s[1];
+ if ( stream_be == this->cpu_be ) {
+ *d++ = s[0];
+ *d++ = s[1];
+ } else {
+ *d++ = s[1];
+ *d++ = s[0];
+ }
} else {
- *d++ = s[1];
- *d++ = s[2];
+ if ( stream_be == this->cpu_be ) {
+ *d++ = s[1];
+ *d++ = s[2];
+ }
+ else
+ {
+ *d++ = s[2];
+ *d++ = s[1];
+ }
}
s += 3;
n -= 3;
}
+
+ if ( (d - (uint8_t*)audio_buffer->mem)/2*3 < buf->size )
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "lpcm_decoder: lost %i bytes\n", (int)(buf->size - (d - (uint8_t*)audio_buffer->mem))/2*3);
+
} else {
memcpy (audio_buffer->mem, sample_buffer, buf->size);
}
diff --git a/src/demuxers/demux_4xm.c b/src/demuxers/demux_4xm.c
index 6256cb042..264806421 100644
--- a/src/demuxers/demux_4xm.c
+++ b/src/demuxers/demux_4xm.c
@@ -159,7 +159,7 @@ static int open_fourxm_file(demux_fourxm_t *fourxm) {
/* read the whole header */
header_size = _X_LE_32(&preview[4]) - 4;
header = xine_xmalloc(header_size);
- if (fourxm->input->read(fourxm->input, header, header_size) != header_size) {
+ if (!header || fourxm->input->read(fourxm->input, header, header_size) != header_size) {
free(header);
return 0;
}
diff --git a/src/demuxers/demux_aiff.c b/src/demuxers/demux_aiff.c
index 51bc624e3..06ff65680 100644
--- a/src/demuxers/demux_aiff.c
+++ b/src/demuxers/demux_aiff.c
@@ -46,6 +46,10 @@
#define COMM_TAG FOURCC_TAG('C', 'O', 'M', 'M')
#define SSND_TAG FOURCC_TAG('S', 'S', 'N', 'D')
#define APCM_TAG FOURCC_TAG('A', 'P', 'C', 'M')
+#define NAME_TAG FOURCC_TAG('N', 'A', 'M', 'E')
+#define AUTH_TAG FOURCC_TAG('A', 'U', 'T', 'H')
+#define COPY_TAG FOURCC_TAG('(', 'c', ')', ' ')
+#define ANNO_TAG FOURCC_TAG('A', 'N', 'N', 'O')
#define PREAMBLE_SIZE 8
#define AIFF_SIGNATURE_SIZE 12
@@ -80,6 +84,24 @@ typedef struct {
demux_class_t demux_class;
} demux_aiff_class_t;
+/* converts IEEE 80bit extended into int, based on FFMPEG code */
+int extended_to_int(const unsigned char p[10])
+{
+ uint64_t m = 0;
+ int e, i;
+
+ for (i = 0; i < 8; i++)
+ m = (m<<8) + p[2+i];;
+ e = (((int)p[0]&0x7f)<<8) | p[1];
+ if (e == 0x7fff && m)
+ return 0.0/0.0;
+ e -= 16383 + 63;
+
+ if (p[0]&0x80)
+ m= -m;
+ return (int) ldexp(m, e);
+}
+
/* returns 1 if the AIFF file was opened successfully, 0 otherwise */
static int open_aiff_file(demux_aiff_t *this) {
@@ -87,6 +109,7 @@ static int open_aiff_file(demux_aiff_t *this) {
unsigned char preamble[PREAMBLE_SIZE];
unsigned int chunk_type;
unsigned int chunk_size;
+ unsigned char extended_sample_rate[10];
if (_x_demux_read_header(this->input, signature, AIFF_SIGNATURE_SIZE) != AIFF_SIGNATURE_SIZE)
return 0;
@@ -135,7 +158,8 @@ static int open_aiff_file(demux_aiff_t *this) {
this->audio_channels = _X_BE_16(&buffer[0]);
this->audio_frames = _X_BE_32(&buffer[2]);
this->audio_bits = _X_BE_16(&buffer[6]);
- this->audio_sample_rate = _X_BE_16(&buffer[0x0A]);
+ memcpy(&extended_sample_rate, &buffer[8], sizeof(extended_sample_rate));
+ this->audio_sample_rate = extended_to_int(extended_sample_rate);
this->audio_bytes_per_second = this->audio_channels *
(this->audio_bits / 8) * this->audio_sample_rate;
@@ -150,11 +174,18 @@ static int open_aiff_file(demux_aiff_t *this) {
(this->audio_bits / 8);
this->running_time = (this->audio_frames / this->audio_sample_rate) * 1000;
- this->audio_block_align = PCM_BLOCK_ALIGN;
+ /* we should send only complete frames to decoder, as it
+ * doesn't handle underconsumption yet */
+ this->audio_block_align = PCM_BLOCK_ALIGN - PCM_BLOCK_ALIGN % (this->audio_bits / 8 * this->audio_channels);
break;
} else {
+ /* if chunk contains metadata, it will be word-aligned (as seen at sox and ffmpeg) */
+ if ( ((chunk_type == NAME_TAG) || (chunk_type==AUTH_TAG) ||
+ (chunk_type == COPY_TAG) || (chunk_type==ANNO_TAG)) && (chunk_size&1))
+ chunk_size++;
+
/* unrecognized; skip it */
this->input->seek(this->input, chunk_size, SEEK_CUR);
}
diff --git a/src/demuxers/demux_avi.c b/src/demuxers/demux_avi.c
index 27dfce443..e06caf94f 100644
--- a/src/demuxers/demux_avi.c
+++ b/src/demuxers/demux_avi.c
@@ -973,6 +973,10 @@ static avi_t *AVI_init(demux_avi_t *this) {
xine_waveformatex *wavex;
wavex = (xine_waveformatex *)malloc(n);
+ if (!wavex) {
+ this->AVI_errno = AVI_ERR_NO_MEM;
+ return 0;
+ }
memcpy((void *)wavex, hdrl_data+i, n);
_x_waveformatex_le2me( wavex );
@@ -1237,6 +1241,9 @@ static avi_t *AVI_init(demux_avi_t *this) {
/* read from file */
chunk_start = en = malloc (AVI->video_superindex->aIndex[j].dwSize+hdrl_len);
+ if (!chunk_start)
+ ERR_EXIT(AVI_ERR_NO_MEM);
+
if (this->input->seek(this->input, AVI->video_superindex->aIndex[j].qwOffset, SEEK_SET) == (off_t)-1) {
lprintf("cannot seek to 0x%" PRIx64 "\n", AVI->video_superindex->aIndex[j].qwOffset);
free(chunk_start);
@@ -1308,6 +1315,9 @@ static avi_t *AVI_init(demux_avi_t *this) {
/* read from file */
chunk_start = en = malloc (audio->audio_superindex->aIndex[j].dwSize+hdrl_len);
+ if (!chunk_start)
+ ERR_EXIT(AVI_ERR_NO_MEM);
+
if (this->input->seek(this->input, audio->audio_superindex->aIndex[j].qwOffset, SEEK_SET) == (off_t)-1) {
lprintf("cannot seek to 0x%" PRIx64 "\n", audio->audio_superindex->aIndex[j].qwOffset);
free(chunk_start);
diff --git a/src/demuxers/demux_flac.c b/src/demuxers/demux_flac.c
index ed974a69c..94c599562 100644
--- a/src/demuxers/demux_flac.c
+++ b/src/demuxers/demux_flac.c
@@ -166,6 +166,8 @@ static int open_flac_file(demux_flac_t *flac) {
flac->seekpoint_count = block_length / FLAC_SEEKPOINT_SIZE;
flac->seekpoints = xine_xcalloc(flac->seekpoint_count,
sizeof(flac_seekpoint_t));
+ if (flac->seekpoint_count && !flac->seekpoints)
+ return 0;
for (i = 0; i < flac->seekpoint_count; i++) {
if (flac->input->read(flac->input, buffer, FLAC_SEEKPOINT_SIZE) != FLAC_SEEKPOINT_SIZE)
return 0;
diff --git a/src/demuxers/demux_iff.c b/src/demuxers/demux_iff.c
index 665d29cd2..dcef148b4 100644
--- a/src/demuxers/demux_iff.c
+++ b/src/demuxers/demux_iff.c
@@ -401,7 +401,7 @@ static int read_iff_chunk(demux_iff_t *this) {
this->cmap_num = junk_size / PIC_SIZE_OF_COLOR_REGISTER;
this->cmap = (ColorRegister *)xine_xmalloc(junk_size);
this->video_send_palette = 1;
- if (this->input->read(this->input, (char *)this->cmap, junk_size) != junk_size)
+ if (!this->cmap || this->input->read(this->input, (char *)this->cmap, junk_size) != junk_size)
return 0;
break;
case IFF_GRAB_CHUNK:
@@ -709,11 +709,19 @@ static int demux_iff_send_chunk(demux_plugin_t *this_gen) {
/* load the whole chunk into the buffer */
if (this->audio_buffer_filled == 0) {
if (this->audio_interleave_buffer_size > 0)
+ {
this->audio_interleave_buffer =
xine_xmalloc(this->audio_interleave_buffer_size);
+ if (!this->audio_interleave_buffer)
+ return this->status = DEMUX_FINISHED;
+ }
if (this->audio_read_buffer_size > 0)
+ {
this->audio_read_buffer =
xine_xmalloc(this->audio_read_buffer_size);
+ if (!this->audio_read_buffer)
+ return this->status = DEMUX_FINISHED;
+ }
if (this->audio_read_buffer) {
if (this->input->read(this->input, this->audio_read_buffer,
this->data_size) != this->data_size) {
diff --git a/src/demuxers/demux_ipmovie.c b/src/demuxers/demux_ipmovie.c
index 4d08af6fa..88fd70811 100644
--- a/src/demuxers/demux_ipmovie.c
+++ b/src/demuxers/demux_ipmovie.c
@@ -283,9 +283,10 @@ static int process_ipmovie_chunk(demux_ipmovie_t *this) {
this->bih.biWidth = _X_LE_16(&scratch[0]) * 8;
this->bih.biHeight = _X_LE_16(&scratch[2]) * 8;
/* set up staging area for decode map */
- this->decode_map_size = (this->bih.biWidth * this->bih.biHeight) /
- (8 * 8) / 2;
+ this->decode_map_size = (this->bih.biWidth / 8) * (this->bih.biHeight / 8) / 2;
this->decode_map = xine_xmalloc(this->decode_map_size);
+ if (!this->decode_map)
+ this->status = DEMUX_FINISHED;
lprintf("video resolution: %d x %d\n",
this->bih.biWidth, this->bih.biHeight);
break;
diff --git a/src/demuxers/demux_qt.c b/src/demuxers/demux_qt.c
index 15b2773eb..9207a97e0 100644
--- a/src/demuxers/demux_qt.c
+++ b/src/demuxers/demux_qt.c
@@ -939,6 +939,11 @@ static qt_error parse_trak_atom (qt_trak *trak,
const uint32_t current_atom_size = _X_BE_32(&trak_atom[i - 4]);
const qt_atom current_atom = _X_BE_32(&trak_atom[i]);
+ if (current_atom_size > trak_atom_size - i) {
+ last_error = QT_NOT_A_VALID_FILE;
+ goto free_trak;
+ }
+
switch(current_atom) {
case TKHD_ATOM:
trak->flags = _X_BE_16(&trak_atom[i + 6]);
@@ -1025,6 +1030,10 @@ static qt_error parse_trak_atom (qt_trak *trak,
trak->stsd_atoms[k].video.properties_atom_size = current_stsd_atom_size - 4;
trak->stsd_atoms[k].video.properties_atom =
xine_xmalloc(trak->stsd_atoms[k].video.properties_atom_size);
+ if (!trak->stsd_atoms[k].video.properties_atom) {
+ last_error = QT_NO_MEMORY;
+ goto free_trak;
+ }
memcpy(trak->stsd_atoms[k].video.properties_atom, &trak_atom[atom_pos],
trak->stsd_atoms[k].video.properties_atom_size);
@@ -1164,6 +1173,10 @@ static qt_error parse_trak_atom (qt_trak *trak,
trak->stsd_atoms[k].audio.properties_atom_size = current_stsd_atom_size - 4;
trak->stsd_atoms[k].audio.properties_atom =
xine_xmalloc(trak->stsd_atoms[k].audio.properties_atom_size);
+ if (!trak->stsd_atoms[k].audio.properties_atom) {
+ last_error = QT_NO_MEMORY;
+ goto free_trak;
+ }
memcpy(trak->stsd_atoms[k].audio.properties_atom, &trak_atom[atom_pos],
trak->stsd_atoms[k].audio.properties_atom_size);
@@ -1280,6 +1293,10 @@ static qt_error parse_trak_atom (qt_trak *trak,
trak->stsd_atoms[k].audio.properties_atom_size = 36;
trak->stsd_atoms[k].audio.properties_atom =
xine_xmalloc(trak->stsd_atoms[k].audio.properties_atom_size);
+ if (!trak->stsd_atoms[k].audio.properties_atom) {
+ last_error = QT_NO_MEMORY;
+ goto free_trak;
+ }
memcpy(trak->stsd_atoms[k].audio.properties_atom,
&trak_atom[atom_pos + 0x20],
trak->stsd_atoms[k].audio.properties_atom_size);
@@ -1301,6 +1318,10 @@ static qt_error parse_trak_atom (qt_trak *trak,
(current_atom_size >= (0x4C + wave_size))) {
trak->stsd_atoms[k].audio.wave_size = wave_size;
trak->stsd_atoms[k].audio.wave = xine_xmalloc(wave_size);
+ if (!trak->stsd_atoms[k].audio.wave) {
+ last_error = QT_NO_MEMORY;
+ goto free_trak;
+ }
memcpy(trak->stsd_atoms[k].audio.wave, &trak_atom[atom_pos + 0x4C],
wave_size);
_x_waveformatex_le2me(trak->stsd_atoms[k].audio.wave);
@@ -1370,8 +1391,16 @@ static qt_error parse_trak_atom (qt_trak *trak,
j += mp4_read_descr_len( &trak_atom[j], &len );
debug_atom_load(" decoder config is %d (0x%X) bytes long\n",
len, len);
+ if (len > current_atom_size - (j - i)) {
+ last_error = QT_NOT_A_VALID_FILE;
+ goto free_trak;
+ }
trak->decoder_config = realloc(trak->decoder_config, len);
trak->decoder_config_len = len;
+ if (!trak->decoder_config) {
+ last_error = QT_NO_MEMORY;
+ goto free_trak;
+ }
memcpy(trak->decoder_config,&trak_atom[j],len);
}
}
diff --git a/src/demuxers/demux_realaudio.c b/src/demuxers/demux_realaudio.c
index 732ddfcc4..7ee608c83 100644
--- a/src/demuxers/demux_realaudio.c
+++ b/src/demuxers/demux_realaudio.c
@@ -103,7 +103,7 @@ static int open_ra_file(demux_ra_t *this) {
/* allocate for and read header data */
this->header = xine_xmalloc(this->header_size);
- if (_x_demux_read_header(this->input, this->header, this->header_size) != this->header_size) {
+ if (!this->header || _x_demux_read_header(this->input, this->header, this->header_size) != this->header_size) {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_realaudio: unable to read header\n");
free(this->header);
return 0;
diff --git a/src/demuxers/demux_wav.c b/src/demuxers/demux_wav.c
index 0c17c836a..2beb43291 100644
--- a/src/demuxers/demux_wav.c
+++ b/src/demuxers/demux_wav.c
@@ -131,7 +131,7 @@ static int open_wav_file(demux_wav_t *this) {
this->input->seek(this->input, wave_pos, SEEK_SET);
this->wave = xine_xmalloc( this->wave_size );
- if (this->input->read(this->input, (void *)this->wave, this->wave_size) !=
+ if (!this->wave || this->input->read(this->input, (void *)this->wave, this->wave_size) !=
this->wave_size) {
free (this->wave);
return 0;