From 145f41dee44664c80dfed90ad9710f9ac223a1c5 Mon Sep 17 00:00:00 2001 From: Andreas Huggel Date: Tue, 24 Jan 2006 08:58:10 +0000 Subject: [PATCH] Better handling of the header, and fixed a memory leak --- src/crwimage.cpp | 30 ++++++++++++++++++++++-------- src/crwimage.hpp | 9 ++++++++- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/crwimage.cpp b/src/crwimage.cpp index 9d3ff459..aa270cdf 100644 --- a/src/crwimage.cpp +++ b/src/crwimage.cpp @@ -284,7 +284,8 @@ namespace Exiv2 { CiffHeader::~CiffHeader() { - delete pRootDir_; + delete pRootDir_; + delete[] pPadding_; } CiffComponent::~CiffComponent() @@ -330,10 +331,16 @@ namespace Exiv2 { throw Error(33); } offset_ = getULong(pData + 2, byteOrder_); + if (offset_ < 14 || offset_ > size) throw Error(33); if (std::memcmp(pData + 6, signature(), 8) != 0) { throw Error(33); } + delete pPadding_; + pPadding_ = new byte[offset_ - 14]; + padded_ = offset_ - 14; + std::memcpy(pPadding_, pData + 14, padded_); + pRootDir_ = new CiffDirectory; pRootDir_->readDirectory(pData + offset_, size - offset_, byteOrder_); } // CiffHeader::read @@ -405,10 +412,10 @@ namespace Exiv2 { for (uint16_t i = 0; i < count; ++i) { if (o + 10 > size) throw Error(33); uint16_t tag = getUShort(pData + o, byteOrder); - AutoPtr m; + CiffComponent::AutoPtr m; switch (CiffComponent::typeId(tag)) { - case directory: m = AutoPtr(new CiffDirectory); break; - default: m = AutoPtr(new CiffEntry); break; + case directory: m = CiffComponent::AutoPtr(new CiffDirectory); break; + default: m = CiffComponent::AutoPtr(new CiffEntry); break; } m->setDir(this->tag()); m->read(pData, size, o, byteOrder); @@ -461,10 +468,16 @@ namespace Exiv2 { o += 4; append(blob, reinterpret_cast(signature_), 8); o += 8; - // Pad with 0s if needed - for (uint32_t i = o; i < offset_; ++i) { - blob.push_back(0); - ++o; + // Pad as needed + if (pPadding_) { + assert(padded_ == offset_ - o); + append(blob, pPadding_, padded_); + } + else { + for (uint32_t i = o; i < offset_; ++i) { + blob.push_back(0); + ++o; + } } if (pRootDir_) { pRootDir_->write(blob, byteOrder_, offset_); @@ -845,6 +858,7 @@ namespace Exiv2 { for (i = b; i != e; ++i) { if ((*i)->tagId() == crwTagId) { // Remove the entry and abort the loop + delete *i; components_.erase(i); break; } diff --git a/src/crwimage.hpp b/src/crwimage.hpp index 7593525d..6d48c485 100644 --- a/src/crwimage.hpp +++ b/src/crwimage.hpp @@ -586,7 +586,9 @@ namespace Exiv2 { CiffHeader() : pRootDir_ (0), byteOrder_ (littleEndian), - offset_ (0x0000001a) + offset_ (0x0000001a), + pPadding_ (0), + padded_ (0) {} //! Virtual destructor virtual ~CiffHeader(); @@ -642,6 +644,9 @@ namespace Exiv2 { /*! @brief Decode the Crw image and add it to \em image. + Walk the parse tree and convert CIFF entries to metadata + entries which are added to \em image. + @param image Image to add metadata to */ void decode(Image& image) const; @@ -668,6 +673,8 @@ namespace Exiv2 { CiffDirectory* pRootDir_; //!< Pointer to the root directory ByteOrder byteOrder_; //!< Applicable byte order uint32_t offset_; //!< Offset to the start of the root dir + byte* pPadding_; //!< Pointer to the (unknown) remainder + uint32_t padded_; //!< Number of padding-bytes }; // class CiffHeader