Remove DataBuf::copyBytes and use std::copy instead

This commit is contained in:
Luis Díaz Más 2022-03-22 18:07:25 +01:00
parent c5c315b6e7
commit ae4df71233
19 changed files with 98 additions and 104 deletions

View File

@ -171,12 +171,12 @@ int setModeAndPrintStructure(Exiv2::PrintStructureOption option, const std::stri
std::stringstream output(std::stringstream::out | std::stringstream::binary); std::stringstream output(std::stringstream::out | std::stringstream::binary);
result = printStructure(output, option, path); result = printStructure(output, option, path);
if (result == 0) { if (result == 0) {
size_t size = output.str().size(); std::string str = output.str();
Exiv2::DataBuf iccProfile(size); Exiv2::DataBuf iccProfile(str.size());
Exiv2::DataBuf ascii(size * 3 + 1); Exiv2::DataBuf ascii(str.size() * 3 + 1);
ascii.write_uint8(size * 3, 0); ascii.write_uint8(str.size() * 3, 0);
iccProfile.copyBytes(0, output.str().c_str(), size); std::copy(str.begin(), str.end(), iccProfile.begin());
if (Exiv2::base64encode(iccProfile.c_data(), size, reinterpret_cast<char*>(ascii.data()), size * 3)) { if (Exiv2::base64encode(iccProfile.c_data(), str.size(), reinterpret_cast<char*>(ascii.data()), str.size() * 3)) {
long chunk = 60; long chunk = 60;
std::string code = std::string("data:") + ascii.c_str(); std::string code = std::string("data:") + ascii.c_str();
size_t length = code.size(); size_t length = code.size();

View File

@ -12,6 +12,7 @@
#include "i18n.h" // NLS support. #include "i18n.h" // NLS support.
#include "xmp_exiv2.hpp" #include "xmp_exiv2.hpp"
#include <algorithm>
#include <cctype> #include <cctype>
#include <cstring> #include <cstring>
#include <fstream> #include <fstream>
@ -941,20 +942,20 @@ static int readFileToBuf(FILE* f, Exiv2::DataBuf& buf) {
std::vector<Exiv2::byte> bytes(buff_size); std::vector<Exiv2::byte> bytes(buff_size);
int nBytes = 0; int nBytes = 0;
bool more{true}; bool more{true};
std::array<char, buff_size> buff;
while (more) { while (more) {
char buff[buff_size]; auto n = fread(buff.data(), 1, buff_size, f);
auto n = static_cast<int>(fread(buff, 1, buff_size, f));
more = n > 0; more = n > 0;
if (more) { if (more) {
bytes.resize(nBytes + n); bytes.resize(nBytes + n);
memcpy(bytes.data() + nBytes, buff, n); std::copy_n(buff.begin(), n, bytes.begin() + nBytes);
nBytes += n; nBytes += n;
} }
} }
if (nBytes) { if (nBytes) {
buf.alloc(nBytes); buf.alloc(nBytes);
buf.copyBytes(0, bytes.data(), nBytes); std::copy(bytes.begin(), bytes.end(), buf.begin());
} }
return nBytes; return nBytes;
} }
@ -1004,7 +1005,7 @@ void Params::getStdin(Exiv2::DataBuf& buf) {
// copy stdinBuf to buf // copy stdinBuf to buf
if (!stdinBuf.empty()) { if (!stdinBuf.empty()) {
buf.alloc(stdinBuf.size()); buf.alloc(stdinBuf.size());
buf.copyBytes(0, stdinBuf.c_data(), buf.size()); std::copy(stdinBuf.begin(), stdinBuf.end(), buf.begin());
} }
#ifdef DEBUG #ifdef DEBUG
std::cerr << "getStdin stdinBuf.size_ = " << stdinBuf.size() << std::endl; std::cerr << "getStdin stdinBuf.size_ = " << stdinBuf.size() << std::endl;

View File

@ -198,9 +198,6 @@ struct EXIV2API DataBuf {
uint64_t read_uint64(size_t offset, ByteOrder byteOrder) const; uint64_t read_uint64(size_t offset, ByteOrder byteOrder) const;
void write_uint64(size_t offset, uint64_t x, ByteOrder byteOrder); void write_uint64(size_t offset, uint64_t x, ByteOrder byteOrder);
//! Copy bytes into the buffer (starting at address &pData_[offset]).
void copyBytes(size_t offset, const void* buf, size_t bufsize);
//! Equivalent to: memcmp(&pData_[offset], buf, bufsize) //! Equivalent to: memcmp(&pData_[offset], buf, bufsize)
int cmpBytes(size_t offset, const void* buf, size_t bufsize) const; int cmpBytes(size_t offset, const void* buf, size_t bufsize) const;

View File

@ -10,10 +10,10 @@
#include "types.hpp" #include "types.hpp"
// + standard includes // + standard includes
#include <cmath>
#include <cstring> #include <cstring>
#include <iomanip> #include <iomanip>
#include <map> #include <map>
#include <cmath>
// ***************************************************************************** // *****************************************************************************
// namespace extensions // namespace extensions

View File

@ -28,13 +28,16 @@ int main(int argc, char* const argv[]) {
} }
// Map it to memory // Map it to memory
const Exiv2::byte* pData = file.mmap(); const Exiv2::byte* pData = file.mmap();
DataBuf buf(file.size()); std::vector<byte> buf(file.size());
// Read from the memory mapped region // Read from the memory mapped region
buf.copyBytes(0, pData, buf.size()); std::copy_n(pData, buf.size(), buf.begin());
// Reopen file in write mode and write to it // Reopen file in write mode and write to it
file.write(buf.c_data(), buf.size()); file.write(buf.data(), buf.size());
// Read from the mapped region again // Read from the mapped region again
buf.copyBytes(0, pData, buf.size()); std::copy_n(pData, buf.size(), buf.begin());
file.close(); file.close();
return EXIT_SUCCESS; return EXIT_SUCCESS;

View File

@ -44,7 +44,7 @@ DataBuf Cr2Header::write() const {
buf.write_uint16(2, tag(), byteOrder()); buf.write_uint16(2, tag(), byteOrder());
buf.write_uint32(4, 0x00000010, byteOrder()); buf.write_uint32(4, 0x00000010, byteOrder());
buf.copyBytes(8, cr2sig_, 4); std::copy_n(cr2sig_, 4, buf.begin() + 8);
// Write a dummy value for the RAW IFD offset. The offset-writer is used to set this offset in a second pass. // Write a dummy value for the RAW IFD offset. The offset-writer is used to set this offset in a second pass.
buf.write_uint32(12, 0x00000000, byteOrder()); buf.write_uint32(12, 0x00000000, byteOrder());
return buf; return buf;

View File

@ -874,7 +874,7 @@ void CrwMap::encode0x0805(const Image& image, const CrwMapping* pCrwMapping, Cif
if (cc && cc->size() > size) if (cc && cc->size() > size)
size = cc->size(); size = cc->size();
DataBuf buf(size); DataBuf buf(size);
buf.copyBytes(0, comment.data(), comment.size()); std::copy(comment.begin(), comment.end(), buf.begin());
pHead->add(pCrwMapping->crwTagId_, pCrwMapping->crwDir_, std::move(buf)); pHead->add(pCrwMapping->crwTagId_, pCrwMapping->crwDir_, std::move(buf));
} else { } else {
if (cc) { if (cc) {
@ -984,7 +984,7 @@ void CrwMap::encode0x1810(const Image& image, const CrwMapping* pCrwMapping, Cif
} }
DataBuf buf(size); DataBuf buf(size);
if (cc) if (cc)
buf.copyBytes(8, cc->pData() + 8, cc->size() - 8); std::copy_n(cc->pData() + 8, cc->size() - 8, buf.begin() + 8);
if (edX != edEnd && edX->size() == 4) { if (edX != edEnd && edX->size() == 4) {
edX->copy(buf.data(), pHead->byteOrder()); edX->copy(buf.data(), pHead->byteOrder());
} }

View File

@ -361,8 +361,8 @@ void Image::printIFDStructure(BasicIo& io, std::ostream& out, Exiv2::PrintStruct
} }
// Overflow check // Overflow check
enforce(allocate64 <= std::numeric_limits<size_t>::max(), ErrorCode::kerCorruptedMetadata); enforce(allocate64 <= std::numeric_limits<size_t>::max(), ErrorCode::kerCorruptedMetadata);
DataBuf buf(allocate64); // allocate a buffer DataBuf buf(allocate64); // allocate a buffer
buf.copyBytes(0, dir.c_data(8), 4); // copy dir[8:11] into buffer (short strings) std::copy_n(dir.c_data(8), 4, buf.begin()); // copy dir[8:11] into buffer (short strings)
// We have already checked that this multiplication cannot overflow. // We have already checked that this multiplication cannot overflow.
const size_t count_x_size = count * size; const size_t count_x_size = count * size;

View File

@ -25,7 +25,7 @@ std::string stringFormat(const char* format, ...) {
va_list args; // variable arg list va_list args; // variable arg list
va_start(args, format); // args start after format va_start(args, format); // args start after format
rc = vsnprintf(&buffer[0], buffer.size(), format, args); rc = vsnprintf(&buffer[0], buffer.size(), format, args);
va_end(args); // free the args va_end(args); // free the args
if (rc > 0) if (rc > 0)
need = static_cast<size_t>(rc); need = static_cast<size_t>(rc);
} while (buffer.size() <= need); } while (buffer.size() <= need);

View File

@ -16,6 +16,7 @@
#include "tiffimage.hpp" #include "tiffimage.hpp"
#include "types.hpp" #include "types.hpp"
#include <algorithm>
#include <array> #include <array>
#include <iostream> #include <iostream>
@ -224,7 +225,7 @@ void Jp2Image::readMetadata() {
throw Error(ErrorCode::kerCorruptedMetadata); throw Error(ErrorCode::kerCorruptedMetadata);
} }
DataBuf icc(iccLength); DataBuf icc(iccLength);
icc.copyBytes(0, data.c_data(pad), icc.size()); std::copy_n(data.c_data(pad), icc.size(), icc.begin());
#ifdef EXIV2_DEBUG_MESSAGES #ifdef EXIV2_DEBUG_MESSAGES
const char* iccPath = "/tmp/libexiv2_jp2.icc"; const char* iccPath = "/tmp/libexiv2_jp2.icc";
FILE* f = fopen(iccPath, "wb"); FILE* f = fopen(iccPath, "wb");
@ -645,8 +646,8 @@ void Jp2Image::encodeJp2Header(const DataBuf& boxBuf, DataBuf& outBuf) {
enforce(newlen <= output.size() - outlen, ErrorCode::kerCorruptedMetadata); enforce(newlen <= output.size() - outlen, ErrorCode::kerCorruptedMetadata);
ul2Data(reinterpret_cast<byte*>(&newBox.length), psize, bigEndian); ul2Data(reinterpret_cast<byte*>(&newBox.length), psize, bigEndian);
ul2Data(reinterpret_cast<byte*>(&newBox.type), newBox.type, bigEndian); ul2Data(reinterpret_cast<byte*>(&newBox.type), newBox.type, bigEndian);
output.copyBytes(outlen, &newBox, sizeof(newBox)); std::copy_n(reinterpret_cast<char*>(&newBox), sizeof(newBox), output.begin() + outlen);
output.copyBytes(outlen + sizeof(newBox), pad, psize); std::copy_n(pad, psize, output.begin() + outlen + sizeof(newBox));
} else { } else {
const char* pad = "\x02\x00\x00"; const char* pad = "\x02\x00\x00";
uint32_t psize = 3; uint32_t psize = 3;
@ -654,13 +655,13 @@ void Jp2Image::encodeJp2Header(const DataBuf& boxBuf, DataBuf& outBuf) {
enforce(newlen <= output.size() - outlen, ErrorCode::kerCorruptedMetadata); enforce(newlen <= output.size() - outlen, ErrorCode::kerCorruptedMetadata);
ul2Data(reinterpret_cast<byte*>(&newBox.length), static_cast<uint32_t>(newlen), bigEndian); ul2Data(reinterpret_cast<byte*>(&newBox.length), static_cast<uint32_t>(newlen), bigEndian);
ul2Data(reinterpret_cast<byte*>(&newBox.type), newBox.type, bigEndian); ul2Data(reinterpret_cast<byte*>(&newBox.type), newBox.type, bigEndian);
output.copyBytes(outlen, &newBox, sizeof(newBox)); std::copy_n(reinterpret_cast<char*>(&newBox), sizeof(newBox), output.begin() + outlen);
output.copyBytes(outlen + sizeof(newBox), pad, psize); std::copy_n(pad, psize, output.begin() + outlen + sizeof(newBox));
output.copyBytes(outlen + sizeof(newBox) + psize, iccProfile_.c_data(), iccProfile_.size()); std::copy(iccProfile_.begin(), iccProfile_.end(), output.begin() + outlen + sizeof(newBox) + psize);
} }
} else { } else {
enforce(newlen <= output.size() - outlen, ErrorCode::kerCorruptedMetadata); enforce(newlen <= output.size() - outlen, ErrorCode::kerCorruptedMetadata);
output.copyBytes(outlen, boxBuf.c_data(inlen), subBox.length); std::copy_n(boxBuf.c_data(inlen), subBox.length, output.begin() + outlen);
} }
outlen += newlen; outlen += newlen;
@ -669,7 +670,7 @@ void Jp2Image::encodeJp2Header(const DataBuf& boxBuf, DataBuf& outBuf) {
// allocate the correct number of bytes, copy the data and update the box header // allocate the correct number of bytes, copy the data and update the box header
outBuf.alloc(outlen); outBuf.alloc(outlen);
outBuf.copyBytes(0, output.c_data(), outlen); std::copy_n(output.c_data(), outlen, outBuf.begin());
auto oBox = reinterpret_cast<Internal::Jp2BoxHeader*>(outBuf.data()); auto oBox = reinterpret_cast<Internal::Jp2BoxHeader*>(outBuf.data());
ul2Data(reinterpret_cast<byte*>(&oBox->type), kJp2BoxTypeHeader, bigEndian); ul2Data(reinterpret_cast<byte*>(&oBox->type), kJp2BoxTypeHeader, bigEndian);
ul2Data(reinterpret_cast<byte*>(&oBox->length), static_cast<uint32_t>(outlen), bigEndian); ul2Data(reinterpret_cast<byte*>(&oBox->length), static_cast<uint32_t>(outlen), bigEndian);
@ -743,8 +744,8 @@ void Jp2Image::doWriteMetadata(BasicIo& outIo) {
enforce(box.length - 8 <= static_cast<size_t>(io_->size() - io_->tell()), ErrorCode::kerCorruptedMetadata); enforce(box.length - 8 <= static_cast<size_t>(io_->size() - io_->tell()), ErrorCode::kerCorruptedMetadata);
// Read whole box : Box header + Box data (not fixed size - can be null). // Read whole box : Box header + Box data (not fixed size - can be null).
DataBuf boxBuf(box.length); // Box header (8 bytes) + box data. DataBuf boxBuf(box.length); // Box header (8 bytes) + box data.
boxBuf.copyBytes(0, bheaderBuf.c_data(), 8); // Copy header. std::copy_n(bheaderBuf.begin(), 8, boxBuf.begin()); // Copy header.
io_->readOrThrow(boxBuf.data(8), box.length - 8, ErrorCode::kerInputDataReadFailed); // Extract box data. io_->readOrThrow(boxBuf.data(8), box.length - 8, ErrorCode::kerInputDataReadFailed); // Extract box data.
switch (box.type) { switch (box.type) {
@ -767,15 +768,15 @@ void Jp2Image::doWriteMetadata(BasicIo& outIo) {
ExifParser::encode(blob, littleEndian, exifData_); ExifParser::encode(blob, littleEndian, exifData_);
if (!blob.empty()) { if (!blob.empty()) {
DataBuf rawExif(blob.size()); DataBuf rawExif(blob.size());
rawExif.copyBytes(0, &blob[0], blob.size()); std::copy(blob.begin(), blob.end(), rawExif.begin());
DataBuf boxData(8 + 16 + rawExif.size()); DataBuf boxData(8 + 16 + rawExif.size());
ul2Data(boxDataSize, static_cast<uint32_t>(boxData.size()), bigEndian); ul2Data(boxDataSize, static_cast<uint32_t>(boxData.size()), bigEndian);
ul2Data(boxUUIDtype, kJp2BoxTypeUuid, bigEndian); ul2Data(boxUUIDtype, kJp2BoxTypeUuid, bigEndian);
boxData.copyBytes(0, boxDataSize, 4); std::copy_n(boxDataSize, 4, boxData.begin());
boxData.copyBytes(4, boxUUIDtype, 4); std::copy_n(boxUUIDtype, 4, boxData.begin() + 4);
boxData.copyBytes(8, kJp2UuidExif, 16); std::copy_n(kJp2UuidExif, 16, boxData.begin() + 8);
boxData.copyBytes(8 + 16, rawExif.c_data(), rawExif.size()); std::copy(rawExif.begin(), rawExif.end(), boxData.begin() + 8 + 16);
#ifdef EXIV2_DEBUG_MESSAGES #ifdef EXIV2_DEBUG_MESSAGES
std::cout << "Exiv2::Jp2Image::doWriteMetadata: Write box with Exif metadata (length: " << boxData.size() std::cout << "Exiv2::Jp2Image::doWriteMetadata: Write box with Exif metadata (length: " << boxData.size()
@ -794,10 +795,10 @@ void Jp2Image::doWriteMetadata(BasicIo& outIo) {
DataBuf boxData(8 + 16 + rawIptc.size()); DataBuf boxData(8 + 16 + rawIptc.size());
ul2Data(boxDataSize, static_cast<uint32_t>(boxData.size()), bigEndian); ul2Data(boxDataSize, static_cast<uint32_t>(boxData.size()), bigEndian);
ul2Data(boxUUIDtype, kJp2BoxTypeUuid, bigEndian); ul2Data(boxUUIDtype, kJp2BoxTypeUuid, bigEndian);
boxData.copyBytes(0, boxDataSize, 4); std::copy_n(boxDataSize, 4, boxData.begin());
boxData.copyBytes(4, boxUUIDtype, 4); std::copy_n(boxUUIDtype, 4, boxData.begin() + 4);
boxData.copyBytes(8, kJp2UuidIptc, 16); std::copy_n(kJp2UuidExif, 16, boxData.begin() + 8);
boxData.copyBytes(8 + 16, rawIptc.c_data(), rawIptc.size()); std::copy(rawIptc.begin(), rawIptc.end(), boxData.begin() + 8 + 16);
#ifdef EXIV2_DEBUG_MESSAGES #ifdef EXIV2_DEBUG_MESSAGES
std::cout << "Exiv2::Jp2Image::doWriteMetadata: Write box with Iptc metadata (length: " << boxData.size() std::cout << "Exiv2::Jp2Image::doWriteMetadata: Write box with Iptc metadata (length: " << boxData.size()
@ -822,10 +823,10 @@ void Jp2Image::doWriteMetadata(BasicIo& outIo) {
DataBuf boxData(8 + 16 + xmp.size()); DataBuf boxData(8 + 16 + xmp.size());
ul2Data(boxDataSize, static_cast<uint32_t>(boxData.size()), bigEndian); ul2Data(boxDataSize, static_cast<uint32_t>(boxData.size()), bigEndian);
ul2Data(boxUUIDtype, kJp2BoxTypeUuid, bigEndian); ul2Data(boxUUIDtype, kJp2BoxTypeUuid, bigEndian);
boxData.copyBytes(0, boxDataSize, 4); std::copy_n(boxDataSize, 4, boxData.begin());
boxData.copyBytes(4, boxUUIDtype, 4); std::copy_n(boxUUIDtype, 4, boxData.begin() + 4);
boxData.copyBytes(8, kJp2UuidXmp, 16); std::copy_n(kJp2UuidExif, 16, boxData.begin() + 8);
boxData.copyBytes(8 + 16, xmp.c_data(), xmp.size()); std::copy(xmp.begin(), xmp.end(), boxData.begin() + 8 + 16);
#ifdef EXIV2_DEBUG_MESSAGES #ifdef EXIV2_DEBUG_MESSAGES
std::cout << "Exiv2::Jp2Image::doWriteMetadata: Write box with XMP metadata (length: " << boxData.size() std::cout << "Exiv2::Jp2Image::doWriteMetadata: Write box with XMP metadata (length: " << boxData.size()

View File

@ -272,11 +272,11 @@ void JpegBase::readMetadata() {
while (marker != sos_ && marker != eoi_ && search > 0) { while (marker != sos_ && marker != eoi_ && search > 0) {
// 2-byte buffer for reading the size. // 2-byte buffer for reading the size.
byte sizebuf[2]; std::array<byte, 2> sizebuf;
uint16_t size = 0; // Size of the segment, including the 2-byte size field uint16_t size = 0; // Size of the segment, including the 2-byte size field
if (markerHasLength(marker)) { if (markerHasLength(marker)) {
io_->readOrThrow(sizebuf, 2, ErrorCode::kerFailedToReadImageData); io_->readOrThrow(sizebuf.data(), sizebuf.size(), ErrorCode::kerFailedToReadImageData);
size = getUShort(sizebuf, bigEndian); size = getUShort(sizebuf.data(), bigEndian);
enforce(size >= 2, ErrorCode::kerFailedToReadImageData); enforce(size >= 2, ErrorCode::kerFailedToReadImageData);
} }
@ -285,7 +285,7 @@ void JpegBase::readMetadata() {
/// \todo check if it makes sense to check for size /// \todo check if it makes sense to check for size
if (size > 0) { if (size > 0) {
io_->readOrThrow(buf.data(2), size - 2, ErrorCode::kerFailedToReadImageData); io_->readOrThrow(buf.data(2), size - 2, ErrorCode::kerFailedToReadImageData);
buf.copyBytes(0, sizebuf, 2); std::copy(sizebuf.begin(), sizebuf.end(), buf.begin());
} }
if (!foundExifData && marker == app1_ && size >= 8 // prevent out-of-bounds read in memcmp on next line if (!foundExifData && marker == app1_ && size >= 8 // prevent out-of-bounds read in memcmp on next line
@ -363,9 +363,9 @@ void JpegBase::readMetadata() {
DataBuf profile(Safe::add(iccProfile_.size(), icc_size)); DataBuf profile(Safe::add(iccProfile_.size(), icc_size));
if (!iccProfile_.empty()) { if (!iccProfile_.empty()) {
profile.copyBytes(0, iccProfile_.c_data(), iccProfile_.size()); std::copy(iccProfile_.begin(), iccProfile_.end(), profile.begin());
} }
profile.copyBytes(iccProfile_.size(), buf.c_data(2 + 14), icc_size); std::copy_n(buf.c_data(2 + 14), icc_size, profile.data() + iccProfile_.size());
setIccProfile(std::move(profile), chunk == chunks); setIccProfile(std::move(profile), chunk == chunks);
} else if (pixelHeight_ == 0 && inRange2(marker, sof0_, sof3_, sof5_, sof15_)) { } else if (pixelHeight_ == 0 && inRange2(marker, sof0_, sof3_, sof5_, sof15_)) {
// We hit a SOFn (start-of-frame) marker // We hit a SOFn (start-of-frame) marker
@ -479,11 +479,11 @@ void JpegBase::printStructure(std::ostream& out, PrintStructureOption option, in
bool bLF = bPrint; bool bLF = bPrint;
// 2-byte buffer for reading the size. // 2-byte buffer for reading the size.
byte sizebuf[2]; std::array<byte, 2> sizebuf;
uint16_t size = 0; uint16_t size = 0;
if (markerHasLength(marker)) { if (markerHasLength(marker)) {
io_->readOrThrow(sizebuf, 2, ErrorCode::kerFailedToReadImageData); io_->readOrThrow(sizebuf.data(), sizebuf.size(), ErrorCode::kerFailedToReadImageData);
size = getUShort(sizebuf, bigEndian); size = getUShort(sizebuf.data(), bigEndian);
// `size` is the size of the segment, including the 2-byte size field // `size` is the size of the segment, including the 2-byte size field
// that we just read. // that we just read.
enforce(size >= 2, ErrorCode::kerFailedToReadImageData); enforce(size >= 2, ErrorCode::kerFailedToReadImageData);
@ -493,7 +493,7 @@ void JpegBase::printStructure(std::ostream& out, PrintStructureOption option, in
DataBuf buf(size); DataBuf buf(size);
if (size > 0) { if (size > 0) {
io_->readOrThrow(buf.data(2), size - 2, ErrorCode::kerFailedToReadImageData); io_->readOrThrow(buf.data(2), size - 2, ErrorCode::kerFailedToReadImageData);
buf.copyBytes(0, sizebuf, 2); std::copy(sizebuf.begin(), sizebuf.end(), buf.begin());
} }
if (bPrint && markerHasLength(marker)) if (bPrint && markerHasLength(marker))
@ -732,11 +732,11 @@ void JpegBase::writeMetadata() {
DataBuf JpegBase::readNextSegment(byte marker) { DataBuf JpegBase::readNextSegment(byte marker) {
// 2-byte buffer for reading the size. // 2-byte buffer for reading the size.
byte sizebuf[2]; std::array<byte, 2> sizebuf;
uint16_t size = 0; uint16_t size = 0;
if (markerHasLength(marker)) { if (markerHasLength(marker)) {
io_->readOrThrow(sizebuf, 2, ErrorCode::kerFailedToReadImageData); io_->readOrThrow(sizebuf.data(), sizebuf.size(), ErrorCode::kerFailedToReadImageData);
size = getUShort(sizebuf, bigEndian); size = getUShort(sizebuf.data(), bigEndian);
// `size` is the size of the segment, including the 2-byte size field // `size` is the size of the segment, including the 2-byte size field
// that we just read. // that we just read.
enforce(size >= 2, ErrorCode::kerFailedToReadImageData); enforce(size >= 2, ErrorCode::kerFailedToReadImageData);
@ -746,7 +746,7 @@ DataBuf JpegBase::readNextSegment(byte marker) {
DataBuf buf(size); DataBuf buf(size);
if (size > 0) { if (size > 0) {
io_->readOrThrow(buf.data(2), size - 2, ErrorCode::kerFailedToReadImageData); io_->readOrThrow(buf.data(2), size - 2, ErrorCode::kerFailedToReadImageData);
buf.copyBytes(0, sizebuf, 2); std::copy(sizebuf.begin(), sizebuf.end(), buf.begin());
} }
return buf; return buf;
} }
@ -805,7 +805,7 @@ void JpegBase::doWriteMetadata(BasicIo& outIo) {
++search; ++search;
if (buf.size() > 8) { if (buf.size() > 8) {
rawExif.alloc(buf.size() - 8); rawExif.alloc(buf.size() - 8);
rawExif.copyBytes(0, buf.c_data(8), buf.size() - 8); std::copy_n(buf.c_data(8), rawExif.size(), rawExif.begin());
} }
} else if (skipApp1Xmp == notfound && marker == app1_ && } else if (skipApp1Xmp == notfound && marker == app1_ &&
buf.size() >= 31 && // prevent out-of-bounds read in memcmp on next line buf.size() >= 31 && // prevent out-of-bounds read in memcmp on next line

View File

@ -188,7 +188,7 @@ bool OlympusMnHeader::read(const byte* pData, size_t size, ByteOrder /*byteOrder
if (!pData || size < sizeOfSignature()) if (!pData || size < sizeOfSignature())
return false; return false;
header_.alloc(sizeOfSignature()); header_.alloc(sizeOfSignature());
header_.copyBytes(0, pData, header_.size()); std::copy_n(pData, header_.size(), header_.data());
return !(header_.size() < sizeOfSignature() || 0 != header_.cmpBytes(0, signature_, 6)); return !(header_.size() < sizeOfSignature() || 0 != header_.cmpBytes(0, signature_, 6));
} }
@ -223,7 +223,7 @@ bool Olympus2MnHeader::read(const byte* pData, size_t size, ByteOrder /*byteOrde
if (!pData || size < sizeOfSignature()) if (!pData || size < sizeOfSignature())
return false; return false;
header_.alloc(sizeOfSignature()); header_.alloc(sizeOfSignature());
header_.copyBytes(0, pData, header_.size()); std::copy_n(pData, header_.size(), header_.data());
return !(header_.size() < sizeOfSignature() || 0 != header_.cmpBytes(0, signature_, 10)); return !(header_.size() < sizeOfSignature() || 0 != header_.cmpBytes(0, signature_, 10));
} }
@ -263,7 +263,7 @@ bool FujiMnHeader::read(const byte* pData, size_t size, ByteOrder /*byteOrder*/)
if (!pData || size < sizeOfSignature()) if (!pData || size < sizeOfSignature())
return false; return false;
header_.alloc(sizeOfSignature()); header_.alloc(sizeOfSignature());
header_.copyBytes(0, pData, header_.size()); std::copy_n(pData, header_.size(), header_.data());
// Read offset to the IFD relative to the start of the makernote // Read offset to the IFD relative to the start of the makernote
// from the header. Note that we ignore the byteOrder argument // from the header. Note that we ignore the byteOrder argument
start_ = header_.read_uint32(8, byteOrder_); start_ = header_.read_uint32(8, byteOrder_);
@ -299,7 +299,7 @@ bool Nikon2MnHeader::read(const byte* pData, size_t size, ByteOrder /*byteOrder*
if (0 != memcmp(pData, signature_, 6)) if (0 != memcmp(pData, signature_, 6))
return false; return false;
buf_.alloc(sizeOfSignature()); buf_.alloc(sizeOfSignature());
buf_.copyBytes(0, pData, buf_.size()); std::copy_n(pData, buf_.size(), buf_.data());
start_ = sizeOfSignature(); start_ = sizeOfSignature();
return true; return true;
} // Nikon2MnHeader::read } // Nikon2MnHeader::read
@ -318,7 +318,7 @@ size_t Nikon3MnHeader::sizeOfSignature() {
Nikon3MnHeader::Nikon3MnHeader() : byteOrder_(invalidByteOrder), start_(sizeOfSignature()) { Nikon3MnHeader::Nikon3MnHeader() : byteOrder_(invalidByteOrder), start_(sizeOfSignature()) {
buf_.alloc(sizeOfSignature()); buf_.alloc(sizeOfSignature());
buf_.copyBytes(0, signature_, buf_.size()); std::copy_n(signature_, buf_.size(), buf_.data());
} }
size_t Nikon3MnHeader::size() const { size_t Nikon3MnHeader::size() const {
@ -343,7 +343,7 @@ bool Nikon3MnHeader::read(const byte* pData, size_t size, ByteOrder /*byteOrder*
if (0 != memcmp(pData, signature_, 6)) if (0 != memcmp(pData, signature_, 6))
return false; return false;
buf_.alloc(sizeOfSignature()); buf_.alloc(sizeOfSignature());
buf_.copyBytes(0, pData, buf_.size()); std::copy_n(pData, buf_.size(), buf_.data());
TiffHeader th; TiffHeader th;
if (!th.read(buf_.data(10), 8)) if (!th.read(buf_.data(10), 8))
return false; return false;
@ -389,7 +389,7 @@ bool PanasonicMnHeader::read(const byte* pData, size_t size, ByteOrder /*byteOrd
if (0 != memcmp(pData, signature_, 9)) if (0 != memcmp(pData, signature_, 9))
return false; return false;
buf_.alloc(sizeOfSignature()); buf_.alloc(sizeOfSignature());
buf_.copyBytes(0, pData, buf_.size()); std::copy_n(pData, buf_.size(), buf_.data());
start_ = sizeOfSignature(); start_ = sizeOfSignature();
return true; return true;
} // PanasonicMnHeader::read } // PanasonicMnHeader::read
@ -425,7 +425,7 @@ bool PentaxDngMnHeader::read(const byte* pData, size_t size, ByteOrder /*byteOrd
if (!pData || size < sizeOfSignature()) if (!pData || size < sizeOfSignature())
return false; return false;
header_.alloc(sizeOfSignature()); header_.alloc(sizeOfSignature());
header_.copyBytes(0, pData, header_.size()); std::copy_n(pData, header_.size(), header_.data());
return !(header_.size() < sizeOfSignature() || 0 != header_.cmpBytes(0, signature_, 7)); return !(header_.size() < sizeOfSignature() || 0 != header_.cmpBytes(0, signature_, 7));
} }
@ -456,7 +456,7 @@ bool PentaxMnHeader::read(const byte* pData, size_t size, ByteOrder /*byteOrder*
if (!pData || size < sizeOfSignature()) if (!pData || size < sizeOfSignature())
return false; return false;
header_.alloc(sizeOfSignature()); header_.alloc(sizeOfSignature());
header_.copyBytes(0, pData, header_.size()); std::copy_n(pData, header_.size(), header_.data());
return !(header_.size() < sizeOfSignature() || 0 != header_.cmpBytes(0, signature_, 3)); return !(header_.size() < sizeOfSignature() || 0 != header_.cmpBytes(0, signature_, 3));
} }
@ -510,7 +510,7 @@ bool SigmaMnHeader::read(const byte* pData, size_t size, ByteOrder /*byteOrder*/
if (0 != memcmp(pData, signature1_, 8) && 0 != memcmp(pData, signature2_, 8)) if (0 != memcmp(pData, signature1_, 8) && 0 != memcmp(pData, signature2_, 8))
return false; return false;
buf_.alloc(sizeOfSignature()); buf_.alloc(sizeOfSignature());
buf_.copyBytes(0, pData, buf_.size()); std::copy_n(pData, buf_.size(), buf_.data());
start_ = sizeOfSignature(); start_ = sizeOfSignature();
return true; return true;
} // SigmaMnHeader::read } // SigmaMnHeader::read
@ -544,7 +544,7 @@ bool SonyMnHeader::read(const byte* pData, size_t size, ByteOrder /*byteOrder*/)
if (0 != memcmp(pData, signature_, sizeOfSignature())) if (0 != memcmp(pData, signature_, sizeOfSignature()))
return false; return false;
buf_.alloc(sizeOfSignature()); buf_.alloc(sizeOfSignature());
buf_.copyBytes(0, pData, buf_.size()); std::copy_n(pData, buf_.size(), buf_.data());
start_ = sizeOfSignature(); start_ = sizeOfSignature();
return true; return true;
} // SonyMnHeader::read } // SonyMnHeader::read
@ -583,7 +583,7 @@ bool Casio2MnHeader::read(const byte* pData, size_t size, ByteOrder /*byteOrder*
if (0 != memcmp(pData, signature_, sizeOfSignature())) if (0 != memcmp(pData, signature_, sizeOfSignature()))
return false; return false;
buf_.alloc(sizeOfSignature()); buf_.alloc(sizeOfSignature());
buf_.copyBytes(0, pData, buf_.size()); std::copy_n(pData, buf_.size(), buf_.data());
start_ = sizeOfSignature(); start_ = sizeOfSignature();
return true; return true;
} // Casio2MnHeader::read } // Casio2MnHeader::read
@ -891,7 +891,7 @@ DataBuf nikonCrypt(uint16_t tag, const byte* pData, size_t size, TiffComponent*
} }
} }
buf.alloc(size); buf.alloc(size);
buf.copyBytes(0, pData, buf.size()); std::copy_n(pData, buf.size(), buf.data());
ncrypt(buf.data(nci->start_), static_cast<uint32_t>(buf.size()) - nci->start_, count, serial); ncrypt(buf.data(nci->start_), static_cast<uint32_t>(buf.size()) - nci->start_, count, serial);
return buf; return buf;
} }

View File

@ -180,7 +180,7 @@ void PgfImage::doWriteMetadata(BasicIo& outIo) {
// Write new Header size. // Write new Header size.
uint32_t newHeaderSize = static_cast<uint32_t>(header.size() + imgSize); uint32_t newHeaderSize = static_cast<uint32_t>(header.size() + imgSize);
DataBuf buffer(4); DataBuf buffer(4);
buffer.copyBytes(0, &newHeaderSize, 4); std::copy_n(&newHeaderSize, 4, buffer.data());
byteSwap_(buffer, 0, bSwap_); byteSwap_(buffer, 0, bSwap_);
if (outIo.write(buffer.c_data(), 4) != 4) if (outIo.write(buffer.c_data(), 4) != 4)
throw Error(ErrorCode::kerImageWriteFailed); throw Error(ErrorCode::kerImageWriteFailed);
@ -259,7 +259,7 @@ DataBuf PgfImage::readPgfHeaderStructure(BasicIo& iIo, uint32_t& width, uint32_t
throw Error(ErrorCode::kerInputDataReadFailed); throw Error(ErrorCode::kerInputDataReadFailed);
DataBuf work(8); // don't disturb the binary data - doWriteMetadata reuses it DataBuf work(8); // don't disturb the binary data - doWriteMetadata reuses it
work.copyBytes(0, header.c_data(), 8); std::copy_n(header.c_data(), 8, work.begin());
width = byteSwap_(work, 0, bSwap_); width = byteSwap_(work, 0, bSwap_);
height = byteSwap_(work, 4, bSwap_); height = byteSwap_(work, 4, bSwap_);

View File

@ -490,7 +490,7 @@ DataBuf PngChunk::readRawProfile(const DataBuf& text, bool iTXt) {
if (iTXt) { if (iTXt) {
info.alloc(text.size()); info.alloc(text.size());
info.copyBytes(0, text.c_data(), text.size()); std::copy(text.cbegin(), text.cend(), info.begin());
return info; return info;
} }

View File

@ -340,10 +340,10 @@ void PngImage::printStructure(std::ostream& out, PrintStructureOption option, in
} }
if (bSoft && !dataBuf.empty()) { if (bSoft && !dataBuf.empty()) {
DataBuf s(dataBuf.size() + 1); // allocate buffer with an extra byte DataBuf s(dataBuf.size() + 1); // allocate buffer with an extra byte
s.copyBytes(0, dataBuf.c_data(), dataBuf.size()); // copy in the dataBuf std::copy(dataBuf.begin(), dataBuf.end(), s.begin()); // copy in the dataBuf
s.write_uint8(dataBuf.size(), 0); // nul terminate it s.write_uint8(dataBuf.size(), 0); // nul terminate it
const auto str = s.c_str(); // give it name const auto str = s.c_str(); // give it name
out << Internal::indent(depth) << buff.c_str() << ": " << str; out << Internal::indent(depth) << buff.c_str() << ": " << str;
bLF = true; bLF = true;
} }
@ -526,7 +526,7 @@ void PngImage::doWriteMetadata(BasicIo& outIo) {
// Read whole chunk : Chunk header + Chunk data (not fixed size - can be null) + CRC (4 bytes). // Read whole chunk : Chunk header + Chunk data (not fixed size - can be null) + CRC (4 bytes).
DataBuf chunkBuf(8 + dataOffset + 4); // Chunk header (8 bytes) + Chunk data + CRC (4 bytes). DataBuf chunkBuf(8 + dataOffset + 4); // Chunk header (8 bytes) + Chunk data + CRC (4 bytes).
chunkBuf.copyBytes(0, cheaderBuf.c_data(), 8); // Copy header. std::copy_n(cheaderBuf.begin(), 8, chunkBuf.begin()); // Copy header.
bufRead = io_->read(chunkBuf.data(8), dataOffset + 4); // Extract chunk data + CRC bufRead = io_->read(chunkBuf.data(8), dataOffset + 4); // Extract chunk data + CRC
if (io_->error()) if (io_->error())
throw Error(ErrorCode::kerFailedToReadImageData); throw Error(ErrorCode::kerFailedToReadImageData);

View File

@ -12,6 +12,7 @@
#include "tiffimage.hpp" #include "tiffimage.hpp"
#include "tiffimage_int.hpp" #include "tiffimage_int.hpp"
#include <algorithm>
#include <climits> #include <climits>
namespace { namespace {
@ -739,7 +740,7 @@ DataBuf LoaderTiff::getData() const {
// That's why we check again for each step here to really make sure we don't overstep // That's why we check again for each step here to really make sure we don't overstep
enforce(Safe::add(idxBuf, size) <= size_, ErrorCode::kerCorruptedMetadata); enforce(Safe::add(idxBuf, size) <= size_, ErrorCode::kerCorruptedMetadata);
if (size != 0 && Safe::add(offset, size) <= static_cast<uint32_t>(io.size())) { if (size != 0 && Safe::add(offset, size) <= static_cast<uint32_t>(io.size())) {
buf.copyBytes(idxBuf, base + offset, size); std::copy_n(base + offset, size, buf.begin() + idxBuf);
} }
idxBuf += size; idxBuf += size;
@ -953,9 +954,9 @@ DataBuf makePnm(size_t width, size_t height, const DataBuf &rgb) {
const std::string header = "P6\n" + toString(width) + " " + toString(height) + "\n255\n"; const std::string header = "P6\n" + toString(width) + " " + toString(height) + "\n255\n";
const auto headerBytes = reinterpret_cast<const byte *>(header.data()); const auto headerBytes = reinterpret_cast<const byte *>(header.data());
DataBuf dest(static_cast<long>(header.size() + rgb.size())); DataBuf dest(header.size() + rgb.size());
dest.copyBytes(0, headerBytes, header.size()); std::copy_n(headerBytes, header.size(), dest.begin());
dest.copyBytes(header.size(), rgb.c_data(), rgb.size()); std::copy_n(rgb.c_data(), rgb.size(), dest.begin() + header.size());
return dest; return dest;
} }

View File

@ -512,7 +512,7 @@ void TiffEncoder::encodeIptc() {
if (rawIptc.size() % 4 != 0) { if (rawIptc.size() % 4 != 0) {
// Pad the last unsignedLong value with 0s // Pad the last unsignedLong value with 0s
buf.alloc((rawIptc.size() / 4) * 4 + 4); buf.alloc((rawIptc.size() / 4) * 4 + 4);
buf.copyBytes(0, rawIptc.c_data(), rawIptc.size()); std::copy(rawIptc.begin(), rawIptc.end(), buf.begin());
} else { } else {
buf = std::move(rawIptc); // Note: This resets rawIptc buf = std::move(rawIptc); // Note: This resets rawIptc
} }

View File

@ -164,15 +164,6 @@ void Exiv2::DataBuf::write_uint64(size_t offset, uint64_t x, ByteOrder byteOrder
ull2Data(&pData_[offset], x, byteOrder); ull2Data(&pData_[offset], x, byteOrder);
} }
void Exiv2::DataBuf::copyBytes(size_t offset, const void* buf, size_t bufsize) {
if (pData_.size() < bufsize || offset > pData_.size() - bufsize) {
throw std::overflow_error("Overflow in Exiv2::DataBuf::copyBytes");
}
if (bufsize > 0) {
memcpy(&pData_[offset], buf, bufsize);
}
}
int Exiv2::DataBuf::cmpBytes(size_t offset, const void* buf, size_t bufsize) const { int Exiv2::DataBuf::cmpBytes(size_t offset, const void* buf, size_t bufsize) const {
if (pData_.size() < bufsize || offset > pData_.size() - bufsize) { if (pData_.size() < bufsize || offset > pData_.size() - bufsize) {
throw std::overflow_error("Overflow in Exiv2::DataBuf::cmpBytes"); throw std::overflow_error("Overflow in Exiv2::DataBuf::cmpBytes");

View File

@ -680,18 +680,18 @@ void WebPImage::decodeChunks(long filesize) {
if (s_header) { if (s_header) {
us2Data(size_buff2, static_cast<uint16_t>(sizePayload - 6), bigEndian); us2Data(size_buff2, static_cast<uint16_t>(sizePayload - 6), bigEndian);
rawExifData.copyBytes(0, reinterpret_cast<char*>(&exifLongHeader), 4); std::copy_n(reinterpret_cast<char*>(&exifLongHeader), 4, rawExifData.begin());
rawExifData.copyBytes(4, reinterpret_cast<char*>(&size_buff2), 2); std::copy_n(reinterpret_cast<char*>(&size_buff2), 2, rawExifData.begin() + 4);
} }
if (be_header || le_header) { if (be_header || le_header) {
us2Data(size_buff2, static_cast<uint16_t>(sizePayload - 6), bigEndian); us2Data(size_buff2, static_cast<uint16_t>(sizePayload - 6), bigEndian);
rawExifData.copyBytes(0, reinterpret_cast<char*>(&exifLongHeader), 4); std::copy_n(reinterpret_cast<char*>(&exifLongHeader), 4, rawExifData.begin());
rawExifData.copyBytes(4, reinterpret_cast<char*>(&size_buff2), 2); std::copy_n(reinterpret_cast<char*>(&size_buff2), 2, rawExifData.begin() + 4);
rawExifData.copyBytes(6, reinterpret_cast<char*>(&exifShortHeader), 6); std::copy_n(reinterpret_cast<char*>(&exifShortHeader), 6, rawExifData.begin() + 6);
} }
rawExifData.copyBytes(offset, payload.c_data(), payload.size()); std::copy(payload.begin(), payload.end(), rawExifData.begin() + offset);
#ifdef EXIV2_DEBUG_MESSAGES #ifdef EXIV2_DEBUG_MESSAGES
std::cout << "Display Hex Dump [size:" << static_cast<unsigned long>(sizePayload) << "]" << std::endl; std::cout << "Display Hex Dump [size:" << static_cast<unsigned long>(sizePayload) << "]" << std::endl;