Validate some sizes avifParseCondensedImageBox
avifROStreamReadVarInt() may read a uint32_t value as large as
UINT32_MAX. Check the uint32_t variables before incrementing them.
Declare `offset` as uint64_t instead of size_t, because it is assigned
to uint64_t struct members.
diff --git a/src/read.c b/src/read.c
index fa9fef4..73410a3 100644
--- a/src/read.c
+++ b/src/read.c
@@ -3296,9 +3296,11 @@
AVIF_CHECKERR(version == 0, AVIF_RESULT_NOT_IMPLEMENTED);
uint32_t width, height;
- AVIF_CHECKERR(avifROStreamReadVarInt(&s, &width), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) width_minus_one;
- AVIF_CHECKERR(avifROStreamReadVarInt(&s, &height), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) height_minus_one;
+ AVIF_CHECKERR(avifROStreamReadVarInt(&s, &width), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) width_minus_one;
+ AVIF_CHECKERR(width != UINT32_MAX, AVIF_RESULT_BMFF_PARSE_FAILED);
++width;
+ AVIF_CHECKERR(avifROStreamReadVarInt(&s, &height), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) height_minus_one;
+ AVIF_CHECKERR(height != UINT32_MAX, AVIF_RESULT_BMFF_PARSE_FAILED);
++height;
uint32_t isFloat;
@@ -3326,7 +3328,8 @@
colorPrimaries = AVIF_COLOR_PRIMARIES_UNSPECIFIED;
transferCharacteristics = AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED;
AVIF_CHECKERR(avifROStreamReadBits(&s, &matrixCoefficients, 8), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(8) matrix_coefficients;
- AVIF_CHECKERR(avifROStreamReadVarInt(&s, &iccDataSize), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) icc_data_size;
+ AVIF_CHECKERR(avifROStreamReadVarInt(&s, &iccDataSize), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) icc_data_size_minus_one;
+ AVIF_CHECKERR(iccDataSize != UINT32_MAX, AVIF_RESULT_BMFF_PARSE_FAILED);
++iccDataSize;
} else if (colorType == AVIF_CONI_COLOR_TYPE_SRGB) {
// sRGB
@@ -3351,7 +3354,8 @@
uint32_t colorItemCodecConfigSize, colorItemDataSize;
AVIF_CHECKERR(avifROStreamReadVarInt(&s, &colorItemCodecConfigSize), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) main_item_codec_config_size;
AVIF_CHECKERR(colorItemCodecConfigSize == 4, AVIF_RESULT_NOT_IMPLEMENTED);
- AVIF_CHECKERR(avifROStreamReadVarInt(&s, &colorItemDataSize), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) main_item_data_size;
+ AVIF_CHECKERR(avifROStreamReadVarInt(&s, &colorItemDataSize), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) main_item_data_size_minus_one;
+ AVIF_CHECKERR(colorItemDataSize != UINT32_MAX, AVIF_RESULT_BMFF_PARSE_FAILED);
++colorItemDataSize;
uint32_t hasAlpha;
@@ -3370,17 +3374,20 @@
uint32_t extendedMetaSize = 0, exifSize = 0, xmpSize = 0;
AVIF_CHECKERR(avifROStreamReadBits(&s, &hasExtendedMeta, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(1) has_extended_meta;
if (hasExtendedMeta) {
- AVIF_CHECKERR(avifROStreamReadVarInt(&s, &extendedMetaSize), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) extended_meta_size;
+ AVIF_CHECKERR(avifROStreamReadVarInt(&s, &extendedMetaSize), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) extended_meta_size_minus_one;
+ AVIF_CHECKERR(extendedMetaSize != UINT32_MAX, AVIF_RESULT_BMFF_PARSE_FAILED);
++extendedMetaSize;
}
AVIF_CHECKERR(avifROStreamReadBits(&s, &hasExif, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(1) has_exif;
if (hasExif) {
- AVIF_CHECKERR(avifROStreamReadVarInt(&s, &exifSize), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) exif_data_size;
+ AVIF_CHECKERR(avifROStreamReadVarInt(&s, &exifSize), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) exif_data_size_minus_one;
+ AVIF_CHECKERR(exifSize != UINT32_MAX, AVIF_RESULT_BMFF_PARSE_FAILED);
++exifSize;
}
AVIF_CHECKERR(avifROStreamReadBits(&s, &hasXMP, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(1) has_xmp;
if (hasXMP) {
- AVIF_CHECKERR(avifROStreamReadVarInt(&s, &xmpSize), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) xmp_data_size;
+ AVIF_CHECKERR(avifROStreamReadVarInt(&s, &xmpSize), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) xmp_data_size_minus_one;
+ AVIF_CHECKERR(xmpSize != UINT32_MAX, AVIF_RESULT_BMFF_PARSE_FAILED);
++xmpSize;
}
@@ -3409,7 +3416,7 @@
// Store and update the offset for the following item extents and properties.
// The extendedMeta field is parsed after creating the items defined by the CondensedImageBox
// so the stream s cannot be used for keeping track of the position.
- size_t offset = (size_t)rawOffset + avifROStreamOffset(&s) + (size_t)extendedMetaSize;
+ uint64_t offset = rawOffset + avifROStreamOffset(&s) + extendedMetaSize;
// Create the items and properties generated by the CondensedImageBox.
// The CondensedImageBox always creates 8 properties for specification easiness.