|
32 | 32 | #include "image.hpp"
|
33 | 33 | #include "basicio.hpp"
|
34 | 34 | #include "error.hpp"
|
| 35 | +#include "enforce.hpp" |
35 | 36 | #include "futils.hpp"
|
36 | 37 |
|
37 | 38 | // + standard includes
|
@@ -114,26 +115,33 @@ namespace Exiv2 {
|
114 | 115 | uint32_t const end = getULong(tmp + 4, bigEndian);
|
115 | 116 |
|
116 | 117 | pos += len;
|
117 |
| - if (pos > end) throw Error(kerFailedToReadImageData); |
| 118 | + enforce(pos <= end, kerFailedToReadImageData); |
118 | 119 | io_->read(tmp, len);
|
119 | 120 | if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData);
|
120 | 121 |
|
121 | 122 | while (memcmp(tmp + 1, "TTW", 3) != 0) {
|
122 | 123 | uint32_t const siz = getULong(tmp + 4, bigEndian);
|
| 124 | + enforce(siz <= end - pos, kerFailedToReadImageData); |
123 | 125 | pos += siz;
|
124 |
| - if (pos > end) throw Error(kerFailedToReadImageData); |
125 | 126 | io_->seek(siz, BasicIo::cur);
|
126 |
| - if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData); |
| 127 | + enforce(!io_->error() && !io_->eof(), kerFailedToReadImageData); |
127 | 128 |
|
| 129 | + enforce(len <= end - pos, kerFailedToReadImageData); |
128 | 130 | pos += len;
|
129 |
| - if (pos > end) throw Error(kerFailedToReadImageData); |
130 | 131 | io_->read(tmp, len);
|
131 |
| - if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData); |
| 132 | + enforce(!io_->error() && !io_->eof(), kerFailedToReadImageData); |
132 | 133 | }
|
133 | 134 |
|
134 |
| - DataBuf buf(getULong(tmp + 4, bigEndian)); |
| 135 | + const uint32_t siz = getULong(tmp + 4, bigEndian); |
| 136 | + // First do an approximate bounds check of siz, so that we don't |
| 137 | + // get DOS-ed by a 4GB allocation on the next line. If siz is |
| 138 | + // greater than io_->size() then it is definitely invalid. But the |
| 139 | + // exact bounds checking is done by the call to io_->read, which |
| 140 | + // will fail if there are fewer than siz bytes left to read. |
| 141 | + enforce(siz <= io_->size(), kerFailedToReadImageData); |
| 142 | + DataBuf buf(siz); |
135 | 143 | io_->read(buf.pData_, buf.size_);
|
136 |
| - if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData); |
| 144 | + enforce(!io_->error() && !io_->eof(), kerFailedToReadImageData); |
137 | 145 |
|
138 | 146 | ByteOrder bo = TiffParser::decode(exifData_,
|
139 | 147 | iptcData_,
|
|
0 commit comments