summaryrefslogtreecommitdiff
path: root/libavcodec/qpeg.c
diff options
context:
space:
mode:
authorKostya Shishkov <kostya.shishkov@gmail.com>2005-08-13 09:12:09 +0000
committerMichael Niedermayer <michaelni@gmx.at>2005-08-13 09:12:09 +0000
commitf63166f8dff65942c633adf32da9847ee1da3a47 (patch)
tree9f13f55bbdec05ab012f4ce644028a3a7d62c424 /libavcodec/qpeg.c
parent9c633e9a6f6630d7a030256602da4acfa9773e04 (diff)
security fixes
* check for writing to lines -1,-2,... * check for motion compensation (copying from and to valid place) patch by (Kostya: kostya shishkov, gmail com) Originally committed as revision 4508 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/qpeg.c')
-rw-r--r--libavcodec/qpeg.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/libavcodec/qpeg.c b/libavcodec/qpeg.c
index a2d7e4acc0..e4a78bcb3f 100644
--- a/libavcodec/qpeg.c
+++ b/libavcodec/qpeg.c
@@ -40,11 +40,13 @@ static void qpeg_decode_intra(uint8_t *src, uint8_t *dst, int size,
int c0, c1;
int run, copy;
int filled = 0;
+ int rows_to_go;
+ rows_to_go = height;
height--;
dst = dst + height * stride;
- while(size > 0) {
+ while((size > 0) && (rows_to_go > 0)) {
code = *src++;
size--;
run = copy = 0;
@@ -85,17 +87,23 @@ static void qpeg_decode_intra(uint8_t *src, uint8_t *dst, int size,
if (filled >= width) {
filled = 0;
dst -= stride;
+ rows_to_go--;
+ if(rows_to_go <= 0)
+ break;
}
}
} else {
+ size -= copy;
for(i = 0; i < copy; i++) {
dst[filled++] = *src++;
if (filled >= width) {
filled = 0;
dst -= stride;
+ rows_to_go--;
+ if(rows_to_go <= 0)
+ break;
}
}
- size -= copy;
}
}
}
@@ -113,17 +121,19 @@ static void qpeg_decode_inter(uint8_t *src, uint8_t *dst, int size,
int i, j;
int code;
int filled = 0;
+ int orig_height;
uint8_t *blkdata;
/* copy prev frame */
for(i = 0; i < height; i++)
memcpy(refdata + (i * width), dst + (i * stride), width);
+ orig_height = height;
blkdata = src - 0x86;
height--;
dst = dst + height * stride;
- while(size > 0) {
+ while((size > 0) && (height >= 0)) {
code = *src++;
size--;
@@ -155,11 +165,19 @@ static void qpeg_decode_inter(uint8_t *src, uint8_t *dst, int size,
val -= 16;
me_y = val;
- /* do motion compensation */
- me_plane = refdata + (filled + me_x) + (height - me_y) * width;
- for(j = 0; j < me_h; j++) {
- for(i = 0; i < me_w; i++)
- dst[filled + i - (j * stride)] = me_plane[i - (j * width)];
+ /* check motion vector */
+ if ((me_x + filled < 0) || (me_x + me_w + filled > width) ||
+ (height - me_y - me_h < 0) || (height - me_y > orig_height) ||
+ (filled + me_w > width) || (height - me_h < 0))
+ av_log(NULL, AV_LOG_ERROR, "Bogus motion vector (%i,%i), block size %ix%i at %i,%i\n",
+ me_x, me_y, me_w, me_h, filled, height);
+ else {
+ /* do motion compensation */
+ me_plane = refdata + (filled + me_x) + (height - me_y) * width;
+ for(j = 0; j < me_h; j++) {
+ for(i = 0; i < me_w; i++)
+ dst[filled + i - (j * stride)] = me_plane[i - (j * width)];
+ }
}
}
code = *src++;
@@ -212,6 +230,8 @@ static void qpeg_decode_inter(uint8_t *src, uint8_t *dst, int size,
filled -= width;
dst -= stride;
height--;
+ if(height < 0)
+ break;
}
} else {
/* zero code treated as one-pixel skip */