2020ImagingTgaRleDecode (Imaging im , ImagingCodecState state , UINT8 * buf , Py_ssize_t bytes ) {
2121 int n , depth ;
2222 UINT8 * ptr ;
23+ UINT8 extra_data = 0 ;
24+ int extra_bytes = 0 ;
2325
2426 ptr = buf ;
2527
@@ -42,15 +44,13 @@ ImagingTgaRleDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t
4244 return ptr - buf ;
4345 }
4446
47+ n = depth * ((ptr [0 ] & 0x7f ) + 1 );
4548 if (ptr [0 ] & 0x80 ) {
4649 /* Run (1 + pixelsize bytes) */
47-
4850 if (bytes < 1 + depth ) {
4951 break ;
5052 }
5153
52- n = depth * ((ptr [0 ] & 0x7f ) + 1 );
53-
5454 if (state -> x + n > state -> bytes ) {
5555 state -> errcode = IMAGING_CODEC_OVERRUN ;
5656 return -1 ;
@@ -67,18 +67,17 @@ ImagingTgaRleDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t
6767
6868 ptr += 1 + depth ;
6969 bytes -= 1 + depth ;
70-
7170 } else {
7271 /* Literal (1+n+1 bytes block) */
73- n = depth * (ptr [0 ] + 1 );
74-
7572 if (bytes < 1 + n ) {
7673 break ;
7774 }
7875
7976 if (state -> x + n > state -> bytes ) {
80- state -> errcode = IMAGING_CODEC_OVERRUN ;
81- return -1 ;
77+ extra_bytes = n ; /* full value */
78+ n = state -> bytes - state -> x ;
79+ extra_bytes -= n ;
80+ extra_data = ptr [1 ];
8281 }
8382
8483 memcpy (state -> buffer + state -> x , ptr + 1 , n );
@@ -87,24 +86,43 @@ ImagingTgaRleDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t
8786 bytes -= 1 + n ;
8887 }
8988
90- state -> x += n ;
89+ for (;;) {
90+ state -> x += n ;
9191
92- if (state -> x >= state -> bytes ) {
93- /* Got a full line, unpack it */
94- state -> shuffle (
95- (UINT8 * )im -> image [state -> y + state -> yoff ] +
96- state -> xoff * im -> pixelsize ,
97- state -> buffer ,
98- state -> xsize );
92+ if (state -> x >= state -> bytes ) {
93+ /* Got a full line, unpack it */
94+ state -> shuffle (
95+ (UINT8 * )im -> image [state -> y + state -> yoff ] +
96+ state -> xoff * im -> pixelsize ,
97+ state -> buffer ,
98+ state -> xsize );
9999
100- state -> x = 0 ;
100+ state -> x = 0 ;
101101
102- state -> y += state -> ystep ;
102+ state -> y += state -> ystep ;
103103
104- if (state -> y < 0 || state -> y >= state -> ysize ) {
105- /* End of file (errcode = 0) */
106- return -1 ;
104+ if (state -> y < 0 || state -> y >= state -> ysize ) {
105+ /* End of file (errcode = 0) */
106+ return -1 ;
107+ }
108+ }
109+
110+ if (extra_bytes == 0 ) {
111+ break ;
112+ }
113+
114+ if (state -> x > 0 ) {
115+ break ; // assert
116+ }
117+
118+ if (extra_bytes >= state -> bytes ) {
119+ n = state -> bytes ;
120+ } else {
121+ n = extra_bytes ;
107122 }
123+ memcpy (state -> buffer + state -> x , ptr , n );
124+ ptr += n ;
125+ extra_bytes -= n ;
108126 }
109127 }
110128
0 commit comments