Do an additional check before patching bad JPEG headers.

Make sure the SOFn marker is 5 bytes before the bad dimension.

BUG=chromium:86459

Change-Id: I744c1bd8b2af1c6e979a2401679e0f3198d22e32
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/56530
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxcodec/jpeg/jpegmodule.cpp b/core/fxcodec/jpeg/jpegmodule.cpp
index b7a4c31..9ba2e3e 100644
--- a/core/fxcodec/jpeg/jpegmodule.cpp
+++ b/core/fxcodec/jpeg/jpegmodule.cpp
@@ -250,6 +250,9 @@
   // Can only be called inside a jpeg_read_header() setjmp handler.
   bool HasKnownBadHeaderWithInvalidHeight() const;
 
+  // Is a JPEG SOFn marker, which is defined as 0xff, 0xc[0-9a-f].
+  bool IsSofSegment(int marker_offset) const;
+
   // Patch up the in-memory JPEG header for known bad JPEGs.
   void PatchUpKnownBadHeaderWithInvalidHeight();
 
@@ -258,6 +261,9 @@
 
   uint8_t* GetWritableSrcData();
 
+  // Before |kKnownBadHeaderWithInvalidHeightByteOffsetStart|.
+  static const size_t kSofMarkerByteOffset = 5;
+
   static const int kKnownBadHeaderWithInvalidHeightByteOffsetStart = 163;
 
   uint32_t m_nDefaultScaleDenom = 1;
@@ -425,6 +431,11 @@
   if (m_SrcSpan.size() <= kKnownBadHeaderWithInvalidHeightByteOffsetStart + 3)
     return false;
 
+  if (!IsSofSegment(kKnownBadHeaderWithInvalidHeightByteOffsetStart -
+                    kSofMarkerByteOffset)) {
+    return false;
+  }
+
   const uint8_t* pHeaderDimensions =
       &m_SrcSpan[kKnownBadHeaderWithInvalidHeightByteOffsetStart];
   uint8_t nExpectedWidthByte1 = (m_OrigWidth >> 8) & 0xff;
@@ -435,6 +446,12 @@
          pHeaderDimensions[3] == nExpectedWidthByte2;
 }
 
+bool JpegDecoder::IsSofSegment(int marker_offset) const {
+  const uint8_t* pHeaderMarker = &m_SrcSpan[marker_offset];
+  return pHeaderMarker[0] == 0xff && pHeaderMarker[1] >= 0xc0 &&
+         pHeaderMarker[1] <= 0xcf;
+}
+
 void JpegDecoder::PatchUpKnownBadHeaderWithInvalidHeight() {
   ASSERT(m_SrcSpan.size() >
          kKnownBadHeaderWithInvalidHeightByteOffsetStart + 1);