Mercurial > libavcodec.hg
comparison flicvideo.c @ 2825:faa53103dde0 libavcodec
tinfoil patch: make sure that pixel pointer does not go out of bounds
author | melanson |
---|---|
date | Sat, 13 Aug 2005 16:59:01 +0000 |
parents | 18b8b2dcc037 |
children | f7114e03d8dd |
comparison
equal
deleted
inserted
replaced
2824:dae9760d1f12 | 2825:faa53103dde0 |
---|---|
49 #define FLI_BLACK 13 | 49 #define FLI_BLACK 13 |
50 #define FLI_BRUN 15 | 50 #define FLI_BRUN 15 |
51 #define FLI_COPY 16 | 51 #define FLI_COPY 16 |
52 #define FLI_MINI 18 | 52 #define FLI_MINI 18 |
53 | 53 |
54 #define CHECK_PIXEL_PTR(n) \ | |
55 if (pixel_ptr + n > pixel_limit) { \ | |
56 av_log (s->avctx, AV_LOG_INFO, "Problem: pixel_ptr >= pixel_limit (%d >= %d)\n", \ | |
57 pixel_ptr + n, pixel_limit); \ | |
58 return -1; \ | |
59 } \ | |
60 | |
54 typedef struct FlicDecodeContext { | 61 typedef struct FlicDecodeContext { |
55 AVCodecContext *avctx; | 62 AVCodecContext *avctx; |
56 AVFrame frame; | 63 AVFrame frame; |
57 | 64 |
58 unsigned int palette[256]; | 65 unsigned int palette[256]; |
118 int y_ptr; | 125 int y_ptr; |
119 signed char byte_run; | 126 signed char byte_run; |
120 int pixel_skip; | 127 int pixel_skip; |
121 int pixel_countdown; | 128 int pixel_countdown; |
122 unsigned char *pixels; | 129 unsigned char *pixels; |
130 int pixel_limit; | |
123 | 131 |
124 s->frame.reference = 1; | 132 s->frame.reference = 1; |
125 s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; | 133 s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; |
126 if (avctx->reget_buffer(avctx, &s->frame) < 0) { | 134 if (avctx->reget_buffer(avctx, &s->frame) < 0) { |
127 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); | 135 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); |
128 return -1; | 136 return -1; |
129 } | 137 } |
130 | 138 |
131 pixels = s->frame.data[0]; | 139 pixels = s->frame.data[0]; |
140 pixel_limit = s->avctx->height * s->frame.linesize[0]; | |
132 | 141 |
133 frame_size = LE_32(&buf[stream_ptr]); | 142 frame_size = LE_32(&buf[stream_ptr]); |
134 stream_ptr += 6; /* skip the magic number */ | 143 stream_ptr += 6; /* skip the magic number */ |
135 num_chunks = LE_16(&buf[stream_ptr]); | 144 num_chunks = LE_16(&buf[stream_ptr]); |
136 stream_ptr += 10; /* skip padding */ | 145 stream_ptr += 10; /* skip padding */ |
216 byte_run = buf[stream_ptr++]; | 225 byte_run = buf[stream_ptr++]; |
217 if (byte_run < 0) { | 226 if (byte_run < 0) { |
218 byte_run = -byte_run; | 227 byte_run = -byte_run; |
219 palette_idx1 = buf[stream_ptr++]; | 228 palette_idx1 = buf[stream_ptr++]; |
220 palette_idx2 = buf[stream_ptr++]; | 229 palette_idx2 = buf[stream_ptr++]; |
230 CHECK_PIXEL_PTR(byte_run); | |
221 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) { | 231 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) { |
222 pixels[pixel_ptr++] = palette_idx1; | 232 pixels[pixel_ptr++] = palette_idx1; |
223 pixels[pixel_ptr++] = palette_idx2; | 233 pixels[pixel_ptr++] = palette_idx2; |
224 } | 234 } |
225 } else { | 235 } else { |
236 CHECK_PIXEL_PTR(byte_run * 2); | |
226 for (j = 0; j < byte_run * 2; j++, pixel_countdown--) { | 237 for (j = 0; j < byte_run * 2; j++, pixel_countdown--) { |
227 palette_idx1 = buf[stream_ptr++]; | 238 palette_idx1 = buf[stream_ptr++]; |
228 pixels[pixel_ptr++] = palette_idx1; | 239 pixels[pixel_ptr++] = palette_idx1; |
229 } | 240 } |
230 } | 241 } |
254 pixel_skip = buf[stream_ptr++]; | 265 pixel_skip = buf[stream_ptr++]; |
255 pixel_ptr += pixel_skip; | 266 pixel_ptr += pixel_skip; |
256 pixel_countdown -= pixel_skip; | 267 pixel_countdown -= pixel_skip; |
257 byte_run = buf[stream_ptr++]; | 268 byte_run = buf[stream_ptr++]; |
258 if (byte_run > 0) { | 269 if (byte_run > 0) { |
270 CHECK_PIXEL_PTR(byte_run); | |
259 for (j = 0; j < byte_run; j++, pixel_countdown--) { | 271 for (j = 0; j < byte_run; j++, pixel_countdown--) { |
260 palette_idx1 = buf[stream_ptr++]; | 272 palette_idx1 = buf[stream_ptr++]; |
261 pixels[pixel_ptr++] = palette_idx1; | 273 pixels[pixel_ptr++] = palette_idx1; |
262 } | 274 } |
263 } else { | 275 } else { |
264 byte_run = -byte_run; | 276 byte_run = -byte_run; |
265 palette_idx1 = buf[stream_ptr++]; | 277 palette_idx1 = buf[stream_ptr++]; |
278 CHECK_PIXEL_PTR(byte_run); | |
266 for (j = 0; j < byte_run; j++, pixel_countdown--) { | 279 for (j = 0; j < byte_run; j++, pixel_countdown--) { |
267 pixels[pixel_ptr++] = palette_idx1; | 280 pixels[pixel_ptr++] = palette_idx1; |
268 } | 281 } |
269 } | 282 } |
270 } | 283 } |
293 pixel_countdown = s->avctx->width; | 306 pixel_countdown = s->avctx->width; |
294 while (pixel_countdown > 0) { | 307 while (pixel_countdown > 0) { |
295 byte_run = buf[stream_ptr++]; | 308 byte_run = buf[stream_ptr++]; |
296 if (byte_run > 0) { | 309 if (byte_run > 0) { |
297 palette_idx1 = buf[stream_ptr++]; | 310 palette_idx1 = buf[stream_ptr++]; |
311 CHECK_PIXEL_PTR(byte_run); | |
298 for (j = 0; j < byte_run; j++) { | 312 for (j = 0; j < byte_run; j++) { |
299 pixels[pixel_ptr++] = palette_idx1; | 313 pixels[pixel_ptr++] = palette_idx1; |
300 pixel_countdown--; | 314 pixel_countdown--; |
301 if (pixel_countdown < 0) | 315 if (pixel_countdown < 0) |
302 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n", | 316 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n", |
303 pixel_countdown); | 317 pixel_countdown); |
304 } | 318 } |
305 } else { /* copy bytes if byte_run < 0 */ | 319 } else { /* copy bytes if byte_run < 0 */ |
306 byte_run = -byte_run; | 320 byte_run = -byte_run; |
321 CHECK_PIXEL_PTR(byte_run); | |
307 for (j = 0; j < byte_run; j++) { | 322 for (j = 0; j < byte_run; j++) { |
308 palette_idx1 = buf[stream_ptr++]; | 323 palette_idx1 = buf[stream_ptr++]; |
309 pixels[pixel_ptr++] = palette_idx1; | 324 pixels[pixel_ptr++] = palette_idx1; |
310 pixel_countdown--; | 325 pixel_countdown--; |
311 if (pixel_countdown < 0) | 326 if (pixel_countdown < 0) |