Commit 720cad26 for libheif
commit 720cad262288196225c5c9c9cc7ee530309f020f
Author: Dirk Farin <dirk.farin@gmail.com>
Date: Sat Nov 29 21:58:16 2025 +0100
heif_list_compatible_brands() checks that input starts with 'ftyp' box. (fixes #1633)
diff --git a/libheif/api/libheif/heif_brands.cc b/libheif/api/libheif/heif_brands.cc
index 43938d68..c030785c 100644
--- a/libheif/api/libheif/heif_brands.cc
+++ b/libheif/api/libheif/heif_brands.cc
@@ -108,11 +108,35 @@ heif_error heif_list_compatible_brands(const uint8_t* data, int len, heif_brand2
return {heif_error_Usage_error, heif_suberror_Invalid_parameter_value, "data length must be positive"};
}
+ const heif_security_limits* security_limits = heif_get_global_security_limits();
+
+
+ // --- check that file begins with ftyp box
+
+ {
+ auto stream = std::make_shared<StreamReader_memory>(data, len, false);
+ BitstreamRange range(stream, len);
+
+ BoxHeader hdr;
+ Error err = hdr.parse_header(range);
+ if (err) {
+ return {err.error_code, err.sub_error_code, "error reading ftype box header"};
+ }
+
+ if (hdr.get_short_type() != fourcc("ftyp")) {
+ return {
+ heif_error_Invalid_input,
+ heif_suberror_Unspecified,
+ "File does not begin with 'ftyp' box."
+ };
+ }
+ }
+
auto stream = std::make_shared<StreamReader_memory>(data, len, false);
BitstreamRange range(stream, len);
std::shared_ptr<Box> box;
- Error err = Box::read(range, &box, heif_get_global_security_limits());
+ Error err = Box::read(range, &box, security_limits);
if (err) {
if (err.sub_error_code == heif_suberror_End_of_data) {
return {err.error_code, err.sub_error_code, "insufficient input data"};
@@ -128,6 +152,15 @@ heif_error heif_list_compatible_brands(const uint8_t* data, int len, heif_brand2
auto brands = ftyp->list_brands();
size_t nBrands = brands.size();
+
+ if (nBrands > security_limits->max_number_of_file_brands) {
+ return {
+ heif_error_Memory_allocation_error,
+ heif_suberror_Security_limit_exceeded,
+ "File contains more brands than allowed by security limits."
+ };
+ }
+
*out_brands = (heif_brand2*) malloc(sizeof(heif_brand2) * nBrands);
*out_size = (int)nBrands;
diff --git a/libheif/box.cc b/libheif/box.cc
index a474488c..d47952ab 100644
--- a/libheif/box.cc
+++ b/libheif/box.cc
@@ -1254,6 +1254,14 @@ Error Box_ftyp::parse(BitstreamRange& range, const heif_security_limits* limits)
uint64_t n_minor_brands = (get_box_size() - get_header_size() - 8) / 4;
+ if (n_minor_brands > limits->max_number_of_file_brands) {
+ return {
+ heif_error_Memory_allocation_error,
+ heif_suberror_Security_limit_exceeded,
+ "Number of minor brands in file exceeds security limit"
+ };
+ }
+
for (uint64_t i = 0; i < n_minor_brands && !range.error(); i++) {
m_compatible_brands.push_back(range.read32());
}