History

lavf: sanity check size in av_get/append_packet().

To avoid allocating ridiculous amounts of memory for corrupted files, read the input in chunks limited to filesize or an arbitrary large amount when that is not known (chosen to be 50M).

Anton Khirnov committed 13 years ago

Commit aa3c7791 parent ca6c3f21 file · +49 −19Browse files

Unified · Split

libavformat/utils.c+49−19
@@ -214,38 +214,68 @@ AVInputFormat *av_find_input_format(const char *short_name) · 213 unmodified lines
214 return NULL;214 return NULL;
215}215}
216 216
217/* an arbitrarily chosen "sane" max packet size -- 50M */
218#define SANE_CHUNK_SIZE (50000000)
217 219
218int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)220/*
221 * Read the data in sane-sized chunks and append to pkt.
222 * Return the number of bytes read or an error.
223 */
224static int append_packet_chunked(AVIOContext *s, AVPacket *pkt, int size)
219{225{
220 int ret= av_new_packet(pkt, size);226 int64_t chunk_size = size;
227 int orig_pos = pkt->pos; // av_grow_packet might reset pos
228 int orig_size = pkt->size;
229 int ret = 0;
221 230
222 if(ret<0)231 do {
223 return ret;232 int prev_size = pkt->size;
233 int read_size;
234
235 /*
236 * When the caller requests a lot of data, limit it to the amount left
237 * in file or SANE_CHUNK_SIZE when it is not known
238 */
239 if (size > SANE_CHUNK_SIZE) {
240 int64_t filesize = avio_size(s) - avio_tell(s);
241 chunk_size = FFMAX(filesize, SANE_CHUNK_SIZE);
242 }
243 read_size = FFMIN(size, chunk_size);
244
245 ret = av_grow_packet(pkt, read_size);
246 if (ret < 0)
247 break;
248
249 ret = avio_read(s, pkt->data + prev_size, read_size);
250 if (ret != read_size) {
251 av_shrink_packet(pkt, prev_size + FFMAX(ret, 0));
252 break;
253 }
224 254
225 pkt->pos= avio_tell(s);255 size -= read_size;
256 } while (size > 0);
226 257
227 ret= avio_read(s, pkt->data, size);258 pkt->pos = orig_pos;
228 if(ret<=0)259 if (!pkt->size)
229 av_free_packet(pkt);260 av_free_packet(pkt);
230 else261 return pkt->size > orig_size ? pkt->size - orig_size : ret;
231 av_shrink_packet(pkt, ret);262}
232 263
233 return ret;264int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
265{
266 av_init_packet(pkt);
267 pkt->data = NULL;
268 pkt->size = 0;
269 pkt->pos = avio_tell(s);
270
271 return append_packet_chunked(s, pkt, size);
234}272}
235 273
236int av_append_packet(AVIOContext *s, AVPacket *pkt, int size)274int av_append_packet(AVIOContext *s, AVPacket *pkt, int size)
237{275{
238 int ret;
239 int old_size;
240 if (!pkt->size)276 if (!pkt->size)
241 return av_get_packet(s, pkt, size);277 return av_get_packet(s, pkt, size);
242 old_size = pkt->size;278 return append_packet_chunked(s, pkt, size);
243 ret = av_grow_packet(pkt, size);
244 if (ret < 0)
245 return ret;
246 ret = avio_read(s, pkt->data + old_size, size);
247 av_shrink_packet(pkt, old_size + FFMAX(ret, 0));
248 return ret;
249}279}
250 280
251 281

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t