mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-10-31 07:57:27 +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) */ | ||||
|                     printf("%d", ct_bytes); | ||||
|                     return -1; | ||||
|                 } | ||||
|             } | ||||
|              | ||||
|             if (extra_bytes == 0) { | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
| 	    if (++state->y >= state->ysize) { | ||||
| 		/* End of file (errcode = 0) */ | ||||
| 		return -1; | ||||
| 	    } | ||||
| 	} | ||||
|             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