Port Iptc::printStructure & getUshort to slices API

This fixes #211, #210, #209
v0.27.3
Dan Čermák 7 years ago
parent fec6535ae8
commit 962962a8e9

@ -274,7 +274,7 @@ namespace Exiv2 {
/*! /*!
@brief dump iptc formatted binary data (used by printStructure kpsRecursive) @brief dump iptc formatted binary data (used by printStructure kpsRecursive)
*/ */
static void printStructure(std::ostream& out, const byte* bytes,const size_t size,uint32_t depth); static void printStructure(std::ostream& out, const Slice<byte*>& bytes,uint32_t depth);
//@} //@}
private: private:

@ -33,6 +33,7 @@
#include "config.h" #include "config.h"
#include "slice.hpp" #include "slice.hpp"
#include "exiv2lib_export.h" #include "exiv2lib_export.h"
#include "slice.hpp"
// + standard includes // + standard includes
#include <string> #include <string>
@ -296,6 +297,17 @@ namespace Exiv2 {
//! Read a 2 byte unsigned short value from the data buffer //! Read a 2 byte unsigned short value from the data buffer
EXIV2API uint16_t getUShort(const byte* buf, ByteOrder byteOrder); EXIV2API uint16_t getUShort(const byte* buf, ByteOrder byteOrder);
//! Read a 2 byte unsigned short value from a Slice
template <typename T>
uint16_t getUShort(const Slice<T>& buf, ByteOrder byteOrder)
{
if (byteOrder == littleEndian) {
return static_cast<byte>(buf.at(1)) << 8 | static_cast<byte>(buf.at(0));
} else {
return static_cast<byte>(buf.at(0)) << 8 | static_cast<byte>(buf.at(1));
}
}
//! Read a 4 byte unsigned long value from the data buffer //! Read a 4 byte unsigned long value from the data buffer
EXIV2API uint32_t getULong(const byte* buf, ByteOrder byteOrder); EXIV2API uint32_t getULong(const byte* buf, ByteOrder byteOrder);
//! Read a 8 byte unsigned long value from the data buffer //! Read a 8 byte unsigned long value from the data buffer

@ -4,6 +4,7 @@
#include <cassert> #include <cassert>
#include <limits> #include <limits>
#include "safe_op.hpp"
#include "exif.hpp" #include "exif.hpp"
#include "error.hpp" #include "error.hpp"
#include "image_int.hpp" #include "image_int.hpp"
@ -355,13 +356,19 @@ namespace Exiv2
} }
else if ( option == kpsRecursive && tag == 0x83bb /* IPTCNAA */ ) else if ( option == kpsRecursive && tag == 0x83bb /* IPTCNAA */ )
{ {
const size_t restore = io.tell(); // save if (Safe::add(count, offset) > io.size()) {
throw Error(kerCorruptedMetadata);
}
const size_t restore = io.tell();
io.seek(offset, BasicIo::beg); // position io.seek(offset, BasicIo::beg); // position
byte* bytes=new byte[(size_t)count] ; // allocate memory std::vector<byte> bytes(count) ; // allocate memory
io.read(bytes,(long)count) ; // read // TODO: once we have C++11 use bytes.data()
io.seek(restore, BasicIo::beg); // restore const long read_bytes = io.read(&bytes[0], static_cast<long>(count));
IptcData::printStructure(out,bytes,(size_t)count,depth); io.seek(restore, BasicIo::beg);
delete[] bytes; // free // TODO: once we have C++11 use bytes.data()
IptcData::printStructure(out, makeSliceUntil(&bytes[0], read_bytes), depth);
} }
else if ( option == kpsRecursive && tag == 0x927c /* MakerNote */ && count > 10) else if ( option == kpsRecursive && tag == 0x927c /* MakerNote */ && count > 10)
{ {

@ -28,6 +28,8 @@
#include "image_int.hpp" #include "image_int.hpp"
#include "error.hpp" #include "error.hpp"
#include "futils.hpp" #include "futils.hpp"
#include "safe_op.hpp"
#include "slice.hpp"
#include "cr2image.hpp" #include "cr2image.hpp"
#include "crwimage.hpp" #include "crwimage.hpp"
@ -454,19 +456,20 @@ namespace Exiv2 {
io.seek(restore,BasicIo::beg); io.seek(restore,BasicIo::beg);
} }
} else if ( option == kpsRecursive && tag == 0x83bb /* IPTCNAA */ ) { } else if ( option == kpsRecursive && tag == 0x83bb /* IPTCNAA */ ) {
if (offset > std::numeric_limits<uint32_t>::max() - count) {
throw Error(kerArithmeticOverflow); if (static_cast<size_t>(Safe::add(count, offset)) > io.size()) {
}
if (static_cast<size_t>(offset + count) > io.size()) {
throw Error(kerCorruptedMetadata); throw Error(kerCorruptedMetadata);
} }
size_t restore = io.tell(); // save
const size_t restore = io.tell();
io.seek(offset, BasicIo::beg); // position io.seek(offset, BasicIo::beg); // position
byte* bytes=new byte[count] ; // allocate memory std::vector<byte> bytes(count) ; // allocate memory
io.read(bytes,count) ; // read // TODO: once we have C++11 use bytes.data()
io.seek(restore,BasicIo::beg); // restore const long read_bytes = io.read(&bytes[0], count);
IptcData::printStructure(out,bytes,count,depth); io.seek(restore, BasicIo::beg);
delete[] bytes; // free // TODO: once we have C++11 use bytes.data()
IptcData::printStructure(out, makeSliceUntil(&bytes[0], read_bytes), depth);
} else if ( option == kpsRecursive && tag == 0x927c /* MakerNote */ && count > 10) { } else if ( option == kpsRecursive && tag == 0x927c /* MakerNote */ && count > 10) {
size_t restore = io.tell(); // save size_t restore = io.tell(); // save

@ -347,21 +347,21 @@ namespace Exiv2 {
return iptcMetadata_.erase(pos); return iptcMetadata_.erase(pos);
} }
void IptcData::printStructure(std::ostream& out, const byte* bytes, const size_t size, uint32_t depth) void IptcData::printStructure(std::ostream& out, const Slice<byte*>& bytes, uint32_t depth)
{ {
uint32_t i = 0; uint32_t i = 0;
while (i < size - 3 && bytes[i] != 0x1c) while (i < bytes.size() - 3 && bytes.at(i) != 0x1c)
i++; i++;
depth++; depth++;
out << Internal::indent(depth) << "Record | DataSet | Name | Length | Data" << std::endl; out << Internal::indent(depth) << "Record | DataSet | Name | Length | Data" << std::endl;
while (i < size - 3) { while (i < bytes.size() - 3) {
if (bytes[i] != 0x1c) { if (bytes.at(i) != 0x1c) {
break; break;
} }
char buff[100]; char buff[100];
uint16_t record = bytes[i + 1]; uint16_t record = bytes.at(i + 1);
uint16_t dataset = bytes[i + 2]; uint16_t dataset = bytes.at(i + 2);
uint16_t len = getUShort(bytes + i + 3, bigEndian); uint16_t len = getUShort(bytes.subSlice(i + 3, bytes.size()), bigEndian);
sprintf(buff, " %6d | %7d | %-24s | %6d | ", record, dataset, sprintf(buff, " %6d | %7d | %-24s | %6d | ", record, dataset,
Exiv2::IptcDataSets::dataSetName(dataset, record).c_str(), len); Exiv2::IptcDataSets::dataSetName(dataset, record).c_str(), len);

@ -576,7 +576,7 @@ namespace Exiv2
if(bIsIPTC && bRecursive) if(bIsIPTC && bRecursive)
{ {
IptcData::printStructure(out,rawData.pData_,rawData.size_,depth); IptcData::printStructure(out, makeSlice(rawData.pData_, 0, rawData.size_), depth);
} }
if( bIsXMP && bXMP ) if( bIsXMP && bXMP )

@ -637,7 +637,7 @@ namespace Exiv2 {
throw Error(kerFailedToReadImageData); throw Error(kerFailedToReadImageData);
if (bufRead < 2) if (bufRead < 2)
throw Error(kerNotAJpeg); throw Error(kerNotAJpeg);
uint16_t size = mHasLength[marker] ? getUShort(buf.pData_, bigEndian) : 0; const uint16_t size = mHasLength[marker] ? getUShort(buf.pData_, bigEndian) : 0;
if (bPrint && mHasLength[marker]) if (bPrint && mHasLength[marker])
out << Internal::stringFormat(" | %7d ", size); out << Internal::stringFormat(" | %7d ", size);
@ -780,7 +780,7 @@ namespace Exiv2 {
} }
if (bPS) { if (bPS) {
IptcData::printStructure(out, exif, size, depth); IptcData::printStructure(out, makeSlice(exif, 0, size), depth);
} else { } else {
// create a copy on write memio object with the data, then print the structure // create a copy on write memio object with the data, then print the structure
BasicIo::AutoPtr p = BasicIo::AutoPtr(new MemIo(exif + start, size - start)); BasicIo::AutoPtr p = BasicIo::AutoPtr(new MemIo(exif + start, size - start));

@ -356,7 +356,7 @@ namespace Exiv2 {
printTiffStructure(*p,out,option,depth); printTiffStructure(*p,out,option,depth);
} }
if ( bIptc ) { if ( bIptc ) {
IptcData::printStructure(out,parsedBuf.pData_,parsedBuf.size_,depth); IptcData::printStructure(out, makeSlice(parsedBuf.pData_, 0, parsedBuf.size_), depth);
} }
} }
} }

@ -276,12 +276,7 @@ namespace Exiv2 {
uint16_t getUShort(const byte* buf, ByteOrder byteOrder) uint16_t getUShort(const byte* buf, ByteOrder byteOrder)
{ {
if (byteOrder == littleEndian) { return getUShort(makeSliceUntil(buf, 2), byteOrder);
return (byte)buf[1] << 8 | (byte)buf[0];
}
else {
return (byte)buf[0] << 8 | (byte)buf[1];
}
} }
uint32_t getULong(const byte* buf, ByteOrder byteOrder) uint32_t getULong(const byte* buf, ByteOrder byteOrder)

Loading…
Cancel
Save