From 07d3f7a24b10b1bc31177cc6f3099a08fe3b851f Mon Sep 17 00:00:00 2001 From: David Houlder Date: Tue, 19 Oct 2021 22:44:55 +1100 Subject: [PATCH] Performance boost: don't read boxes we're not interested in --- src/bmffimage.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/bmffimage.cpp b/src/bmffimage.cpp index 7b53789ba0..d1a7894427 100644 --- a/src/bmffimage.cpp +++ b/src/bmffimage.cpp @@ -127,6 +127,14 @@ namespace Exiv2 return box == TAG_meta || box == TAG_iinf || box == TAG_iloc; } + static bool skipBox(uint32_t box) + { + // Allows boxHandler() to optimise the reading of files by identifying + // box types that we're not interested in. Box types listed here must + // not appear in the cases in switch (box_type) in boxHandler(). + return box == TAG_mdat; // mdat is where the main image lives and can be huge + } + std::string BmffImage::mimeType() const { switch (fileType_) { @@ -232,7 +240,18 @@ namespace Exiv2 long restore = io_->tell(); enforce(box_length >= hdrsize, Exiv2::kerCorruptedMetadata); enforce(box_length - hdrsize <= static_cast(pbox_end - restore), Exiv2::kerCorruptedMetadata); - DataBuf data(static_cast(box_length - hdrsize)); + + const long buffer_size = static_cast(box_length - hdrsize); + if (skipBox(box_type)) { + if (bTrace) { + out << std::endl; + } + // The enforce() above checks that restore + buffer_size won't + // exceed pbox_end, and by implication, won't excced LONG_MAX + return restore + buffer_size; + } + + DataBuf data(buffer_size); const long box_end = restore + data.size_; io_->read(data.pData_, data.size_); io_->seek(restore, BasicIo::beg); @@ -250,6 +269,7 @@ namespace Exiv2 } switch (box_type) { + // See notes in skipBox() case TAG_ftyp: { enforce(data.size_ >= 4, Exiv2::kerCorruptedMetadata); fileType_ = getLong(data.pData_, endian_);