Bounds check lineSrc in JBig2_Image.cpp.

No matter how the dimensions might be determined, we know the
hard end of the source line, and can use it for a bounds check.
We expect the size is quantized to a multiple of m_stride, so
as long as each block operates within an m_stride, the initial
check should be sufficient.

Bug: 867501
Change-Id: Iaf9936557b856f3eb09fef522f3e6738aa4f38f0
Reviewed-on: https://pdfium-review.googlesource.com/39310
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxcodec/jbig2/JBig2_Image.cpp b/core/fxcodec/jbig2/JBig2_Image.cpp
index 442a36d..59f65c6 100644
--- a/core/fxcodec/jbig2/JBig2_Image.cpp
+++ b/core/fxcodec/jbig2/JBig2_Image.cpp
@@ -705,8 +705,9 @@
   int32_t maskL = 0xffffffff >> d1;
   int32_t maskR = 0xffffffff << ((32 - (xd1 & 31)) % 32);
   int32_t maskM = maskL & maskR;
-  uint8_t* lineSrc =
+  const uint8_t* lineSrc =
       data() + (rtSrc.top + ys0) * m_nStride + (((xs0 + rtSrc.left) >> 5) << 2);
+  const uint8_t* lineSrcEnd = data() + m_nHeight * m_nStride;
   int32_t lineLeft = m_nStride - ((xs0 >> 5) << 2);
   uint8_t* lineDst = pDst->data() + yd0 * pDst->m_nStride + ((xd0 >> 5) << 2);
   if ((xd0 & ~31) == ((xd1 - 1) & ~31)) {
@@ -714,6 +715,8 @@
       if (s1 > d1) {
         uint32_t shift = s1 - d1;
         for (int32_t yy = yd0; yy < yd1; yy++) {
+          if (lineSrc >= lineSrcEnd)
+            return false;
           uint32_t tmp1 = JBIG2_GETDWORD(lineSrc) << shift;
           uint32_t tmp2 = JBIG2_GETDWORD(lineDst);
           uint32_t tmp = 0;
@@ -744,6 +747,8 @@
       } else {
         uint32_t shift = d1 - s1;
         for (int32_t yy = yd0; yy < yd1; yy++) {
+          if (lineSrc >= lineSrcEnd)
+            return false;
           uint32_t tmp1 = JBIG2_GETDWORD(lineSrc) >> shift;
           uint32_t tmp2 = JBIG2_GETDWORD(lineDst);
           uint32_t tmp = 0;
@@ -776,6 +781,8 @@
       uint32_t shift1 = s1 - d1;
       uint32_t shift2 = 32 - shift1;
       for (int32_t yy = yd0; yy < yd1; yy++) {
+        if (lineSrc >= lineSrcEnd)
+          return false;
         uint32_t tmp1 = (JBIG2_GETDWORD(lineSrc) << shift1) |
                         (JBIG2_GETDWORD(lineSrc + 4) >> shift2);
         uint32_t tmp2 = JBIG2_GETDWORD(lineDst);
@@ -811,7 +818,9 @@
       uint32_t shift2 = 32 - shift1;
       int32_t middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5);
       for (int32_t yy = yd0; yy < yd1; yy++) {
-        uint8_t* sp = lineSrc;
+        if (lineSrc >= lineSrcEnd)
+          return false;
+        const uint8_t* sp = lineSrc;
         uint8_t* dp = lineDst;
         if (d1 != 0) {
           uint32_t tmp1 = (JBIG2_GETDWORD(sp) << shift1) |
@@ -906,7 +915,9 @@
     } else if (s1 == d1) {
       int32_t middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5);
       for (int32_t yy = yd0; yy < yd1; yy++) {
-        uint8_t* sp = lineSrc;
+        if (lineSrc >= lineSrcEnd)
+          return false;
+        const uint8_t* sp = lineSrc;
         uint8_t* dp = lineDst;
         if (d1 != 0) {
           uint32_t tmp1 = JBIG2_GETDWORD(sp);
@@ -998,7 +1009,9 @@
       uint32_t shift2 = 32 - shift1;
       int32_t middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5);
       for (int32_t yy = yd0; yy < yd1; yy++) {
-        uint8_t* sp = lineSrc;
+        if (lineSrc >= lineSrcEnd)
+          return false;
+        const uint8_t* sp = lineSrc;
         uint8_t* dp = lineDst;
         if (d1 != 0) {
           uint32_t tmp1 = JBIG2_GETDWORD(sp) >> shift1;
diff --git a/testing/resources/pixel/bug_867501.pdf b/testing/resources/pixel/bug_867501.pdf
new file mode 100644
index 0000000..0b517b9
--- /dev/null
+++ b/testing/resources/pixel/bug_867501.pdf
Binary files differ
diff --git a/testing/resources/pixel/bug_867501_expected.pdf.0.png b/testing/resources/pixel/bug_867501_expected.pdf.0.png
new file mode 100644
index 0000000..bd6f8c1
--- /dev/null
+++ b/testing/resources/pixel/bug_867501_expected.pdf.0.png
Binary files differ