mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-11-04 01:47:47 +03:00 
			
		
		
		
	Fixed literal expansion, allowed run length > line length
This commit is contained in:
		
							parent
							
								
									17d38d0905
								
							
						
					
					
						commit
						5df2851f85
					
				| 
						 | 
				
			
			@ -7,7 +7,7 @@
 | 
			
		|||
 * decoder for SUN RLE data.
 | 
			
		||||
 *
 | 
			
		||||
 * history:
 | 
			
		||||
 *	97-01-04 fl	Created
 | 
			
		||||
 *      97-01-04 fl     Created
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) Fredrik Lundh 1997.
 | 
			
		||||
 * Copyright (c) Secret Labs AB 1997.
 | 
			
		||||
| 
						 | 
				
			
			@ -24,88 +24,106 @@ ImagingSunRleDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
 | 
			
		|||
{
 | 
			
		||||
    int n;
 | 
			
		||||
    UINT8* ptr;
 | 
			
		||||
    UINT8 extra_data = 0;
 | 
			
		||||
    UINT8 extra_bytes = 0;
 | 
			
		||||
    int ct_bytes = 0;
 | 
			
		||||
 | 
			
		||||
    ptr = buf;
 | 
			
		||||
 | 
			
		||||
    for (;;) {
 | 
			
		||||
 | 
			
		||||
	if (bytes < 1)
 | 
			
		||||
	    return ptr - buf;
 | 
			
		||||
        if (bytes < 1)
 | 
			
		||||
            return ptr - buf;
 | 
			
		||||
 | 
			
		||||
	if (ptr[0] == 0x80) {
 | 
			
		||||
        if (ptr[0] == 0x80) {
 | 
			
		||||
 | 
			
		||||
	    if (bytes < 2)
 | 
			
		||||
		break;
 | 
			
		||||
            if (bytes < 2)
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
	    n = ptr[1];
 | 
			
		||||
            n = ptr[1];
 | 
			
		||||
 | 
			
		||||
	    if (n == 0) {
 | 
			
		||||
 | 
			
		||||
		/* Literal 0x80 (2 bytes) */
 | 
			
		||||
		n = 1;
 | 
			
		||||
            if (n == 0) {
 | 
			
		||||
 | 
			
		||||
		state->buffer[state->x] = 0x80;
 | 
			
		||||
                /* Literal 0x80 (2 bytes) */
 | 
			
		||||
                n = 1;
 | 
			
		||||
                ct_bytes += n;        
 | 
			
		||||
 | 
			
		||||
		ptr += 2;
 | 
			
		||||
		bytes -= 2;
 | 
			
		||||
                state->buffer[state->x] = 0x80;
 | 
			
		||||
 | 
			
		||||
	    } else {
 | 
			
		||||
                ptr += 2;
 | 
			
		||||
                bytes -= 2;
 | 
			
		||||
 | 
			
		||||
		/* Run (3 bytes) */
 | 
			
		||||
		if (bytes < 3)
 | 
			
		||||
		    break;
 | 
			
		||||
            } else {
 | 
			
		||||
 | 
			
		||||
		if (state->x + n > state->bytes) {
 | 
			
		||||
		    /* FIXME: is this correct? */
 | 
			
		||||
		    state->errcode = IMAGING_CODEC_OVERRUN;
 | 
			
		||||
		    return -1;
 | 
			
		||||
		}
 | 
			
		||||
                /* Run (3 bytes) */
 | 
			
		||||
                if (bytes < 3)
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
		memset(state->buffer + state->x, ptr[2], n);
 | 
			
		||||
                ct_bytes += n;        
 | 
			
		||||
 | 
			
		||||
		ptr += 3;
 | 
			
		||||
		bytes -= 3;
 | 
			
		||||
                if (state->x + n > state->bytes) {
 | 
			
		||||
                    extra_bytes = n;  /* full value */
 | 
			
		||||
                    n = state->bytes - state->x;
 | 
			
		||||
                    extra_bytes -= n;
 | 
			
		||||
                    extra_data = ptr[2];
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
	    }
 | 
			
		||||
                memset(state->buffer + state->x, ptr[2], n);
 | 
			
		||||
 | 
			
		||||
	} else {
 | 
			
		||||
                ptr += 3;
 | 
			
		||||
                bytes -= 3;
 | 
			
		||||
 | 
			
		||||
	    /* Literal (1+n bytes block) */
 | 
			
		||||
	    n = ptr[0];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
	    if (bytes < 1 + n)
 | 
			
		||||
		break;
 | 
			
		||||
        } else {
 | 
			
		||||
 | 
			
		||||
	    if (state->x + n > state->bytes) {
 | 
			
		||||
		/* FIXME: is this correct? */
 | 
			
		||||
		state->errcode = IMAGING_CODEC_OVERRUN;
 | 
			
		||||
		return -1;
 | 
			
		||||
	    }
 | 
			
		||||
            /* Literal byte */ 
 | 
			
		||||
            n = 1; 
 | 
			
		||||
            ct_bytes += n;        
 | 
			
		||||
 | 
			
		||||
	    memcpy(state->buffer + state->x, ptr + 1, n);
 | 
			
		||||
            state->buffer[state->x] = ptr[0];
 | 
			
		||||
 | 
			
		||||
	    ptr += 1 + n;
 | 
			
		||||
	    bytes -= 1 + n;
 | 
			
		||||
            ptr += 1;
 | 
			
		||||
            bytes -= 1;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
	state->x += n;
 | 
			
		||||
        for (;;) {
 | 
			
		||||
            state->x += n;
 | 
			
		||||
        
 | 
			
		||||
	if (state->x >= state->bytes) {
 | 
			
		||||
            if (state->x >= state->bytes) {
 | 
			
		||||
 | 
			
		||||
	    /* Got a full line, unpack it */
 | 
			
		||||
	    state->shuffle((UINT8*) im->image[state->y + state->yoff] +
 | 
			
		||||
			   state->xoff * im->pixelsize, state->buffer,
 | 
			
		||||
			   state->xsize);
 | 
			
		||||
                /* Got a full line, unpack it */
 | 
			
		||||
                state->shuffle((UINT8*) im->image[state->y + state->yoff] +
 | 
			
		||||
                               state->xoff * im->pixelsize, state->buffer,
 | 
			
		||||
                               state->xsize);
 | 
			
		||||
 | 
			
		||||
	    state->x = 0;
 | 
			
		||||
                state->x = 0;
 | 
			
		||||
 | 
			
		||||
	    if (++state->y >= state->ysize) {
 | 
			
		||||
		/* End of file (errcode = 0) */
 | 
			
		||||
		return -1;
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
                if (++state->y >= state->ysize) {
 | 
			
		||||
                    /* End of file (errcode = 0) */
 | 
			
		||||
                    printf("%d", ct_bytes);
 | 
			
		||||
                    return -1;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            if (extra_bytes == 0) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (state->x > 0) {
 | 
			
		||||
                break; // assert
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (extra_bytes >= state->bytes) {
 | 
			
		||||
                n = state->bytes;
 | 
			
		||||
            } else {
 | 
			
		||||
                n = extra_bytes;
 | 
			
		||||
            }
 | 
			
		||||
            memset(state->buffer + state->x, extra_data, n);
 | 
			
		||||
            extra_bytes -= n;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ptr - buf;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user