@@ -246,33 +246,35 @@ ERR BufferCalcIFDSize(const U8* pbdata, size_t cbdata, U32 ofsifd, U8 endian, U3
246246}
247247
248248
249- ERR StreamCalcIFDSize (struct WMPStream * pWS , U32 uIFDOfs , U32 * pcbifd )
249+ static ERR StreamCalcIFDSizePrivate (struct WMPStream * pWS , U32 uIFDOfs , U32 * pcbifd , U32 rcnt )
250250{
251251 ERR err = WMP_errSuccess ;
252252 size_t offCurPos = 0 ;
253253 Bool GetPosOK = FALSE;
254- U16 cDir ;
255- U32 i ;
256- U32 ofsdir ;
257- U32 cbifd = 0 ;
254+ U16 cDir = 0 ;
258255 U32 cbEXIFIFD = 0 ;
259256 U32 cbGPSInfoIFD = 0 ;
260257 U32 cbInteroperabilityIFD = 0 ;
261258
259+ // sanity check: avoid infinite recursion
260+ if (rcnt > 10 ) {
261+ Call (WMP_errFail );
262+ }
263+
262264 * pcbifd = 0 ;
263265 Call (pWS -> GetPos (pWS , & offCurPos ));
264266 GetPosOK = TRUE;
265267
266268 Call (GetUShort (pWS , uIFDOfs , & cDir ));
267- cbifd = sizeof (U16 ) + cDir * SizeofIFDEntry + sizeof (U32 );
268- ofsdir = uIFDOfs + sizeof (U16 );
269- for ( i = 0 ; i < cDir ; i ++ )
269+ U32 cbifd = sizeof (U16 ) + cDir * SizeofIFDEntry + sizeof (U32 );
270+ U32 ofsdir = uIFDOfs + sizeof (U16 );
271+ for (U16 i = 0 ; i < cDir ; i ++ )
270272 {
271- U16 tag ;
272- U16 type ;
273- U32 count ;
274- U32 value ;
275- U32 datasize ;
273+ U16 tag = 0 ;
274+ U16 type = 0 ;
275+ U32 count = 0 ;
276+ U32 value = 0 ;
277+ U32 datasize = 0 ;
276278
277279 Call (GetUShort (pWS , ofsdir , & tag ));
278280 Call (GetUShort (pWS , ofsdir + sizeof (U16 ), & type ));
@@ -281,39 +283,48 @@ ERR StreamCalcIFDSize(struct WMPStream* pWS, U32 uIFDOfs, U32 *pcbifd)
281283 FailIf (type == 0 || type >= sizeof (IFDEntryTypeSizes ) / sizeof (IFDEntryTypeSizes [0 ]), WMP_errUnsupportedFormat );
282284 if ( tag == WMP_tagEXIFMetadata )
283285 {
284- Call (StreamCalcIFDSize (pWS , value , & cbEXIFIFD ));
286+ Call (StreamCalcIFDSizePrivate (pWS , value , & cbEXIFIFD , rcnt + 1 ));
285287 }
286288 else if ( tag == WMP_tagGPSInfoMetadata )
287289 {
288- Call (StreamCalcIFDSize (pWS , value , & cbGPSInfoIFD ));
290+ Call (StreamCalcIFDSizePrivate (pWS , value , & cbGPSInfoIFD , rcnt + 1 ));
289291 }
290292 else if ( tag == WMP_tagInteroperabilityIFD )
291293 {
292- Call (StreamCalcIFDSize (pWS , value , & cbInteroperabilityIFD ));
294+ Call (StreamCalcIFDSizePrivate (pWS , value , & cbInteroperabilityIFD , rcnt + 1 ));
293295 }
294296 else
295297 {
296298 datasize = IFDEntryTypeSizes [type ] * count ;
297- if ( datasize > 4 )
299+ if (datasize > 4 ) {
298300 cbifd += datasize ;
301+ }
299302 }
300303 ofsdir += SizeofIFDEntry ;
301304 }
302- if ( cbEXIFIFD != 0 )
303- cbifd += ( cbifd & 1 ) + cbEXIFIFD ;
304- if ( cbGPSInfoIFD != 0 )
305- cbifd += ( cbifd & 1 ) + cbGPSInfoIFD ;
306- if ( cbInteroperabilityIFD != 0 )
307- cbifd += ( cbifd & 1 ) + cbInteroperabilityIFD ;
305+ if (cbEXIFIFD != 0 ) {
306+ cbifd += (cbifd & 1 ) + cbEXIFIFD ;
307+ }
308+ if (cbGPSInfoIFD != 0 ) {
309+ cbifd += (cbifd & 1 ) + cbGPSInfoIFD ;
310+ }
311+ if (cbInteroperabilityIFD != 0 ) {
312+ cbifd += (cbifd & 1 ) + cbInteroperabilityIFD ;
313+ }
308314 * pcbifd = cbifd ;
309315
310316Cleanup :
311- if ( GetPosOK )
312- Call (pWS -> SetPos (pWS , offCurPos ));
317+ if (GetPosOK && WMP_errSuccess == err ) {
318+ err = pWS -> SetPos (pWS , offCurPos );
319+ }
313320 return ( err );
314321}
315322
316323
324+ ERR StreamCalcIFDSize (struct WMPStream * pWS , U32 uIFDOfs , U32 * pcbifd )
325+ {
326+ return StreamCalcIFDSizePrivate (pWS , uIFDOfs , pcbifd , 0 );
327+ }
317328
318329// src IFD copied to dst IFD with any nested IFD's
319330// src IFD is arbitrary endian, arbitrary data arrangement
@@ -322,28 +333,23 @@ ERR StreamCalcIFDSize(struct WMPStream* pWS, U32 uIFDOfs, U32 *pcbifd)
322333ERR BufferCopyIFD (const U8 * pbsrc , U32 cbsrc , U32 ofssrc , U8 endian , U8 * pbdst , U32 cbdst , U32 * pofsdst )
323334{
324335 ERR err = WMP_errSuccess ;
325- U16 cDir ;
326- U16 i ;
336+ U16 cDir = 0 ;
327337 U16 ofsEXIFIFDEntry = 0 ;
328338 U16 ofsGPSInfoIFDEntry = 0 ;
329339 U16 ofsInteroperabilityIFDEntry = 0 ;
330340 U32 ofsEXIFIFD = 0 ;
331341 U32 ofsGPSInfoIFD = 0 ;
332342 U32 ofsInteroperabilityIFD = 0 ;
333- U32 ofsdstnextdata ;
334343 U32 ofsdst = * pofsdst ;
335- U32 ofssrcdir ;
336- U32 ofsdstdir ;
337- U32 ofsnextifd ;
338344
339345 Call (getbfwe (pbsrc , cbsrc , ofssrc , & cDir , endian ));
340346 Call (setbfw (pbdst , cbdst , ofsdst , cDir ));
341- ofsnextifd = ofsdst + sizeof (U16 ) + SizeofIFDEntry * cDir ;
342- ofsdstnextdata = ofsnextifd + sizeof (U32 );
347+ U32 ofsnextifd = ofsdst + sizeof (U16 ) + SizeofIFDEntry * cDir ;
348+ U32 ofsdstnextdata = ofsnextifd + sizeof (U32 );
343349
344- ofssrcdir = ofssrc + sizeof (U16 );
345- ofsdstdir = ofsdst + sizeof (U16 );
346- for ( i = 0 ; i < cDir ; i ++ )
350+ U32 ofssrcdir = ofssrc + sizeof (U16 );
351+ U32 ofsdstdir = ofsdst + sizeof (U16 );
352+ for (U16 i = 0 ; i < cDir ; i ++ )
347353 {
348354 U16 tag ;
349355 U16 type ;
@@ -476,32 +482,27 @@ ERR StreamCopyIFD(struct WMPStream* pWS, U32 ofssrc, U8* pbdst, U32 cbdst, U32*
476482 ERR err = WMP_errSuccess ;
477483 size_t offCurPos = 0 ;
478484 Bool GetPosOK = FALSE;
479- U16 cDir ;
480- U16 i ;
485+ U16 cDir = 0 ;
481486 U16 ofsEXIFIFDEntry = 0 ;
482487 U16 ofsGPSInfoIFDEntry = 0 ;
483488 U16 ofsInteroperabilityIFDEntry = 0 ;
484489 U32 ofsEXIFIFD = 0 ;
485490 U32 ofsGPSInfoIFD = 0 ;
486491 U32 ofsInteroperabilityIFD = 0 ;
487- U32 ofsdstnextdata ;
488492 U32 ofsdst = * pofsdst ;
489- U32 ofssrcdir ;
490- U32 ofsdstdir ;
491- U32 ofsnextifd ;
492493
493494 Call (pWS -> GetPos (pWS , & offCurPos ));
494495 GetPosOK = TRUE;
495496
496497 Call (GetUShort (pWS , ofssrc , & cDir ));
497498 Call (setbfw (pbdst , cbdst , ofsdst , cDir ));
498499
499- ofsnextifd = ofsdst + sizeof (U16 ) + SizeofIFDEntry * cDir ;
500- ofsdstnextdata = ofsnextifd + sizeof (U32 );
500+ U32 ofsnextifd = ofsdst + sizeof (U16 ) + SizeofIFDEntry * cDir ;
501+ U32 ofsdstnextdata = ofsnextifd + sizeof (U32 );
501502
502- ofssrcdir = ofssrc + sizeof (U16 );
503- ofsdstdir = ofsdst + sizeof (U16 );
504- for ( i = 0 ; i < cDir ; i ++ )
503+ U32 ofssrcdir = ofssrc + sizeof (U16 );
504+ U32 ofsdstdir = ofsdst + sizeof (U16 );
505+ for (U16 i = 0 ; i < cDir ; i ++ )
505506 {
506507 U16 tag ;
507508 U16 type ;
@@ -579,8 +580,9 @@ ERR StreamCopyIFD(struct WMPStream* pWS, U32 ofssrc, U8* pbdst, U32 cbdst, U32*
579580 * pofsdst = ofsdstnextdata ;
580581
581582Cleanup :
582- if ( GetPosOK )
583+ if (GetPosOK ) {
583584 Call (pWS -> SetPos (pWS , offCurPos ));
585+ }
584586 return err ;
585587}
586588
0 commit comments