diff --git a/src/read.c b/src/read.c index 64640e1584..e6078e1362 100644 --- a/src/read.c +++ b/src/read.c @@ -2154,6 +2154,20 @@ static avifResult avifParseItemLocationBox(avifMeta * meta, const uint8_t * raw, AVIF_CHECKERR(avifROStreamReadUX8(&s, &baseOffset, baseOffsetSize), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(base_offset_size*8) base_offset; uint16_t extentCount; AVIF_CHECKERR(avifROStreamReadU16(&s, &extentCount), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(16) extent_count; + const uint32_t bytesPerExtent = indexSize + offsetSize + lengthSize; + if (bytesPerExtent == 0 && extentCount > 1) { + avifDiagnosticsPrintf(diag, "Item ID [%u] declares %u extents that consume no input bytes", itemID, extentCount); + return AVIF_RESULT_BMFF_PARSE_FAILED; + } + const size_t remainingBytes = avifROStreamRemainingBytes(&s); + if ((uint64_t)extentCount * bytesPerExtent > remainingBytes) { + avifDiagnosticsPrintf(diag, + "Item ID [%u] extent_count [%u] exceeds the remaining %zu bytes of the iloc box", + itemID, + extentCount, + remainingBytes); + return AVIF_RESULT_BMFF_PARSE_FAILED; + } for (int extentIter = 0; extentIter < extentCount; ++extentIter) { if ((version == 1 || version == 2) && indexSize > 0) { // Section 8.11.3.1 of ISO/IEC 14496-12: @@ -2169,7 +2183,11 @@ static avifResult avifParseItemLocationBox(avifMeta * meta, const uint8_t * raw, AVIF_CHECKERR(avifROStreamReadUX8(&s, &extentOffset, offsetSize), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(offset_size*8) extent_offset; uint64_t extentLength; AVIF_CHECKERR(avifROStreamReadUX8(&s, &extentLength, lengthSize), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(length_size*8) extent_length; - + // ISO/IEC 14496-12, Section 8.11.3.2.4.3: extent_length == 0 is not supported by libavif. + if (lengthSize > 0 && extentLength == 0) { + avifDiagnosticsPrintf(diag, "Item ID [%u] uses extent_length = 0, which is not supported", itemID); + return AVIF_RESULT_NOT_IMPLEMENTED; + } avifExtent * extent = (avifExtent *)avifArrayPush(&item->extents); AVIF_CHECKERR(extent != NULL, AVIF_RESULT_OUT_OF_MEMORY); if (extentOffset > UINT64_MAX - baseOffset) {