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)