Check for decoder completeness in CJBig2_GRRDProc
This CL adds checks in CJBig2_GRRDProc to verify if the decoder is
completed before trying to decode. This is currently done in all
decoding calls in CJBig2_GRDProc.
Bug: chromium:782826
Change-Id: Ifb4ee4d09e8357e969aefa107b4dafbc2284324b
Reviewed-on: https://pdfium-review.googlesource.com/18333
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Nicolás Peña Moreno <npm@chromium.org>
diff --git a/core/fxcodec/jbig2/JBig2_GrrdProc.cpp b/core/fxcodec/jbig2/JBig2_GrrdProc.cpp
index df86c88..f5f569c 100644
--- a/core/fxcodec/jbig2/JBig2_GrrdProc.cpp
+++ b/core/fxcodec/jbig2/JBig2_GrrdProc.cpp
@@ -43,9 +43,12 @@
auto GRREG = pdfium::MakeUnique<CJBig2_Image>(GRW, GRH);
GRREG->fill(0);
for (uint32_t h = 0; h < GRH; h++) {
- if (TPGRON)
- LTP = LTP ^ pArithDecoder->DECODE(&grContext[0x0010]);
+ if (TPGRON) {
+ if (pArithDecoder->IsComplete())
+ return nullptr;
+ LTP = LTP ^ pArithDecoder->DECODE(&grContext[0x0010]);
+ }
uint32_t lines[5];
lines[0] = GRREG->getPixel(1, h - 1);
lines[0] |= GRREG->getPixel(0, h - 1) << 1;
@@ -66,6 +69,9 @@
for (uint32_t w = 0; w < GRW; w++) {
uint32_t CONTEXT =
decode_Template0_unopt_CalculateContext(*GRREG, lines, w, h);
+ if (pArithDecoder->IsComplete())
+ return nullptr;
+
int bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
decode_Template0_unopt_SetPixel(GRREG.get(), lines, w, h, bVal);
}
@@ -82,6 +88,9 @@
(bVal == GRREFERENCE->getPixel(w + 1, h + 1)))) {
uint32_t CONTEXT =
decode_Template0_unopt_CalculateContext(*GRREG, lines, w, h);
+ if (pArithDecoder->IsComplete())
+ return nullptr;
+
bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
}
decode_Template0_unopt_SetPixel(GRREG.get(), lines, w, h, bVal);
@@ -150,8 +159,12 @@
GRREFERENCEDY = 0;
intptr_t nOffset = -GRREFERENCEDY * nStrideR;
for (int32_t h = 0; h < iGRH; h++) {
- if (TPGRON)
+ if (TPGRON) {
+ if (pArithDecoder->IsComplete())
+ return nullptr;
+
LTP = LTP ^ pArithDecoder->DECODE(&grContext[0x0010]);
+ }
uint32_t line1 = (h > 0) ? pLine[-nStride] << 4 : 0;
int32_t reference_h = h - GRREFERENCEDY;
bool line1_r_ok = (reference_h > 0 && reference_h < GRHR + 1);
@@ -193,6 +206,9 @@
}
uint8_t cVal = 0;
for (int32_t k = 0; k < nBits; k++) {
+ if (pArithDecoder->IsComplete())
+ return nullptr;
+
int bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
cVal |= bVal << (7 - k);
CONTEXT = ((CONTEXT & 0x0cdb) << 1) | (bVal << 9) |
@@ -239,6 +255,9 @@
(bVal == GRREFERENCE->getPixel(w + k - 1, h + 1)) &&
(bVal == GRREFERENCE->getPixel(w + k, h + 1)) &&
(bVal == GRREFERENCE->getPixel(w + k + 1, h + 1)))) {
+ if (pArithDecoder->IsComplete())
+ return nullptr;
+
bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
}
cVal |= bVal << (7 - k);
@@ -265,8 +284,12 @@
auto GRREG = pdfium::MakeUnique<CJBig2_Image>(GRW, GRH);
GRREG->fill(0);
for (uint32_t h = 0; h < GRH; h++) {
- if (TPGRON)
+ if (TPGRON) {
+ if (pArithDecoder->IsComplete())
+ return nullptr;
+
LTP = LTP ^ pArithDecoder->DECODE(&grContext[0x0008]);
+ }
if (!LTP) {
uint32_t line1 = GRREG->getPixel(1, h - 1);
line1 |= GRREG->getPixel(0, h - 1) << 1;
@@ -289,6 +312,9 @@
CONTEXT |= line3 << 5;
CONTEXT |= line2 << 6;
CONTEXT |= line1 << 7;
+ if (pArithDecoder->IsComplete())
+ return nullptr;
+
int bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
GRREG->setPixel(w, h, bVal);
line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x07;
@@ -337,6 +363,9 @@
CONTEXT |= line3 << 5;
CONTEXT |= line2 << 6;
CONTEXT |= line1 << 7;
+ if (pArithDecoder->IsComplete())
+ return nullptr;
+
bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
}
GRREG->setPixel(w, h, bVal);
@@ -384,8 +413,12 @@
}
intptr_t nOffset = -GRREFERENCEDY * nStrideR;
for (int32_t h = 0; h < iGRH; h++) {
- if (TPGRON)
+ if (TPGRON) {
+ if (pArithDecoder->IsComplete())
+ return nullptr;
+
LTP = LTP ^ pArithDecoder->DECODE(&grContext[0x0008]);
+ }
uint32_t line1 = (h > 0) ? pLine[-nStride] << 1 : 0;
int32_t reference_h = h - GRREFERENCEDY;
bool line1_r_ok = (reference_h > 0 && reference_h < GRHR + 1);
@@ -461,6 +494,9 @@
(bVal == GRREFERENCE->getPixel(w + k - 1, h + 1)) &&
(bVal == GRREFERENCE->getPixel(w + k, h + 1)) &&
(bVal == GRREFERENCE->getPixel(w + k + 1, h + 1)))) {
+ if (pArithDecoder->IsComplete())
+ return nullptr;
+
bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
}
cVal |= bVal << (7 - k);