Skip to content

Commit 030cace

Browse files
committed
Better ID choice for new item.
This is a manual cherry-pick of commit 59f1c9a. This fixes the case where the maximum ID is UINT32_MAX. BUG=oss-fuzz:65657
1 parent 4ae05d6 commit 030cace

1 file changed

Lines changed: 24 additions & 8 deletions

File tree

src/read.c

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3665,12 +3665,8 @@ static avifResult avifDecoderDataFindAlphaItem(avifDecoderData * data,
36653665
uint32_t * alphaItemIndices = avifAlloc(colorItemCount * sizeof(uint32_t));
36663666
AVIF_CHECKERR(alphaItemIndices, AVIF_RESULT_OUT_OF_MEMORY);
36673667
uint32_t alphaItemCount = 0;
3668-
uint32_t maxItemID = 0;
36693668
for (uint32_t i = 0; i < colorItem->meta->items.count; ++i) {
3670-
avifDecoderItem * item = colorItem->meta->items.item[i];
3671-
if (item->id > maxItemID) {
3672-
maxItemID = item->id;
3673-
}
3669+
const avifDecoderItem * const item = colorItem->meta->items.item[i];
36743670
if (item->dimgForID == colorItem->id) {
36753671
avifBool seenAlphaForCurrentItem = AVIF_FALSE;
36763672
for (uint32_t j = 0; j < colorItem->meta->items.count; ++j) {
@@ -3699,11 +3695,31 @@ static avifResult avifDecoderDataFindAlphaItem(avifDecoderData * data,
36993695
}
37003696
}
37013697
assert(alphaItemCount == colorItemCount);
3702-
*alphaItem = avifMetaFindItem(colorItem->meta, maxItemID + 1);
3703-
if (*alphaItem == NULL) {
3698+
// Find an unused ID.
3699+
avifResult result;
3700+
if (colorItem->meta->items.count >= UINT32_MAX - 1) {
3701+
// In the improbable case where all IDs are used.
3702+
result = AVIF_RESULT_DECODE_ALPHA_FAILED;
3703+
} else {
3704+
uint32_t newItemID = 0;
3705+
avifBool isUsed;
3706+
do {
3707+
++newItemID;
3708+
isUsed = AVIF_FALSE;
3709+
for (uint32_t i = 0; i < colorItem->meta->items.count; ++i) {
3710+
if (colorItem->meta->items.item[i]->id == newItemID) {
3711+
isUsed = AVIF_TRUE;
3712+
break;
3713+
}
3714+
}
3715+
} while (isUsed && newItemID != 0);
3716+
*alphaItem = avifMetaFindItem(colorItem->meta, newItemID); // Create new empty item.
3717+
result = (*alphaItem == NULL) ? AVIF_RESULT_OUT_OF_MEMORY : AVIF_RESULT_OK;
3718+
}
3719+
if (result != AVIF_RESULT_OK) {
37043720
avifFree(alphaItemIndices);
37053721
*isAlphaItemInInput = AVIF_FALSE;
3706-
return AVIF_RESULT_OUT_OF_MEMORY;
3722+
return result;
37073723
}
37083724
memcpy((*alphaItem)->type, "grid", 4);
37093725
(*alphaItem)->width = colorItem->width;

0 commit comments

Comments
 (0)