Commit 5d045046 authored by Justin Ruggles's avatar Justin Ruggles

idcin: better error handling

Add some additional checks for EOF and print error messages on an incomplete
header or packet.

FATE reference updated for id-cin-video due to the demuxer no longer
returning a partial video packet at EOF.
parent 33f58c36
...@@ -147,6 +147,7 @@ static int idcin_read_header(AVFormatContext *s) ...@@ -147,6 +147,7 @@ static int idcin_read_header(AVFormatContext *s)
AVStream *st; AVStream *st;
unsigned int width, height; unsigned int width, height;
unsigned int sample_rate, bytes_per_sample, channels; unsigned int sample_rate, bytes_per_sample, channels;
int ret;
/* get the 5 header parameters */ /* get the 5 header parameters */
width = avio_rl32(pb); width = avio_rl32(pb);
...@@ -155,6 +156,11 @@ static int idcin_read_header(AVFormatContext *s) ...@@ -155,6 +156,11 @@ static int idcin_read_header(AVFormatContext *s)
bytes_per_sample = avio_rl32(pb); bytes_per_sample = avio_rl32(pb);
channels = avio_rl32(pb); channels = avio_rl32(pb);
if (s->pb->eof_reached) {
av_log(s, AV_LOG_ERROR, "incomplete header\n");
return s->pb->error ? s->pb->error : AVERROR_EOF;
}
if (av_image_check_size(width, height, 0, s) < 0) if (av_image_check_size(width, height, 0, s) < 0)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
if (sample_rate > 0) { if (sample_rate > 0) {
...@@ -192,9 +198,13 @@ static int idcin_read_header(AVFormatContext *s) ...@@ -192,9 +198,13 @@ static int idcin_read_header(AVFormatContext *s)
/* load up the Huffman tables into extradata */ /* load up the Huffman tables into extradata */
st->codec->extradata_size = HUFFMAN_TABLE_SIZE; st->codec->extradata_size = HUFFMAN_TABLE_SIZE;
st->codec->extradata = av_malloc(HUFFMAN_TABLE_SIZE); st->codec->extradata = av_malloc(HUFFMAN_TABLE_SIZE);
if (avio_read(pb, st->codec->extradata, HUFFMAN_TABLE_SIZE) != ret = avio_read(pb, st->codec->extradata, HUFFMAN_TABLE_SIZE);
HUFFMAN_TABLE_SIZE) if (ret < 0) {
return ret;
} else if (ret != HUFFMAN_TABLE_SIZE) {
av_log(s, AV_LOG_ERROR, "incomplete header\n");
return AVERROR(EIO); return AVERROR(EIO);
}
if (idcin->audio_present) { if (idcin->audio_present) {
idcin->audio_present = 1; idcin->audio_present = 1;
...@@ -251,7 +261,7 @@ static int idcin_read_packet(AVFormatContext *s, ...@@ -251,7 +261,7 @@ static int idcin_read_packet(AVFormatContext *s,
uint32_t palette[256]; uint32_t palette[256];
if (s->pb->eof_reached) if (s->pb->eof_reached)
return AVERROR(EIO); return s->pb->error ? s->pb->error : AVERROR_EOF;
if (idcin->next_chunk_is_video) { if (idcin->next_chunk_is_video) {
command = avio_rl32(pb); command = avio_rl32(pb);
...@@ -259,8 +269,13 @@ static int idcin_read_packet(AVFormatContext *s, ...@@ -259,8 +269,13 @@ static int idcin_read_packet(AVFormatContext *s,
return AVERROR(EIO); return AVERROR(EIO);
} else if (command == 1) { } else if (command == 1) {
/* trigger a palette change */ /* trigger a palette change */
if (avio_read(pb, palette_buffer, 768) != 768) ret = avio_read(pb, palette_buffer, 768);
if (ret < 0) {
return ret;
} else if (ret != 768) {
av_log(s, AV_LOG_ERROR, "incomplete packet\n");
return AVERROR(EIO); return AVERROR(EIO);
}
/* scale the palette as necessary */ /* scale the palette as necessary */
palette_scale = 2; palette_scale = 2;
for (i = 0; i < 768; i++) for (i = 0; i < 768; i++)
...@@ -277,6 +292,10 @@ static int idcin_read_packet(AVFormatContext *s, ...@@ -277,6 +292,10 @@ static int idcin_read_packet(AVFormatContext *s,
} }
} }
if (s->pb->eof_reached) {
av_log(s, AV_LOG_ERROR, "incomplete packet\n");
return s->pb->error ? s->pb->error : AVERROR_EOF;
}
chunk_size = avio_rl32(pb); chunk_size = avio_rl32(pb);
if (chunk_size < 4 || chunk_size > INT_MAX - 4) { if (chunk_size < 4 || chunk_size > INT_MAX - 4) {
av_log(s, AV_LOG_ERROR, "invalid chunk size: %u\n", chunk_size); av_log(s, AV_LOG_ERROR, "invalid chunk size: %u\n", chunk_size);
...@@ -288,6 +307,10 @@ static int idcin_read_packet(AVFormatContext *s, ...@@ -288,6 +307,10 @@ static int idcin_read_packet(AVFormatContext *s,
ret= av_get_packet(pb, pkt, chunk_size); ret= av_get_packet(pb, pkt, chunk_size);
if (ret < 0) if (ret < 0)
return ret; return ret;
else if (ret != chunk_size) {
av_log(s, AV_LOG_ERROR, "incomplete packet\n");
return AVERROR(EIO);
}
if (command == 1) { if (command == 1) {
uint8_t *pal; uint8_t *pal;
......
...@@ -104,4 +104,3 @@ ...@@ -104,4 +104,3 @@
1, 78750, 78750, 1575, 6300, 0xe3bfa403 1, 78750, 78750, 1575, 6300, 0xe3bfa403
0, 51, 51, 1, 230400, 0x488de02d 0, 51, 51, 1, 230400, 0x488de02d
1, 80325, 80325, 1575, 6300, 0x2c5bd9c9 1, 80325, 80325, 1575, 6300, 0x2c5bd9c9
0, 52, 52, 1, 230400, 0x488de02d
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment