Avoids trying to read a packet with 0 or negative size.
Avoids a potential infinite loop due to seeking backwards.
Partially based on a patch by Michael Niedermayer.
(cherry picked from commit e70c5b034c4787377e82cab2d5565486baec0c2a)
Signed-off-by: Luca Barbato <lu_zero@gentoo.org>
... | ... |
@@ -91,6 +91,10 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) |
91 | 91 |
tag = get_swf_tag(pb, &len); |
92 | 92 |
if (tag < 0) |
93 | 93 |
return AVERROR(EIO); |
94 |
+ if (len < 0) { |
|
95 |
+ av_log(s, AV_LOG_ERROR, "invalid tag length: %d\n", len); |
|
96 |
+ return AVERROR_INVALIDDATA; |
|
97 |
+ } |
|
94 | 98 |
if (tag == TAG_VIDEOSTREAM) { |
95 | 99 |
int ch_id = avio_rl16(pb); |
96 | 100 |
len -= 2; |
... | ... |
@@ -150,7 +154,10 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) |
150 | 150 |
st = s->streams[i]; |
151 | 151 |
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->id == ch_id) { |
152 | 152 |
frame = avio_rl16(pb); |
153 |
- if ((res = av_get_packet(pb, pkt, len-2)) < 0) |
|
153 |
+ len -= 2; |
|
154 |
+ if (len <= 0) |
|
155 |
+ goto skip; |
|
156 |
+ if ((res = av_get_packet(pb, pkt, len)) < 0) |
|
154 | 157 |
return res; |
155 | 158 |
pkt->pos = pos; |
156 | 159 |
pkt->pts = frame; |
... | ... |
@@ -164,9 +171,14 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) |
164 | 164 |
if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->id == -1) { |
165 | 165 |
if (st->codec->codec_id == CODEC_ID_MP3) { |
166 | 166 |
avio_skip(pb, 4); |
167 |
- if ((res = av_get_packet(pb, pkt, len-4)) < 0) |
|
167 |
+ len -= 4; |
|
168 |
+ if (len <= 0) |
|
169 |
+ goto skip; |
|
170 |
+ if ((res = av_get_packet(pb, pkt, len)) < 0) |
|
168 | 171 |
return res; |
169 | 172 |
} else { // ADPCM, PCM |
173 |
+ if (len <= 0) |
|
174 |
+ goto skip; |
|
170 | 175 |
if ((res = av_get_packet(pb, pkt, len)) < 0) |
171 | 176 |
return res; |
172 | 177 |
} |
... | ... |
@@ -193,7 +205,10 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) |
193 | 193 |
st = vst; |
194 | 194 |
} |
195 | 195 |
avio_rl16(pb); /* BITMAP_ID */ |
196 |
- if ((res = av_new_packet(pkt, len-2)) < 0) |
|
196 |
+ len -= 2; |
|
197 |
+ if (len < 4) |
|
198 |
+ goto skip; |
|
199 |
+ if ((res = av_new_packet(pkt, len)) < 0) |
|
197 | 200 |
return res; |
198 | 201 |
avio_read(pb, pkt->data, 4); |
199 | 202 |
if (AV_RB32(pkt->data) == 0xffd8ffd9 || |
... | ... |
@@ -210,6 +225,7 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) |
210 | 210 |
return pkt->size; |
211 | 211 |
} |
212 | 212 |
skip: |
213 |
+ len = FFMAX(0, len); |
|
213 | 214 |
avio_skip(pb, len); |
214 | 215 |
} |
215 | 216 |
} |