diff --git a/libavformat/imf.h b/libavformat/imf.h index 26668b1f4d..822e70afef 100644 --- a/libavformat/imf.h +++ b/libavformat/imf.h @@ -102,7 +102,7 @@ typedef struct FFIMFTrackFileVirtualTrack { FFIMFBaseVirtualTrack base; uint32_t resource_count; /**< Number of Resource elements present in the Virtual Track */ FFIMFTrackFileResource *resources; /**< Resource elements of the Virtual Track */ - uint32_t resources_alloc_sz; /**< Size of the resources buffer */ + unsigned int resources_alloc_sz; /**< Size of the resources buffer */ } FFIMFTrackFileVirtualTrack; /** diff --git a/libavformat/imf_cpl.c b/libavformat/imf_cpl.c index fbe892128f..f85d25932c 100644 --- a/libavformat/imf_cpl.c +++ b/libavformat/imf_cpl.c @@ -324,6 +324,8 @@ static int fill_marker_resource(xmlNodePtr marker_resource_elem, if (xmlStrcmp(element->name, "Marker") == 0) { void *tmp; + if (marker_resource->marker_count == UINT32_MAX) + return AVERROR(ENOMEM); tmp = av_realloc_array(marker_resource->markers, marker_resource->marker_count + 1, sizeof(FFIMFMarker)); @@ -384,6 +386,9 @@ static int push_marker_sequence(xmlNodePtr marker_sequence_elem, FFIMFCPL *cpl) if (!resource_list_elem) return 0; resource_elem_count = xmlChildElementCount(resource_list_elem); + if (resource_elem_count > UINT32_MAX + || cpl->main_markers_track->resource_count > UINT32_MAX - resource_elem_count) + return AVERROR(ENOMEM); tmp = av_realloc_array(cpl->main_markers_track->resources, cpl->main_markers_track->resource_count + resource_elem_count, sizeof(FFIMFMarkerResource)); @@ -456,6 +461,8 @@ static int push_main_audio_sequence(xmlNodePtr audio_sequence_elem, FFIMFCPL *cp /* create a main audio virtual track if none exists for the sequence */ if (!vt) { + if (cpl->main_audio_track_count == UINT32_MAX) + return AVERROR(ENOMEM); tmp = av_realloc_array(cpl->main_audio_tracks, cpl->main_audio_track_count + 1, sizeof(FFIMFTrackFileVirtualTrack)); @@ -473,6 +480,9 @@ static int push_main_audio_sequence(xmlNodePtr audio_sequence_elem, FFIMFCPL *cp if (!resource_list_elem) return 0; resource_elem_count = xmlChildElementCount(resource_list_elem); + if (resource_elem_count > UINT32_MAX + || vt->resource_count > UINT32_MAX - resource_elem_count) + return AVERROR(ENOMEM); tmp = av_fast_realloc(vt->resources, &vt->resources_alloc_sz, (vt->resource_count + resource_elem_count) * sizeof(FFIMFTrackFileResource)); @@ -546,6 +556,10 @@ static int push_main_image_2d_sequence(xmlNodePtr image_sequence_elem, FFIMFCPL if (!resource_list_elem) return 0; resource_elem_count = xmlChildElementCount(resource_list_elem); + if (resource_elem_count > UINT32_MAX + || cpl->main_image_2d_track->resource_count > UINT32_MAX - resource_elem_count + || (cpl->main_image_2d_track->resource_count + resource_elem_count) > INT_MAX / sizeof(FFIMFTrackFileResource)) + return AVERROR(ENOMEM); tmp = av_fast_realloc(cpl->main_image_2d_track->resources, &cpl->main_image_2d_track->resources_alloc_sz, (cpl->main_image_2d_track->resource_count + resource_elem_count) * sizeof(FFIMFTrackFileResource)); diff --git a/libavformat/imfdec.c b/libavformat/imfdec.c index 9b063174e2..a8dd34200a 100644 --- a/libavformat/imfdec.c +++ b/libavformat/imfdec.c @@ -92,7 +92,7 @@ typedef struct IMFVirtualTrackPlaybackCtx { AVRational duration; // Resources uint32_t resource_count; - uint32_t resources_alloc_sz; + unsigned int resources_alloc_sz; IMFVirtualTrackResourcePlaybackCtx *resources; // Decoding cursors uint32_t current_resource_index; @@ -154,6 +154,7 @@ static int parse_imf_asset_map_from_xml_dom(AVFormatContext *s, xmlNodePtr asset_map_element = NULL; xmlNodePtr node = NULL; xmlNodePtr asset_element = NULL; + unsigned long elem_count; char *uri; int ret = 0; IMFAssetLocator *asset = NULL; @@ -180,8 +181,12 @@ static int parse_imf_asset_map_from_xml_dom(AVFormatContext *s, av_log(s, AV_LOG_ERROR, "Unable to parse asset map XML - missing AssetList node\n"); return AVERROR_INVALIDDATA; } + elem_count = xmlChildElementCount(node); + if (elem_count > UINT32_MAX + || asset_map->asset_count > UINT32_MAX - elem_count) + return AVERROR(ENOMEM); tmp = av_realloc_array(asset_map->assets, - xmlChildElementCount(node) + asset_map->asset_count, + elem_count + asset_map->asset_count, sizeof(IMFAssetLocator)); if (!tmp) { av_log(NULL, AV_LOG_ERROR, "Cannot allocate IMF asset locators\n"); @@ -436,6 +441,11 @@ static int open_track_file_resource(AVFormatContext *s, "Found locator for " FF_IMF_UUID_FORMAT ": %s\n", UID_ARG(asset_locator->uuid), asset_locator->absolute_uri); + + if (track->resource_count > UINT32_MAX - track_file_resource->base.repeat_count + || (track->resource_count + track_file_resource->base.repeat_count) + > INT_MAX / sizeof(IMFVirtualTrackResourcePlaybackCtx)) + return AVERROR(ENOMEM); tmp = av_fast_realloc(track->resources, &track->resources_alloc_sz, (track->resource_count + track_file_resource->base.repeat_count) @@ -500,6 +510,10 @@ static int open_virtual_track(AVFormatContext *s, track->current_timestamp = av_make_q(0, track->duration.den); + if (c->track_count == UINT32_MAX) { + ret = AVERROR(ENOMEM); + goto clean_up; + } tmp = av_realloc_array(c->tracks, c->track_count + 1, sizeof(IMFVirtualTrackPlaybackCtx *)); if (!tmp) { ret = AVERROR(ENOMEM);