|
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