M74: Avoid 0 byte reads in ParseAndAppendCrossRefSubsectionData().

The existing CPDF_Parser::ParseAndAppendCrossRefSubsectionData() code
does not handle reads properly when the read count is a multiple of the
block size. e.g. For a count of 2048 and a block size of 1024, it tries
to read 1024, 1024, and 0 bytes.

Commit cef91f11 added a check that causes 0 byte reads to fail, so the
existing behavior causes ParseAndAppendCrossRefSubsectionData() to fail
altogether. Fix how ParseAndAppendCrossRefSubsectionData() loops to
avoid the 0 byte read.

BUG=chromium:945624
TBR=tsepez@chromium.org

Change-Id: Ie309dd6c3e139720f19962ec2a094512282aa8ed
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/52410
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
(cherry picked from commit fabd13dc93f6cd9345f20f10456eb5a5ac8863e6)
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/52652
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp
index dc3d398..02cb08e 100644
--- a/core/fpdfapi/parser/cpdf_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_parser.cpp
@@ -453,22 +453,20 @@
   std::vector<char> buf(1024 * kEntryConstSize + 1);
   buf.back() = '\0';
 
-  int32_t nBlocks = count / 1024 + 1;
-  for (int32_t block = 0; block < nBlocks; block++) {
-    int32_t block_size = block == nBlocks - 1 ? count % 1024 : 1024;
+  uint32_t nBytesToRead = count;
+  while (nBytesToRead > 0) {
+    const uint32_t block_size = std::min(nBytesToRead, 1024u);
     if (!m_pSyntax->ReadBlock(reinterpret_cast<uint8_t*>(buf.data()),
                               block_size * kEntryConstSize)) {
       return false;
     }
 
-    for (int32_t i = 0; i < block_size; i++) {
+    for (uint32_t i = 0; i < block_size; i++) {
+      uint32_t iObjectIndex = count - nBytesToRead + i;
       CrossRefObjData& obj_data =
-          (*out_objects)[start_obj_index + block * 1024 + i];
-
-      const uint32_t objnum = start_objnum + block * 1024 + i;
-
+          (*out_objects)[start_obj_index + iObjectIndex];
+      const uint32_t objnum = start_objnum + iObjectIndex;
       obj_data.obj_num = objnum;
-
       ObjectInfo& info = obj_data.info;
 
       char* pEntry = &buf[i * kEntryConstSize];
@@ -496,6 +494,7 @@
         info.type = ObjectType::kNotCompressed;
       }
     }
+    nBytesToRead -= block_size;
   }
   return true;
 }