Skip to content

Commit 456f78a

Browse files
committed
Do not store potentially invalid pointers
Calling avifMetaFindItem() could invalidate all the existing item pointers that are being stored by the caller (since the function could resize the item array). This patch fixes avifDecoderReset by updating the locally stored pointer after call to avifMetaFindItem. This is a manual cherry-pick of commit `2041109` on to the v1.0.x branch.
1 parent 4b40100 commit 456f78a

File tree

1 file changed

+27
-8
lines changed

1 file changed

+27
-8
lines changed

src/read.c

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,8 @@ static void avifMetaDestroy(avifMeta * meta)
769769
avifFree(meta);
770770
}
771771

772+
// CAUTION: This function could potentially resize the meta->items array thereby invalidating all existing pointers that are being
773+
// stored locally. So if this function is being called, exercise caution in the caller to not use invalid pointers.
772774
static avifDecoderItem * avifMetaFindItem(avifMeta * meta, uint32_t itemID)
773775
{
774776
if (itemID == 0) {
@@ -3614,17 +3616,20 @@ static avifBool avifDecoderItemIsAlphaAux(avifDecoderItem * item, uint32_t color
36143616
return auxCProp && isAlphaURN(auxCProp->u.auxC.auxType);
36153617
}
36163618

3617-
// Finds the alpha item whose parent item is colorItem and sets it in the alphaItem output parameter. Returns AVIF_RESULT_OK on
3618-
// success. Note that *alphaItem can be NULL even if the return value is AVIF_RESULT_OK. If the colorItem is a grid and the alpha
3619-
// item is represented as a set of auxl items to each color tile, then a fake item will be created and *isAlphaItemInInput will be
3620-
// set to AVIF_FALSE. In this case, the alpha item merely exists to hold the locations of the alpha tile items. The data of this
3621-
// item need not be read and the pixi property cannot be validated. Otherwise, *isAlphaItemInInput will be set to AVIF_TRUE when
3622-
// *alphaItem is not NULL.
3619+
// Finds the alpha item whose parent item is *colorItemPtr and sets it in the alphaItem output parameter. Returns AVIF_RESULT_OK
3620+
// on success. Note that *alphaItem can be NULL even if the return value is AVIF_RESULT_OK. If the *colorItemPtr is a grid and the
3621+
// alpha item is represented as a set of auxl items to each color tile, then a fake item will be created and *isAlphaItemInInput
3622+
// will be set to AVIF_FALSE. In this case, the alpha item merely exists to hold the locations of the alpha tile items. The data
3623+
// of this item need not be read and the pixi property cannot be validated. Otherwise, *isAlphaItemInInput will be set to
3624+
// AVIF_TRUE when *alphaItem is not NULL. If the data->meta->items array is resized, then the value in *colorItemPtr could become
3625+
// invalid. This function also resets *colorItemPtr to the right value if an alpha item was found and added to the data->meta->items
3626+
// array.
36233627
static avifResult avifDecoderDataFindAlphaItem(avifDecoderData * data,
3624-
avifDecoderItem * colorItem,
3628+
avifDecoderItem ** colorItemPtr,
36253629
avifDecoderItem ** alphaItem,
36263630
avifBool * isAlphaItemInInput)
36273631
{
3632+
const avifDecoderItem * colorItem = *colorItemPtr;
36283633
for (uint32_t itemIndex = 0; itemIndex < data->meta->items.count; ++itemIndex) {
36293634
avifDecoderItem * item = &data->meta->items.item[itemIndex];
36303635
if (avifDecoderItemShouldBeSkipped(item)) {
@@ -3674,12 +3679,26 @@ static avifResult avifDecoderDataFindAlphaItem(avifDecoderData * data,
36743679
*isAlphaItemInInput = AVIF_FALSE;
36753680
return AVIF_RESULT_OK;
36763681
}
3682+
3683+
int colorItemIndex = -1;
3684+
for (uint32_t i = 0; i < data->meta->items.count; ++i) {
3685+
if (colorItem->id == data->meta->items.item[i].id) {
3686+
colorItemIndex = i;
3687+
break;
3688+
}
3689+
}
3690+
assert(colorItemIndex >= 0);
3691+
36773692
*alphaItem = avifMetaFindItem(colorItem->meta, maxItemID + 1);
36783693
if (*alphaItem == NULL) {
36793694
avifFree(alphaItemIndices);
36803695
*isAlphaItemInInput = AVIF_FALSE;
36813696
return AVIF_RESULT_OUT_OF_MEMORY;
36823697
}
3698+
// avifMetaFindItem() could invalidate all existing item pointers. So reset the colorItem pointers.
3699+
*colorItemPtr = &data->meta->items.item[colorItemIndex];
3700+
colorItem = *colorItemPtr;
3701+
36833702
memcpy((*alphaItem)->type, "grid", 4);
36843703
(*alphaItem)->width = colorItem->width;
36853704
(*alphaItem)->height = colorItem->height;
@@ -3929,7 +3948,7 @@ avifResult avifDecoderReset(avifDecoder * decoder)
39293948

39303949
avifBool isAlphaItemInInput;
39313950
avifDecoderItem * alphaItem;
3932-
AVIF_CHECKRES(avifDecoderDataFindAlphaItem(data, colorItem, &alphaItem, &isAlphaItemInInput));
3951+
AVIF_CHECKRES(avifDecoderDataFindAlphaItem(data, &colorItem, &alphaItem, &isAlphaItemInInput));
39333952
avifCodecType alphaCodecType = AVIF_CODEC_TYPE_UNKNOWN;
39343953
if (alphaItem) {
39353954
if (!memcmp(alphaItem->type, "grid", 4)) {

0 commit comments

Comments
 (0)