Skip to content

Commit 21fa8ef

Browse files
committed
PanasonicV8Decompressor: sanitize strip size
1 parent 71518e8 commit 21fa8ef

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

src/librawspeed/decompressors/PanasonicV8Decompressor.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,11 @@
4242
#include "io/IOException.h"
4343
#include <algorithm>
4444
#include <array>
45+
#include <climits>
4546
#include <cstddef>
4647
#include <cstdint>
4748
#include <limits>
49+
#include <numeric>
4850
#include <utility>
4951
#include <vector>
5052

@@ -196,6 +198,24 @@ void isValidImageGrid(iRectangle2D imgDim,
196198
ThrowRDE("Tiles do not cover whole output image");
197199
}
198200

201+
int minBitsPerPixelNeeded(
202+
Array1DRef<const PanasonicV8Decompressor::DecoderLUTEntry> mDecoderLUT) {
203+
invariant(mDecoderLUT.size() > 0);
204+
const auto r = std::accumulate(
205+
mDecoderLUT.begin(), mDecoderLUT.end(), std::numeric_limits<int>::max(),
206+
[](int init, const PanasonicV8Decompressor::DecoderLUTEntry& e) {
207+
if (e.isSentinel())
208+
return init;
209+
invariant(e.bitcount > 0);
210+
const auto total = e.bitcount + e.diffCat;
211+
invariant(total > 0);
212+
return std::min(init, total);
213+
});
214+
invariant(r > 0);
215+
invariant(r <= (16 + 17));
216+
return r;
217+
}
218+
199219
} // namespace
200220

201221
std::vector<iRectangle2D>
@@ -248,6 +268,14 @@ PanasonicV8Decompressor::PanasonicV8Decompressor(
248268
}
249269
if (!mRawOutput->dim.hasPositiveArea())
250270
ThrowRDE("Unexpected image dimensions");
271+
const auto minBpp = minBitsPerPixelNeeded(mDecoderLUT);
272+
for (int stripIdx = 0; stripIdx < mParams.mStrips.size(); ++stripIdx) {
273+
const auto strip = mParams.mStrips(stripIdx);
274+
const auto maxPixelsInStrip = (uint64_t{CHAR_BIT} * strip.size()) / minBpp;
275+
const auto outRect = mParams.mOutRect(stripIdx);
276+
if (outRect.dim.area() > maxPixelsInStrip)
277+
ThrowRDE("Input strip is unsufficient to produce requested tile");
278+
}
251279
}
252280

253281
void PanasonicV8Decompressor::decompress() const {

src/librawspeed/decompressors/PanasonicV8Decompressor.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ class PanasonicV8Decompressor final : public AbstractDecompressor {
111111
struct DecoderLUTEntry {
112112
uint8_t bitcount = 7;
113113
uint8_t diffCat = 0;
114+
115+
[[nodiscard]] bool isSentinel() const {
116+
constexpr auto sentinel = DecoderLUTEntry();
117+
return bitcount == sentinel.bitcount && diffCat == sentinel.diffCat;
118+
}
114119
};
115120

116121
private:

0 commit comments

Comments
 (0)