From 1e24db049f05a53ff7bd732ccde50c41bcd7d690 Mon Sep 17 00:00:00 2001 From: fairay Date: Thu, 6 Apr 2023 15:31:20 +0300 Subject: [PATCH 1/2] Add image reference cycle detection --- libheif/error.cc | 2 ++ libheif/heif.h | 3 +++ libheif/heif_file.cc | 30 ++++++++++++++++++++++++++++++ libheif/heif_file.h | 5 +++++ 4 files changed, 40 insertions(+) diff --git a/libheif/error.cc b/libheif/error.cc index d653cb44d7..7eef599cba 100644 --- a/libheif/error.cc +++ b/libheif/error.cc @@ -179,6 +179,8 @@ const char* heif::Error::get_error_string(heif_suberror_code err) return "Unsupported parameter"; case heif_suberror_Invalid_parameter_value: return "Invalid parameter value"; + case heif_suberror_Item_reference_cycle: + return "Image reference cycle"; // --- Unsupported_feature --- diff --git a/libheif/heif.h b/libheif/heif.h index 793e46c871..c41955b19c 100644 --- a/libheif/heif.h +++ b/libheif/heif.h @@ -253,6 +253,9 @@ enum heif_suberror_code // The value for the given parameter is not in the valid range. heif_suberror_Invalid_parameter_value = 2006, + // Image reference cycle found in iref + heif_suberror_Item_reference_cycle = 2007, + // --- Unsupported_feature --- diff --git a/libheif/heif_file.cc b/libheif/heif_file.cc index 9b887e47b7..d1add4a3f3 100644 --- a/libheif/heif_file.cc +++ b/libheif/heif_file.cc @@ -318,6 +318,13 @@ Error HeifFile::parse_heif_file(BitstreamRange& range) m_idat_box = std::dynamic_pointer_cast(m_meta_box->get_child_box(fourcc("idat"))); m_iref_box = std::dynamic_pointer_cast(m_meta_box->get_child_box(fourcc("iref"))); + if (m_iref_box) { + std::unordered_set parent_items; + Error error = check_for_ref_cycle(get_primary_image_ID(), m_iref_box, parent_items); + if (error) { + return error; + } + } m_iinf_box = std::dynamic_pointer_cast(m_meta_box->get_child_box(fourcc("iinf"))); if (!m_iinf_box) { @@ -345,6 +352,29 @@ Error HeifFile::parse_heif_file(BitstreamRange& range) } +Error HeifFile::check_for_ref_cycle(heif_item_id ID, + std::shared_ptr& iref_box, + std::unordered_set& parent_items) const { + if (parent_items.contains(ID)) { + return Error(heif_error_Invalid_input, + heif_suberror_Item_reference_cycle, + "Image reference cycle"); + } + parent_items.insert(ID); + + std::vector image_references = iref_box->get_references(ID, fourcc("dimg")); + for (heif_item_id reference_idx : image_references) { + Error error = check_for_ref_cycle(reference_idx, iref_box, parent_items); + if (error) { + return error; + } + } + + parent_items.erase(ID); + return Error::Ok; +} + + bool HeifFile::image_exists(heif_item_id ID) const { auto image_iter = m_infe_boxes.find(ID); diff --git a/libheif/heif_file.h b/libheif/heif_file.h index bdc0a10993..4c95227396 100644 --- a/libheif/heif_file.h +++ b/libheif/heif_file.h @@ -32,6 +32,7 @@ #include #include #include +#include #if ENABLE_PARALLEL_TILE_DECODING #include @@ -199,6 +200,10 @@ namespace heif { Error parse_heif_file(BitstreamRange& bitstream); + Error check_for_ref_cycle(heif_item_id ID, + std::shared_ptr& iref_box, + std::unordered_set& parent_items) const; + std::shared_ptr get_infe(heif_item_id ID) const; }; From 5170f7c0ed068b3c9eb91e257d9d496b4c611151 Mon Sep 17 00:00:00 2001 From: fairay Date: Thu, 6 Apr 2023 17:01:35 +0300 Subject: [PATCH 2/2] fix contains method usage --- libheif/heif_file.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libheif/heif_file.cc b/libheif/heif_file.cc index d1add4a3f3..df35011164 100644 --- a/libheif/heif_file.cc +++ b/libheif/heif_file.cc @@ -355,7 +355,7 @@ Error HeifFile::parse_heif_file(BitstreamRange& range) Error HeifFile::check_for_ref_cycle(heif_item_id ID, std::shared_ptr& iref_box, std::unordered_set& parent_items) const { - if (parent_items.contains(ID)) { + if (parent_items.find(ID) != parent_items.end()) { return Error(heif_error_Invalid_input, heif_suberror_Item_reference_cycle, "Image reference cycle");