Defensive coding changes to avoid integer overflow in loop conditions.
This commit is contained in:
parent
ad5e6c479c
commit
69d82ffe01
@ -603,8 +603,8 @@ namespace Action {
|
||||
std::ostringstream os;
|
||||
// #1114 - show negative values for SByte
|
||||
if (md.typeId() == Exiv2::signedByte) {
|
||||
for ( int c = 0 ; c < md.value().count() ; c++ ) {
|
||||
int value = md.value().toLong(c);
|
||||
for ( long c = 0 ; c < md.value().count() ; c++ ) {
|
||||
long value = md.value().toLong(c);
|
||||
os << (c?" ":"") << std::dec << (value < 128 ? value : value - 256);
|
||||
}
|
||||
} else {
|
||||
|
||||
@ -1780,9 +1780,10 @@ namespace Exiv2 {
|
||||
|
||||
// find $right
|
||||
findDiff = false;
|
||||
blockIndex = nBlocks - 1;
|
||||
blockSize = p_->blocksMap_[blockIndex].getSize();
|
||||
while ((blockIndex + 1 > 0) && right < src.size() && !findDiff) {
|
||||
blockIndex = nBlocks;
|
||||
while (blockIndex > 0 && right < src.size() && !findDiff) {
|
||||
blockIndex--;
|
||||
blockSize = p_->blocksMap_[blockIndex].getSize();
|
||||
if(src.seek(-1 * (blockSize + right), BasicIo::end)) {
|
||||
findDiff = true;
|
||||
} else {
|
||||
@ -1797,8 +1798,6 @@ namespace Exiv2 {
|
||||
}
|
||||
}
|
||||
}
|
||||
blockIndex--;
|
||||
blockSize = static_cast<long>(p_->blocksMap_[blockIndex].getSize());
|
||||
}
|
||||
|
||||
delete []buf;
|
||||
|
||||
@ -549,7 +549,7 @@ namespace Exiv2 {
|
||||
auto pos = exifData_->findKey(ExifKey(from));
|
||||
if (pos == exifData_->end()) return;
|
||||
if (!prepareXmpTarget(to)) return;
|
||||
for (int i = 0; i < pos->count(); ++i) {
|
||||
for (long i = 0; i < pos->count(); ++i) {
|
||||
std::string value = pos->toString(i);
|
||||
if (!pos->value().ok()) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
@ -697,7 +697,7 @@ namespace Exiv2 {
|
||||
if (pos == exifData_->end()) return;
|
||||
if (!prepareXmpTarget(to)) return;
|
||||
std::ostringstream value;
|
||||
for (int i = 0; i < pos->count(); ++i) {
|
||||
for (long i = 0; i < pos->count(); ++i) {
|
||||
value << static_cast<char>(pos->toLong(i));
|
||||
}
|
||||
(*xmpData_)[to] = value.str();
|
||||
@ -710,7 +710,7 @@ namespace Exiv2 {
|
||||
if (pos == exifData_->end()) return;
|
||||
if (!prepareXmpTarget(to)) return;
|
||||
std::ostringstream value;
|
||||
for (int i = 0; i < pos->count(); ++i) {
|
||||
for (long i = 0; i < pos->count(); ++i) {
|
||||
if (i > 0) value << '.';
|
||||
value << pos->toLong(i);
|
||||
}
|
||||
@ -828,7 +828,7 @@ namespace Exiv2 {
|
||||
auto pos = xmpData_->findKey(XmpKey(from));
|
||||
if (pos == xmpData_->end()) return;
|
||||
std::ostringstream array;
|
||||
for (int i = 0; i < pos->count(); ++i) {
|
||||
for (long i = 0; i < pos->count(); ++i) {
|
||||
std::string value = pos->toString(i);
|
||||
if (!pos->value().ok()) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
|
||||
@ -953,7 +953,7 @@ namespace {
|
||||
long sumToLong(const Exiv2::Exifdatum& md)
|
||||
{
|
||||
long sum = 0;
|
||||
for (int i = 0; i < md.count(); ++i) {
|
||||
for (long i = 0; i < md.count(); ++i) {
|
||||
sum += md.toLong(i);
|
||||
}
|
||||
return sum;
|
||||
|
||||
@ -1517,7 +1517,7 @@ namespace {
|
||||
std::string parseEscapes(const std::string& input)
|
||||
{
|
||||
std::string result;
|
||||
for (unsigned int i = 0; i < input.length(); ++i) {
|
||||
for (size_t i = 0; i < input.length(); ++i) {
|
||||
char ch = input[i];
|
||||
if (ch != '\\') {
|
||||
result.push_back(ch);
|
||||
@ -1544,7 +1544,7 @@ namespace {
|
||||
result.push_back('\t');
|
||||
break;
|
||||
case 'u': // Escaping of unicode
|
||||
if (input.length() - 4 > i) {
|
||||
if (input.length() >= 4 && input.length() - 4 > i) {
|
||||
int acc = 0;
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
++i;
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
#include "iptc.hpp"
|
||||
#include "types.hpp"
|
||||
#include "error.hpp"
|
||||
#include "enforce.hpp"
|
||||
#include "value.hpp"
|
||||
#include "datasets.hpp"
|
||||
#include "jpgimage.hpp"
|
||||
@ -344,22 +345,24 @@ namespace Exiv2 {
|
||||
|
||||
void IptcData::printStructure(std::ostream& out, const Slice<byte*>& bytes, uint32_t depth)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
while (i < bytes.size() - 3 && bytes.at(i) != 0x1c)
|
||||
size_t i = 0;
|
||||
while (i + 3 < bytes.size() && bytes.at(i) != 0x1c)
|
||||
i++;
|
||||
depth++;
|
||||
out << Internal::indent(depth) << "Record | DataSet | Name | Length | Data" << std::endl;
|
||||
while (i < bytes.size() - 3) {
|
||||
while (i + 3 < bytes.size()) {
|
||||
if (bytes.at(i) != 0x1c) {
|
||||
break;
|
||||
}
|
||||
char buff[100];
|
||||
uint16_t record = bytes.at(i + 1);
|
||||
uint16_t dataset = bytes.at(i + 2);
|
||||
enforce(bytes.size() - i >= 5, kerCorruptedMetadata);
|
||||
uint16_t len = getUShort(bytes.subSlice(i + 3, bytes.size()), bigEndian);
|
||||
snprintf(buff, sizeof(buff), " %6d | %7d | %-24s | %6d | ", record, dataset,
|
||||
Exiv2::IptcDataSets::dataSetName(dataset, record).c_str(), len);
|
||||
|
||||
enforce(bytes.size() - i >= 5 + len, kerCorruptedMetadata);
|
||||
out << buff << Internal::binaryToString(makeSlice(bytes, i + 5, i + 5 + (len > 40 ? 40 : len)))
|
||||
<< (len > 40 ? "..." : "")
|
||||
<< std::endl;
|
||||
|
||||
@ -804,7 +804,7 @@ namespace {
|
||||
enforce(size_ <= static_cast<uint32_t>(io.size()), kerCorruptedMetadata);
|
||||
DataBuf buf(size_);
|
||||
uint32_t idxBuf = 0;
|
||||
for (int i = 0; i < sizes.count(); i++) {
|
||||
for (long i = 0; i < sizes.count(); i++) {
|
||||
uint32_t offset = dataValue.toLong(i);
|
||||
uint32_t size = sizes.toLong(i);
|
||||
enforce(Safe::add(idxBuf, size) < size_, kerCorruptedMetadata);
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
|
||||
#include "convert.hpp"
|
||||
#include "error.hpp"
|
||||
#include "enforce.hpp"
|
||||
#include "i18n.h" // NLS support.
|
||||
|
||||
#include "canonmn_int.hpp"
|
||||
@ -2569,7 +2570,9 @@ namespace Exiv2 {
|
||||
{
|
||||
uint16_t bit = 0;
|
||||
uint16_t comma = 0;
|
||||
for (uint16_t i = 0; i < value.count(); i++ ) { // for each element in value array
|
||||
long count = value.count();
|
||||
enforce(0 <= count && count <= std::numeric_limits<uint16_t>::max(), kerCorruptedMetadata);
|
||||
for (uint16_t i = 0; i < count; i++ ) { // for each element in value array
|
||||
auto bits = static_cast<uint16_t>(value.toLong(i));
|
||||
for (uint16_t b = 0; b < 16; ++b) { // for every bit
|
||||
if (bits & (1 << b)) {
|
||||
|
||||
@ -398,7 +398,7 @@ namespace Exiv2 {
|
||||
return;
|
||||
}
|
||||
uint32_t size = 0;
|
||||
for (int i = 0; i < pSize->count(); ++i) {
|
||||
for (long i = 0; i < pSize->count(); ++i) {
|
||||
size += static_cast<uint32_t>(pSize->toLong(i));
|
||||
}
|
||||
auto offset = static_cast<uint32_t>(pValue()->toLong(0));
|
||||
@ -455,7 +455,7 @@ namespace Exiv2 {
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < pValue()->count(); ++i) {
|
||||
for (long i = 0; i < pValue()->count(); ++i) {
|
||||
const auto offset = static_cast<uint32_t>(pValue()->toLong(i));
|
||||
const byte* pStrip = pData + baseOffset + offset;
|
||||
const auto size = static_cast<uint32_t>(pSize->toLong(i));
|
||||
|
||||
@ -456,7 +456,7 @@ namespace Exiv2 {
|
||||
// create vector of signedShorts from unsignedShorts in Exif.Canon.AFInfo
|
||||
std::vector<int16_t> ints;
|
||||
std::vector<uint16_t> uint;
|
||||
for (int i = 0; i < object->pValue()->count(); i++) {
|
||||
for (long i = 0; i < object->pValue()->count(); i++) {
|
||||
ints.push_back(static_cast<int16_t>(object->pValue()->toLong(i)));
|
||||
uint.push_back(static_cast<uint16_t>(object->pValue()->toLong(i)));
|
||||
}
|
||||
@ -505,10 +505,10 @@ namespace Exiv2 {
|
||||
auto v = Exiv2::Value::create(record.bSigned ? Exiv2::signedShort : Exiv2::unsignedShort);
|
||||
std::ostringstream s;
|
||||
if (record.bSigned) {
|
||||
for (int16_t k = 0; k < record.size; k++)
|
||||
for (uint16_t k = 0; k < record.size; k++)
|
||||
s << " " << ints.at(nStart++);
|
||||
} else {
|
||||
for (int16_t k = 0; k < record.size; k++)
|
||||
for (uint16_t k = 0; k < record.size; k++)
|
||||
s << " " << uint.at(nStart++);
|
||||
}
|
||||
|
||||
|
||||
@ -586,7 +586,7 @@ namespace Exiv2 {
|
||||
bool stringTo<bool>(const std::string& s, bool& ok)
|
||||
{
|
||||
std::string lcs(s); /* lowercase string */
|
||||
for(unsigned i = 0; i < lcs.length(); i++) {
|
||||
for(size_t i = 0; i < lcs.length(); i++) {
|
||||
lcs[i] = std::tolower(s[i]);
|
||||
}
|
||||
/* handle the same values as xmp sdk */
|
||||
|
||||
@ -789,7 +789,7 @@ namespace Exiv2 {
|
||||
if (i.typeId() == xmpBag || i.typeId() == xmpSeq || i.typeId() == xmpAlt) {
|
||||
printNode(ns, i.tagName(), "", options);
|
||||
meta.SetProperty(ns.c_str(), i.tagName().c_str(), nullptr, options);
|
||||
for (int idx = 0; idx < i.count(); ++idx) {
|
||||
for (long idx = 0; idx < i.count(); ++idx) {
|
||||
const std::string item = i.tagName() + "[" + toString(idx + 1) + "]";
|
||||
printNode(ns, item, i.toString(idx), 0);
|
||||
meta.SetProperty(ns.c_str(), item.c_str(), i.toString(idx).c_str());
|
||||
|
||||
@ -229,7 +229,7 @@ namespace Exiv2 {
|
||||
std::string head(reinterpret_cast<const char*>(buf + start), len - start);
|
||||
if (head.substr(0, 5) == "<?xml") {
|
||||
// Forward to the next tag
|
||||
for (unsigned i = 5; i < head.size(); ++i) {
|
||||
for (size_t i = 5; i < head.size(); ++i) {
|
||||
if (head[i] == '<') {
|
||||
head = head.substr(i);
|
||||
break;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user