@@ -1598,7 +1598,7 @@ static avifBool avifParseItemLocationBox(avifMeta * meta, const uint8_t * raw, s
15981598 return AVIF_TRUE ;
15991599}
16001600
1601- static avifBool avifParseImageGridBox (avifImageGrid * grid , const uint8_t * raw , size_t rawLen , avifDiagnostics * diag )
1601+ static avifBool avifParseImageGridBox (avifImageGrid * grid , const uint8_t * raw , size_t rawLen , uint32_t imageSizeLimit , avifDiagnostics * diag )
16021602{
16031603 BEGIN_STREAM (s , raw , rawLen , diag , "Box[grid]" );
16041604
@@ -1631,7 +1631,7 @@ static avifBool avifParseImageGridBox(avifImageGrid * grid, const uint8_t * raw,
16311631 CHECK (avifROStreamReadU32 (& s , & grid -> outputWidth )); // unsigned int(FieldLength) output_width;
16321632 CHECK (avifROStreamReadU32 (& s , & grid -> outputHeight )); // unsigned int(FieldLength) output_height;
16331633 }
1634- if ((grid -> outputWidth == 0 ) || (grid -> outputHeight == 0 ) || (grid -> outputWidth > (AVIF_MAX_IMAGE_SIZE / grid -> outputHeight ))) {
1634+ if ((grid -> outputWidth == 0 ) || (grid -> outputHeight == 0 ) || (grid -> outputWidth > (imageSizeLimit / grid -> outputHeight ))) {
16351635 avifDiagnosticsPrintf (diag , "Grid box contains illegal dimensions: [%u x %u]" , grid -> outputWidth , grid -> outputHeight );
16361636 return AVIF_FALSE ;
16371637 }
@@ -2322,7 +2322,7 @@ static avifBool avifParseMetaBox(avifMeta * meta, const uint8_t * raw, size_t ra
23222322 return AVIF_TRUE ;
23232323}
23242324
2325- static avifBool avifParseTrackHeaderBox (avifTrack * track , const uint8_t * raw , size_t rawLen , avifDiagnostics * diag )
2325+ static avifBool avifParseTrackHeaderBox (avifTrack * track , const uint8_t * raw , size_t rawLen , uint32_t imageSizeLimit , avifDiagnostics * diag )
23262326{
23272327 BEGIN_STREAM (s , raw , rawLen , diag , "Box[tkhd]" );
23282328
@@ -2365,7 +2365,7 @@ static avifBool avifParseTrackHeaderBox(avifTrack * track, const uint8_t * raw,
23652365 track -> width = width >> 16 ;
23662366 track -> height = height >> 16 ;
23672367
2368- if ((track -> width == 0 ) || (track -> height == 0 ) || (track -> width > (AVIF_MAX_IMAGE_SIZE / track -> height ))) {
2368+ if ((track -> width == 0 ) || (track -> height == 0 ) || (track -> width > (imageSizeLimit / track -> height ))) {
23692369 avifDiagnosticsPrintf (diag , "Track ID [%u] has an invalid size [%ux%u]" , track -> id , track -> width , track -> height );
23702370 return AVIF_FALSE ;
23712371 }
@@ -2644,7 +2644,7 @@ static avifBool avifTrackReferenceBox(avifTrack * track, const uint8_t * raw, si
26442644 return AVIF_TRUE ;
26452645}
26462646
2647- static avifBool avifParseTrackBox (avifDecoderData * data , const uint8_t * raw , size_t rawLen )
2647+ static avifBool avifParseTrackBox (avifDecoderData * data , const uint8_t * raw , size_t rawLen , uint32_t imageSizeLimit )
26482648{
26492649 BEGIN_STREAM (s , raw , rawLen , data -> diag , "Box[trak]" );
26502650
@@ -2655,7 +2655,7 @@ static avifBool avifParseTrackBox(avifDecoderData * data, const uint8_t * raw, s
26552655 CHECK (avifROStreamReadBoxHeader (& s , & header ));
26562656
26572657 if (!memcmp (header .type , "tkhd" , 4 )) {
2658- CHECK (avifParseTrackHeaderBox (track , avifROStreamCurrent (& s ), header .size , data -> diag ));
2658+ CHECK (avifParseTrackHeaderBox (track , avifROStreamCurrent (& s ), header .size , imageSizeLimit , data -> diag ));
26592659 } else if (!memcmp (header .type , "meta" , 4 )) {
26602660 CHECK (avifParseMetaBox (track -> meta , avifROStreamCurrent (& s ), header .size , data -> diag ));
26612661 } else if (!memcmp (header .type , "mdia" , 4 )) {
@@ -2669,7 +2669,7 @@ static avifBool avifParseTrackBox(avifDecoderData * data, const uint8_t * raw, s
26692669 return AVIF_TRUE ;
26702670}
26712671
2672- static avifBool avifParseMoovBox (avifDecoderData * data , const uint8_t * raw , size_t rawLen )
2672+ static avifBool avifParseMoovBox (avifDecoderData * data , const uint8_t * raw , size_t rawLen , uint32_t imageSizeLimit )
26732673{
26742674 BEGIN_STREAM (s , raw , rawLen , data -> diag , "Box[moov]" );
26752675
@@ -2678,7 +2678,7 @@ static avifBool avifParseMoovBox(avifDecoderData * data, const uint8_t * raw, si
26782678 CHECK (avifROStreamReadBoxHeader (& s , & header ));
26792679
26802680 if (!memcmp (header .type , "trak" , 4 )) {
2681- CHECK (avifParseTrackBox (data , avifROStreamCurrent (& s ), header .size ));
2681+ CHECK (avifParseTrackBox (data , avifROStreamCurrent (& s ), header .size , imageSizeLimit ));
26822682 }
26832683
26842684 CHECK (avifROStreamSkip (& s , header .size ));
@@ -2779,7 +2779,7 @@ static avifResult avifParse(avifDecoder * decoder)
27792779 metaSeen = AVIF_TRUE ;
27802780 } else if (!memcmp (header .type , "moov" , 4 )) {
27812781 CHECKERR (!moovSeen , AVIF_RESULT_BMFF_PARSE_FAILED );
2782- CHECKERR (avifParseMoovBox (data , boxContents .data , boxContents .size ), AVIF_RESULT_BMFF_PARSE_FAILED );
2782+ CHECKERR (avifParseMoovBox (data , boxContents .data , boxContents .size , decoder -> imageSizeLimit ), AVIF_RESULT_BMFF_PARSE_FAILED );
27832783 moovSeen = AVIF_TRUE ;
27842784 }
27852785
@@ -2847,6 +2847,7 @@ avifDecoder * avifDecoderCreate(void)
28472847 avifDecoder * decoder = (avifDecoder * )avifAlloc (sizeof (avifDecoder ));
28482848 memset (decoder , 0 , sizeof (avifDecoder ));
28492849 decoder -> maxThreads = 1 ;
2850+ decoder -> imageSizeLimit = AVIF_DEFAULT_MAX_IMAGE_SIZE ;
28502851 decoder -> imageCountLimit = AVIF_DEFAULT_IMAGE_COUNT_LIMIT ;
28512852 decoder -> strictFlags = AVIF_STRICT_ENABLED ;
28522853 return decoder ;
@@ -3033,6 +3034,11 @@ avifResult avifDecoderParse(avifDecoder * decoder)
30333034{
30343035 avifDiagnosticsClearError (& decoder -> diag );
30353036
3037+ // An imageSizeLimit greater than AVIF_DEFAULT_MAX_IMAGE_SIZE and the special value of 0 to
3038+ // disable the limit are not yet implemented.
3039+ if ((decoder -> imageSizeLimit > AVIF_DEFAULT_MAX_IMAGE_SIZE ) || (decoder -> imageSizeLimit == 0 )) {
3040+ return AVIF_RESULT_NOT_IMPLEMENTED ;
3041+ }
30363042 if (!decoder -> io || !decoder -> io -> read ) {
30373043 return AVIF_RESULT_IO_NOT_SET ;
30383044 }
@@ -3073,7 +3079,7 @@ avifResult avifDecoderParse(avifDecoder * decoder)
30733079 item -> width = ispeProp -> u .ispe .width ;
30743080 item -> height = ispeProp -> u .ispe .height ;
30753081
3076- if ((item -> width == 0 ) || (item -> height == 0 ) || (item -> width > (AVIF_MAX_IMAGE_SIZE / item -> height ))) {
3082+ if ((item -> width == 0 ) || (item -> height == 0 ) || (item -> width > (decoder -> imageSizeLimit / item -> height ))) {
30773083 avifDiagnosticsPrintf (data -> diag , "Item ID [%u] has an invalid size [%ux%u]" , item -> id , item -> width , item -> height );
30783084 return AVIF_RESULT_BMFF_PARSE_FAILED ;
30793085 }
@@ -3302,7 +3308,7 @@ avifResult avifDecoderReset(avifDecoder * decoder)
33023308 if (readResult != AVIF_RESULT_OK ) {
33033309 return readResult ;
33043310 }
3305- if (!avifParseImageGridBox (& data -> colorGrid , readData .data , readData .size , data -> diag )) {
3311+ if (!avifParseImageGridBox (& data -> colorGrid , readData .data , readData .size , decoder -> imageSizeLimit , data -> diag )) {
33063312 return AVIF_RESULT_INVALID_IMAGE_GRID ;
33073313 }
33083314 }
@@ -3342,7 +3348,7 @@ avifResult avifDecoderReset(avifDecoder * decoder)
33423348 if (readResult != AVIF_RESULT_OK ) {
33433349 return readResult ;
33443350 }
3345- if (!avifParseImageGridBox (& data -> alphaGrid , readData .data , readData .size , data -> diag )) {
3351+ if (!avifParseImageGridBox (& data -> alphaGrid , readData .data , readData .size , decoder -> imageSizeLimit , data -> diag )) {
33463352 return AVIF_RESULT_INVALID_IMAGE_GRID ;
33473353 }
33483354 }
@@ -3611,7 +3617,7 @@ avifResult avifDecoderNextImage(avifDecoder * decoder)
36113617
36123618 // Scale the decoded image so that it corresponds to this tile's output dimensions
36133619 if ((tile -> width != tile -> image -> width ) || (tile -> height != tile -> image -> height )) {
3614- if (!avifImageScale (tile -> image , tile -> width , tile -> height , & decoder -> diag )) {
3620+ if (!avifImageScale (tile -> image , tile -> width , tile -> height , decoder -> imageSizeLimit , & decoder -> diag )) {
36153621 avifDiagnosticsPrintf (& decoder -> diag , "avifImageScale() failed" );
36163622 return tile -> input -> alpha ? AVIF_RESULT_DECODE_ALPHA_FAILED : AVIF_RESULT_DECODE_COLOR_FAILED ;
36173623 }
0 commit comments