Add avifDecoderItemIsAlphaAuxOld as temporary fix
Avoid the failure of the assertion numTiles == numExpectedTiles in
avifFillDimgIdxToItemIdxArray() and allow us to investigate the bug.
Add avifDecoderItemIsAlphaAuxOld() to emulate the old behavior of
avifDecoderItemIsAlphaAux() before commit 2f8eb91 and call
avifDecoderItemIsAlphaAuxOld() in the loop that builds the
dimgIdxToAlphaItemIdx array in avifMetaFindAlphaItem().
Bug: https://g-issues.oss-fuzz.com/issues/553221196
diff --git a/src/read.c b/src/read.c
index 3dc988b..3bd4787 100644
--- a/src/read.c
+++ b/src/read.c
@@ -274,6 +274,20 @@
return AVIF_FALSE;
}
+// Bug oss-fuzz:553221196: The same as avifReferences() except that it emulates
+// the old behavior before commit 2f8eb91 and considers only the last reference.
+static avifBool avifReferencesOld(const avifItemReferenceArray * references, const char * type, uint32_t toID)
+{
+ for (uint32_t i = references->count; i > 0;) {
+ --i;
+ const avifItemReference * reference = &references->ref[i];
+ if (!memcmp(reference->type, type, 4)) {
+ return reference->toID == toID;
+ }
+ }
+ return AVIF_FALSE;
+}
+
// Returns AVIF_TRUE if this item or track is a {type} for at least one item or track.
static avifBool avifHasReference(const avifItemReferenceArray * references, const char * type)
{
@@ -5563,6 +5577,17 @@
return auxCProp && isAlphaURN(auxCProp->u.auxC.auxType);
}
+// Bug oss-fuzz:553221196: The same as avifDecoderItemIsAlphaAux() except that
+// it calls avifReferencesOld() instead of avifReferences() to emulate the old
+// behavior before commit 2f8eb91.
+static avifBool avifDecoderItemIsAlphaAuxOld(const avifDecoderItem * item, uint32_t colorItemId)
+{
+ if (!avifReferencesOld(&item->references, "auxl", colorItemId))
+ return AVIF_FALSE;
+ const avifProperty * auxCProp = avifPropertyArrayFind(&item->properties, "auxC");
+ return auxCProp && isAlphaURN(auxCProp->u.auxC.auxType);
+}
+
// Finds the alpha item whose parent item is colorItem and sets it in the alphaItem output parameter. Returns AVIF_RESULT_OK on
// 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
// item is represented as a set of auxl items to each color tile, then a fake item will be created and *isAlphaItemInInput will be
@@ -5613,7 +5638,7 @@
avifBool seenAlphaForCurrentItem = AVIF_FALSE;
for (uint32_t j = 0; j < meta->items.count; ++j) {
avifDecoderItem * auxlItem = meta->items.item[j];
- if (avifDecoderItemIsAlphaAux(auxlItem, item->id)) {
+ if (avifDecoderItemIsAlphaAuxOld(auxlItem, item->id)) {
if (seenAlphaForCurrentItem || auxlItem->dimgForID != 0 || item->dimgIdx >= tileCount ||
dimgIdxToAlphaItemIdx[item->dimgIdx] != itemIndexNotSet) {
// One of the following invalid cases: