Better handling of the header, and fixed a memory leak

v0.27.3
Andreas Huggel 20 years ago
parent f5bc6a420d
commit 145f41dee4

@ -285,6 +285,7 @@ namespace Exiv2 {
CiffHeader::~CiffHeader() CiffHeader::~CiffHeader()
{ {
delete pRootDir_; delete pRootDir_;
delete[] pPadding_;
} }
CiffComponent::~CiffComponent() CiffComponent::~CiffComponent()
@ -330,10 +331,16 @@ namespace Exiv2 {
throw Error(33); throw Error(33);
} }
offset_ = getULong(pData + 2, byteOrder_); offset_ = getULong(pData + 2, byteOrder_);
if (offset_ < 14 || offset_ > size) throw Error(33);
if (std::memcmp(pData + 6, signature(), 8) != 0) { if (std::memcmp(pData + 6, signature(), 8) != 0) {
throw Error(33); throw Error(33);
} }
delete pPadding_;
pPadding_ = new byte[offset_ - 14];
padded_ = offset_ - 14;
std::memcpy(pPadding_, pData + 14, padded_);
pRootDir_ = new CiffDirectory; pRootDir_ = new CiffDirectory;
pRootDir_->readDirectory(pData + offset_, size - offset_, byteOrder_); pRootDir_->readDirectory(pData + offset_, size - offset_, byteOrder_);
} // CiffHeader::read } // CiffHeader::read
@ -405,10 +412,10 @@ namespace Exiv2 {
for (uint16_t i = 0; i < count; ++i) { for (uint16_t i = 0; i < count; ++i) {
if (o + 10 > size) throw Error(33); if (o + 10 > size) throw Error(33);
uint16_t tag = getUShort(pData + o, byteOrder); uint16_t tag = getUShort(pData + o, byteOrder);
AutoPtr m; CiffComponent::AutoPtr m;
switch (CiffComponent::typeId(tag)) { switch (CiffComponent::typeId(tag)) {
case directory: m = AutoPtr(new CiffDirectory); break; case directory: m = CiffComponent::AutoPtr(new CiffDirectory); break;
default: m = AutoPtr(new CiffEntry); break; default: m = CiffComponent::AutoPtr(new CiffEntry); break;
} }
m->setDir(this->tag()); m->setDir(this->tag());
m->read(pData, size, o, byteOrder); m->read(pData, size, o, byteOrder);
@ -461,11 +468,17 @@ namespace Exiv2 {
o += 4; o += 4;
append(blob, reinterpret_cast<const byte*>(signature_), 8); append(blob, reinterpret_cast<const byte*>(signature_), 8);
o += 8; o += 8;
// Pad with 0s if needed // Pad as needed
if (pPadding_) {
assert(padded_ == offset_ - o);
append(blob, pPadding_, padded_);
}
else {
for (uint32_t i = o; i < offset_; ++i) { for (uint32_t i = o; i < offset_; ++i) {
blob.push_back(0); blob.push_back(0);
++o; ++o;
} }
}
if (pRootDir_) { if (pRootDir_) {
pRootDir_->write(blob, byteOrder_, offset_); pRootDir_->write(blob, byteOrder_, offset_);
} }
@ -845,6 +858,7 @@ namespace Exiv2 {
for (i = b; i != e; ++i) { for (i = b; i != e; ++i) {
if ((*i)->tagId() == crwTagId) { if ((*i)->tagId() == crwTagId) {
// Remove the entry and abort the loop // Remove the entry and abort the loop
delete *i;
components_.erase(i); components_.erase(i);
break; break;
} }

@ -586,7 +586,9 @@ namespace Exiv2 {
CiffHeader() CiffHeader()
: pRootDir_ (0), : pRootDir_ (0),
byteOrder_ (littleEndian), byteOrder_ (littleEndian),
offset_ (0x0000001a) offset_ (0x0000001a),
pPadding_ (0),
padded_ (0)
{} {}
//! Virtual destructor //! Virtual destructor
virtual ~CiffHeader(); virtual ~CiffHeader();
@ -642,6 +644,9 @@ namespace Exiv2 {
/*! /*!
@brief Decode the Crw image and add it to \em image. @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 @param image Image to add metadata to
*/ */
void decode(Image& image) const; void decode(Image& image) const;
@ -668,6 +673,8 @@ namespace Exiv2 {
CiffDirectory* pRootDir_; //!< Pointer to the root directory CiffDirectory* pRootDir_; //!< Pointer to the root directory
ByteOrder byteOrder_; //!< Applicable byte order ByteOrder byteOrder_; //!< Applicable byte order
uint32_t offset_; //!< Offset to the start of the root dir 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 }; // class CiffHeader

Loading…
Cancel
Save