@@ -112,12 +112,17 @@ static BOOL nsc_decode(NSC_CONTEXT* context)
112112 return TRUE;
113113}
114114
115- static BOOL nsc_rle_decode (BYTE * in , BYTE * out , UINT32 outSize , UINT32 originalSize )
115+ static BOOL nsc_rle_decode (const BYTE * in , size_t inSize , BYTE * out , UINT32 outSize ,
116+ UINT32 originalSize )
116117{
117118 UINT32 left = originalSize ;
118119
119120 while (left > 4 )
120121 {
122+ if (inSize < 1 )
123+ return FALSE;
124+ inSize -- ;
125+
121126 const BYTE value = * in ++ ;
122127 UINT32 len = 0 ;
123128
@@ -130,17 +135,26 @@ static BOOL nsc_rle_decode(BYTE* in, BYTE* out, UINT32 outSize, UINT32 originalS
130135 * out ++ = value ;
131136 left -- ;
132137 }
138+ else if (inSize < 1 )
139+ return FALSE;
133140 else if (value == * in )
134141 {
142+ inSize -- ;
135143 in ++ ;
136144
137- if (* in < 0xFF )
145+ if (inSize < 1 )
146+ return FALSE;
147+ else if (* in < 0xFF )
138148 {
149+ inSize -- ;
139150 len = (UINT32 )* in ++ ;
140151 len += 2 ;
141152 }
142153 else
143154 {
155+ if (inSize < 5 )
156+ return FALSE;
157+ inSize -= 5 ;
144158 in ++ ;
145159 len = ((UINT32 )(* in ++ ));
146160 len |= ((UINT32 )(* in ++ )) << 8U ;
@@ -170,6 +184,8 @@ static BOOL nsc_rle_decode(BYTE* in, BYTE* out, UINT32 outSize, UINT32 originalS
170184 if ((outSize < 4 ) || (left < 4 ))
171185 return FALSE;
172186
187+ if (inSize < 4 )
188+ return FALSE;
173189 memcpy (out , in , 4 );
174190 return TRUE;
175191}
@@ -179,14 +195,18 @@ static BOOL nsc_rle_decompress_data(NSC_CONTEXT* context)
179195 if (!context )
180196 return FALSE;
181197
182- BYTE * rle = context -> Planes ;
198+ const BYTE * rle = context -> Planes ;
199+ size_t rleSize = context -> PlanesSize ;
183200 WINPR_ASSERT (rle );
184201
185202 for (size_t i = 0 ; i < 4 ; i ++ )
186203 {
187204 const UINT32 originalSize = context -> OrgByteCount [i ];
188205 const UINT32 planeSize = context -> PlaneByteCount [i ];
189206
207+ if (rleSize < planeSize )
208+ return FALSE;
209+
190210 if (planeSize == 0 )
191211 {
192212 if (context -> priv -> PlaneBuffersLength < originalSize )
@@ -196,7 +216,7 @@ static BOOL nsc_rle_decompress_data(NSC_CONTEXT* context)
196216 }
197217 else if (planeSize < originalSize )
198218 {
199- if (!nsc_rle_decode (rle , context -> priv -> PlaneBuffers [i ],
219+ if (!nsc_rle_decode (rle , rleSize , context -> priv -> PlaneBuffers [i ],
200220 context -> priv -> PlaneBuffersLength , originalSize ))
201221 return FALSE;
202222 }
@@ -205,6 +225,9 @@ static BOOL nsc_rle_decompress_data(NSC_CONTEXT* context)
205225 if (context -> priv -> PlaneBuffersLength < originalSize )
206226 return FALSE;
207227
228+ if (rleSize < originalSize )
229+ return FALSE;
230+
208231 CopyMemory (context -> priv -> PlaneBuffers [i ], rle , originalSize );
209232 }
210233
@@ -232,6 +255,7 @@ static BOOL nsc_stream_initialize(NSC_CONTEXT* context, wStream* s)
232255 Stream_Read_UINT8 (s , context -> ChromaSubsamplingLevel ); /* ChromaSubsamplingLevel (1 byte) */
233256 Stream_Seek (s , 2 ); /* Reserved (2 bytes) */
234257 context -> Planes = Stream_Pointer (s );
258+ context -> PlanesSize = total ;
235259 return Stream_CheckAndLogRequiredLengthWLog (context -> priv -> log , s , total );
236260}
237261
0 commit comments