Check for out of bound reads in vmd_decode() of vmd video decoder.
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
		
				
					committed by
					
						
						Michael Niedermayer
					
				
			
			
				
	
			
			
			
						parent
						
							3b26daedd8
						
					
				
				
					commit
					e07377e736
				
			@@ -203,6 +203,7 @@ static void vmd_decode(VmdVideoContext *s)
 | 
				
			|||||||
    const unsigned char *p_end = s->buf + s->size;
 | 
					    const unsigned char *p_end = s->buf + s->size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const unsigned char *pb;
 | 
					    const unsigned char *pb;
 | 
				
			||||||
 | 
					    const unsigned char *pb_end;
 | 
				
			||||||
    unsigned char meth;
 | 
					    unsigned char meth;
 | 
				
			||||||
    unsigned char *dp;   /* pointer to current frame */
 | 
					    unsigned char *dp;   /* pointer to current frame */
 | 
				
			||||||
    unsigned char *pp;   /* pointer to previous frame */
 | 
					    unsigned char *pp;   /* pointer to previous frame */
 | 
				
			||||||
@@ -248,6 +249,8 @@ static void vmd_decode(VmdVideoContext *s)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /* check if there is a new palette */
 | 
					    /* check if there is a new palette */
 | 
				
			||||||
    if (s->buf[15] & 0x02) {
 | 
					    if (s->buf[15] & 0x02) {
 | 
				
			||||||
 | 
					        if (p_end - p < 2 + 3 * PALETTE_COUNT)
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
        p += 2;
 | 
					        p += 2;
 | 
				
			||||||
        palette32 = (unsigned int *)s->palette;
 | 
					        palette32 = (unsigned int *)s->palette;
 | 
				
			||||||
        for (i = 0; i < PALETTE_COUNT; i++) {
 | 
					        for (i = 0; i < PALETTE_COUNT; i++) {
 | 
				
			||||||
@@ -256,16 +259,17 @@ static void vmd_decode(VmdVideoContext *s)
 | 
				
			|||||||
            b = *p++ * 4;
 | 
					            b = *p++ * 4;
 | 
				
			||||||
            palette32[i] = (r << 16) | (g << 8) | (b);
 | 
					            palette32[i] = (r << 16) | (g << 8) | (b);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        s->size -= (256 * 3 + 2);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (s->size >= 0) {
 | 
					    if (p < p_end) {
 | 
				
			||||||
        /* originally UnpackFrame in VAG's code */
 | 
					        /* originally UnpackFrame in VAG's code */
 | 
				
			||||||
        pb = p;
 | 
					        pb = p;
 | 
				
			||||||
 | 
					        pb_end = p_end;
 | 
				
			||||||
        meth = *pb++;
 | 
					        meth = *pb++;
 | 
				
			||||||
        if (meth & 0x80) {
 | 
					        if (meth & 0x80) {
 | 
				
			||||||
            lz_unpack(pb, p_end - pb, s->unpack_buffer, s->unpack_buffer_size);
 | 
					            lz_unpack(pb, p_end - pb, s->unpack_buffer, s->unpack_buffer_size);
 | 
				
			||||||
            meth &= 0x7F;
 | 
					            meth &= 0x7F;
 | 
				
			||||||
            pb = s->unpack_buffer;
 | 
					            pb = s->unpack_buffer;
 | 
				
			||||||
 | 
					            pb_end = s->unpack_buffer + s->unpack_buffer_size;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
 | 
					        dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
 | 
				
			||||||
@@ -275,10 +279,12 @@ static void vmd_decode(VmdVideoContext *s)
 | 
				
			|||||||
            for (i = 0; i < frame_height; i++) {
 | 
					            for (i = 0; i < frame_height; i++) {
 | 
				
			||||||
                ofs = 0;
 | 
					                ofs = 0;
 | 
				
			||||||
                do {
 | 
					                do {
 | 
				
			||||||
 | 
					                    if (pb_end - pb < 1)
 | 
				
			||||||
 | 
					                        return;
 | 
				
			||||||
                    len = *pb++;
 | 
					                    len = *pb++;
 | 
				
			||||||
                    if (len & 0x80) {
 | 
					                    if (len & 0x80) {
 | 
				
			||||||
                        len = (len & 0x7F) + 1;
 | 
					                        len = (len & 0x7F) + 1;
 | 
				
			||||||
                        if (ofs + len > frame_width)
 | 
					                        if (ofs + len > frame_width || pb_end - pb < len)
 | 
				
			||||||
                            return;
 | 
					                            return;
 | 
				
			||||||
                        memcpy(&dp[ofs], pb, len);
 | 
					                        memcpy(&dp[ofs], pb, len);
 | 
				
			||||||
                        pb += len;
 | 
					                        pb += len;
 | 
				
			||||||
@@ -303,6 +309,8 @@ static void vmd_decode(VmdVideoContext *s)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        case 2:
 | 
					        case 2:
 | 
				
			||||||
            for (i = 0; i < frame_height; i++) {
 | 
					            for (i = 0; i < frame_height; i++) {
 | 
				
			||||||
 | 
					                if (pb_end -pb < frame_width)
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
                memcpy(dp, pb, frame_width);
 | 
					                memcpy(dp, pb, frame_width);
 | 
				
			||||||
                pb += frame_width;
 | 
					                pb += frame_width;
 | 
				
			||||||
                dp += s->frame.linesize[0];
 | 
					                dp += s->frame.linesize[0];
 | 
				
			||||||
@@ -314,13 +322,20 @@ static void vmd_decode(VmdVideoContext *s)
 | 
				
			|||||||
            for (i = 0; i < frame_height; i++) {
 | 
					            for (i = 0; i < frame_height; i++) {
 | 
				
			||||||
                ofs = 0;
 | 
					                ofs = 0;
 | 
				
			||||||
                do {
 | 
					                do {
 | 
				
			||||||
 | 
					                    if (pb_end - pb < 1)
 | 
				
			||||||
 | 
					                        return;
 | 
				
			||||||
                    len = *pb++;
 | 
					                    len = *pb++;
 | 
				
			||||||
                    if (len & 0x80) {
 | 
					                    if (len & 0x80) {
 | 
				
			||||||
                        len = (len & 0x7F) + 1;
 | 
					                        len = (len & 0x7F) + 1;
 | 
				
			||||||
 | 
					                        if (pb_end - pb < 1)
 | 
				
			||||||
 | 
					                            return;
 | 
				
			||||||
                        if (*pb++ == 0xFF)
 | 
					                        if (*pb++ == 0xFF)
 | 
				
			||||||
                            len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs);
 | 
					                            len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs);
 | 
				
			||||||
                        else
 | 
					                        else {
 | 
				
			||||||
 | 
					                        if (pb_end - pb < len)
 | 
				
			||||||
 | 
					                            return;
 | 
				
			||||||
                            memcpy(&dp[ofs], pb, len);
 | 
					                            memcpy(&dp[ofs], pb, len);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
                        pb += len;
 | 
					                        pb += len;
 | 
				
			||||||
                        ofs += len;
 | 
					                        ofs += len;
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user