diff --git a/include/exiv2/quicktimevideo.hpp b/include/exiv2/quicktimevideo.hpp index 03423db8c8..3d08a33e15 100644 --- a/include/exiv2/quicktimevideo.hpp +++ b/include/exiv2/quicktimevideo.hpp @@ -183,8 +183,10 @@ class EXIV2API QuickTimeVideo : public Image { /*! @brief Recognizes which stream is currently under processing, and save its information in currentStream_ . + @param atom_size Full size of the atom currently being processed, in bytes, + including both the atom header and its payload. */ - void setMediaStream(); + void setMediaStream(size_t atom_size); /*! @brief Used to discard a tag along with its data. The Tag will be skipped and not decoded. diff --git a/src/quicktimevideo.cpp b/src/quicktimevideo.cpp index 9418e35c1e..5cd34bb058 100644 --- a/src/quicktimevideo.cpp +++ b/src/quicktimevideo.cpp @@ -645,7 +645,7 @@ void QuickTimeVideo::tagDecoder(Exiv2::DataBuf& buf, size_t size, size_t recursi fileTypeDecoder(size); else if (equalsQTimeTag(buf, "trak")) - setMediaStream(); + setMediaStream(size); else if (equalsQTimeTag(buf, "mvhd")) movieHeaderDecoder(size); @@ -1126,13 +1126,18 @@ void QuickTimeVideo::NikonTagsDecoder(size_t size) { io_->seek(cur_pos + size, BasicIo::beg); } // QuickTimeVideo::NikonTagsDecoder -void QuickTimeVideo::setMediaStream() { +void QuickTimeVideo::setMediaStream(size_t atom_size) { size_t current_position = io_->tell(); + size_t search_end = Safe::add(current_position, atom_size); + if (search_end > io_->size()) + search_end = io_->size(); DataBuf buf(4 + 1); - while (!io_->eof()) { + while (!io_->eof() && Safe::add(io_->tell(), size_t{4}) <= search_end) { io_->readOrThrow(buf.data(), 4); if (equalsQTimeTag(buf, "hdlr")) { + if (Safe::add(io_->tell(), size_t{12}) > search_end) + break; io_->readOrThrow(buf.data(), 4); io_->readOrThrow(buf.data(), 4); io_->readOrThrow(buf.data(), 4);