14d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// Copyright 2016 PDFium Authors. All rights reserved.
24d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// Use of this source code is governed by a BSD-style license that can be
34d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// found in the LICENSE file.
44d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
54d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
64d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
74d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/parser/cpdf_hint_tables.h"
84d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
94d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include <limits>
104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/parser/cpdf_array.h"
124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/parser/cpdf_data_avail.h"
134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/parser/cpdf_dictionary.h"
144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/parser/cpdf_document.h"
154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/parser/cpdf_linearized_header.h"
16d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "core/fpdfapi/parser/cpdf_read_validator.h"
174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/parser/cpdf_stream.h"
184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/parser/cpdf_stream_acc.h"
19d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "core/fxcrt/cfx_bitstream.h"
204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fxcrt/fx_safe_types.h"
214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "third_party/base/numerics/safe_conversions.h"
224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannnamespace {
244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool CanReadFromBitStream(const CFX_BitStream* hStream,
264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                          const FX_SAFE_UINT32& bits) {
274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return bits.IsValid() && hStream->BitsRemaining() >= bits.ValueOrDie();
284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// Sanity check values from the page table header. The note in the PDF 1.7
314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// reference for Table F.3 says the valid range is only 0 through 32. Though 0
324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// is not useful either.
334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool IsValidPageOffsetHintTableBitCount(uint32_t bits) {
344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return bits > 0 && bits <= 32;
354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}  // namespace
384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
39d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannCPDF_HintTables::CPDF_HintTables(CPDF_ReadValidator* pValidator,
404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                 CPDF_LinearizedHeader* pLinearized)
41d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    : m_pValidator(pValidator),
424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      m_pLinearized(pLinearized),
434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      m_nFirstPageSharedObjs(0),
444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      m_szFirstPageObjOffset(0) {
454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  ASSERT(m_pLinearized);
464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCPDF_HintTables::~CPDF_HintTables() {}
494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannuint32_t CPDF_HintTables::GetItemLength(
514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    uint32_t index,
52d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    const std::vector<FX_FILESIZE>& szArray) const {
534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (szArray.size() < 2 || index > szArray.size() - 2 ||
544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      szArray[index] > szArray[index + 1]) {
554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return 0;
564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return szArray[index + 1] - szArray[index];
584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) {
614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!hStream || hStream->IsEOF())
624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int nStreamOffset = ReadPrimaryHintStreamOffset();
654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (nStreamOffset < 0)
664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int nStreamLen = ReadPrimaryHintStreamLength();
694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (nStreamLen < 1 ||
704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      !pdfium::base::IsValueInRangeForNumericType<FX_FILESIZE>(nStreamLen)) {
714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  const uint32_t kHeaderSize = 288;
754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (hStream->BitsRemaining() < kHeaderSize)
764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // Item 1: The least number of objects in a page.
794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  const uint32_t dwObjLeastNum = hStream->GetBits(32);
804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!dwObjLeastNum)
814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // Item 2: The location of the first page's page object.
844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  const uint32_t dwFirstObjLoc = hStream->GetBits(32);
854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (dwFirstObjLoc > static_cast<uint32_t>(nStreamOffset)) {
864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    FX_SAFE_FILESIZE safeLoc = nStreamLen;
874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    safeLoc += dwFirstObjLoc;
884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (!safeLoc.IsValid())
894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return false;
904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    m_szFirstPageObjOffset = safeLoc.ValueOrDie();
914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  } else {
924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (!pdfium::base::IsValueInRangeForNumericType<FX_FILESIZE>(dwFirstObjLoc))
934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return false;
944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    m_szFirstPageObjOffset = dwFirstObjLoc;
954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // Item 3: The number of bits needed to represent the difference
984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // between the greatest and least number of objects in a page.
994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  const uint32_t dwDeltaObjectsBits = hStream->GetBits(16);
1004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!IsValidPageOffsetHintTableBitCount(dwDeltaObjectsBits))
1014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
1024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // Item 4: The least length of a page in bytes.
1044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  const uint32_t dwPageLeastLen = hStream->GetBits(32);
1054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!dwPageLeastLen)
1064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
1074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // Item 5: The number of bits needed to represent the difference
1094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // between the greatest and least length of a page, in bytes.
1104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  const uint32_t dwDeltaPageLenBits = hStream->GetBits(16);
1114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!IsValidPageOffsetHintTableBitCount(dwDeltaPageLenBits))
1124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
1134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // Skip Item 6, 7, 8, 9 total 96 bits.
1154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  hStream->SkipBits(96);
1164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // Item 10: The number of bits needed to represent the greatest
1184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // number of shared object references.
1194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  const uint32_t dwSharedObjBits = hStream->GetBits(16);
1204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!IsValidPageOffsetHintTableBitCount(dwSharedObjBits))
1214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
1224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // Item 11: The number of bits needed to represent the numerically
1244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // greatest shared object identifier used by the pages.
1254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  const uint32_t dwSharedIdBits = hStream->GetBits(16);
1264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!IsValidPageOffsetHintTableBitCount(dwSharedIdBits))
1274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
1284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // Item 12: The number of bits needed to represent the numerator of
1304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // the fractional position for each shared object reference. For each
1314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // shared object referenced from a page, there is an indication of
1324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // where in the page's content stream the object is first referenced.
1334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  const uint32_t dwSharedNumeratorBits = hStream->GetBits(16);
1344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!IsValidPageOffsetHintTableBitCount(dwSharedNumeratorBits))
1354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
1364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // Item 13: Skip Item 13 which has 16 bits.
1384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  hStream->SkipBits(16);
1394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  const int nPages = GetNumberOfPages();
1414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (nPages < 1 || nPages >= FPDF_PAGE_MAX_NUM)
1424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
1434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  const uint32_t dwPages = pdfium::base::checked_cast<uint32_t>(nPages);
1454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  FX_SAFE_UINT32 required_bits = dwDeltaObjectsBits;
1464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  required_bits *= dwPages;
1474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!CanReadFromBitStream(hStream, required_bits))
1484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
1494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  for (int i = 0; i < nPages; ++i) {
1514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    FX_SAFE_UINT32 safeDeltaObj = hStream->GetBits(dwDeltaObjectsBits);
1524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    safeDeltaObj += dwObjLeastNum;
1534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (!safeDeltaObj.IsValid())
1544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return false;
1554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    m_dwDeltaNObjsArray.push_back(safeDeltaObj.ValueOrDie());
1564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
1574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  hStream->ByteAlign();
1584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  required_bits = dwDeltaPageLenBits;
1604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  required_bits *= dwPages;
1614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!CanReadFromBitStream(hStream, required_bits))
1624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
1634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  std::vector<uint32_t> dwPageLenArray;
1654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  for (int i = 0; i < nPages; ++i) {
1664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    FX_SAFE_UINT32 safePageLen = hStream->GetBits(dwDeltaPageLenBits);
1674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    safePageLen += dwPageLeastLen;
1684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (!safePageLen.IsValid())
1694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return false;
1704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    dwPageLenArray.push_back(safePageLen.ValueOrDie());
1724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
1734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int nOffsetE = GetEndOfFirstPageOffset();
1754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (nOffsetE < 0)
1764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
1774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int nFirstPageNum = GetFirstPageNumber();
1794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (nFirstPageNum < 0 || nFirstPageNum > std::numeric_limits<int>::max() - 1)
1804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
1814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  for (int i = 0; i < nPages; ++i) {
1834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (i == nFirstPageNum) {
1844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      m_szPageOffsetArray.push_back(m_szFirstPageObjOffset);
1854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    } else if (i == nFirstPageNum + 1) {
1864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (i == 1) {
1874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        m_szPageOffsetArray.push_back(nOffsetE);
1884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      } else {
1894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        m_szPageOffsetArray.push_back(m_szPageOffsetArray[i - 2] +
1904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                      dwPageLenArray[i - 2]);
1914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
1924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    } else {
1934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (i == 0) {
1944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        m_szPageOffsetArray.push_back(nOffsetE);
1954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      } else {
1964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        m_szPageOffsetArray.push_back(m_szPageOffsetArray[i - 1] +
1974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                      dwPageLenArray[i - 1]);
1984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
1994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
2004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
2014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  m_szPageOffsetArray.push_back(m_szPageOffsetArray[nPages - 1] +
2034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                dwPageLenArray[nPages - 1]);
2044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  hStream->ByteAlign();
2054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // Number of shared objects.
2074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  required_bits = dwSharedObjBits;
2084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  required_bits *= dwPages;
2094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!CanReadFromBitStream(hStream, required_bits))
2104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
2114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  for (int i = 0; i < nPages; i++)
2134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    m_dwNSharedObjsArray.push_back(hStream->GetBits(dwSharedObjBits));
2144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  hStream->ByteAlign();
2154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // Array of identifiers, size = nshared_objects.
2174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  for (int i = 0; i < nPages; i++) {
2184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    required_bits = dwSharedIdBits;
2194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    required_bits *= m_dwNSharedObjsArray[i];
2204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (!CanReadFromBitStream(hStream, required_bits))
2214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return false;
2224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    for (uint32_t j = 0; j < m_dwNSharedObjsArray[i]; j++)
2244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      m_dwIdentifierArray.push_back(hStream->GetBits(dwSharedIdBits));
2254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
2264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  hStream->ByteAlign();
2274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  for (int i = 0; i < nPages; i++) {
2294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    FX_SAFE_UINT32 safeSize = m_dwNSharedObjsArray[i];
2304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    safeSize *= dwSharedNumeratorBits;
2314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (!CanReadFromBitStream(hStream, safeSize))
2324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return false;
2334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    hStream->SkipBits(safeSize.ValueOrDie());
2354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
2364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  hStream->ByteAlign();
2374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  FX_SAFE_UINT32 safeTotalPageLen = dwPages;
2394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  safeTotalPageLen *= dwDeltaPageLenBits;
2404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!CanReadFromBitStream(hStream, safeTotalPageLen))
2414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
2424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  hStream->SkipBits(safeTotalPageLen.ValueOrDie());
2444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  hStream->ByteAlign();
2454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return true;
2464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
2474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream,
2494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                             uint32_t offset) {
2504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!hStream || hStream->IsEOF())
2514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
2524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int nStreamOffset = ReadPrimaryHintStreamOffset();
2544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int nStreamLen = ReadPrimaryHintStreamLength();
2554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (nStreamOffset < 0 || nStreamLen < 1)
2564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
2574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  FX_SAFE_UINT32 bit_offset = offset;
2594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  bit_offset *= 8;
2604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!bit_offset.IsValid() || hStream->GetPos() > bit_offset.ValueOrDie())
2614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
26233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  hStream->SkipBits((bit_offset - hStream->GetPos()).ValueOrDie());
2634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  const uint32_t kHeaderSize = 192;
2654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (hStream->BitsRemaining() < kHeaderSize)
2664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
2674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // Item 1: The object number of the first object in the shared objects
2694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // section.
2704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  uint32_t dwFirstSharedObjNum = hStream->GetBits(32);
2714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // Item 2: The location of the first object in the shared objects section.
2734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  uint32_t dwFirstSharedObjLoc = hStream->GetBits(32);
2744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (dwFirstSharedObjLoc > static_cast<uint32_t>(nStreamOffset))
2754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    dwFirstSharedObjLoc += nStreamLen;
2764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // Item 3: The number of shared object entries for the first page.
2784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  m_nFirstPageSharedObjs = hStream->GetBits(32);
2794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // Item 4: The number of shared object entries for the shared objects
2814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // section, including the number of shared object entries for the first page.
2824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  uint32_t dwSharedObjTotal = hStream->GetBits(32);
2834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // Item 5: The number of bits needed to represent the greatest number of
2854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // objects in a shared object group. Skipped.
2864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  hStream->SkipBits(16);
2874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // Item 6: The least length of a shared object group in bytes.
2894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  uint32_t dwGroupLeastLen = hStream->GetBits(32);
2904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // Item 7: The number of bits needed to represent the difference between the
2924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // greatest and least length of a shared object group, in bytes.
2934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  uint32_t dwDeltaGroupLen = hStream->GetBits(16);
2944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
295d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  // Trying to decode more than 32 bits isn't going to work when we write into
296d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  // a uint32_t.
297d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (dwDeltaGroupLen > 31)
298d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return false;
299d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
3004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (dwFirstSharedObjNum >= CPDF_Parser::kMaxObjectNumber ||
3014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      m_nFirstPageSharedObjs >= CPDF_Parser::kMaxObjectNumber ||
3024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      dwSharedObjTotal >= CPDF_Parser::kMaxObjectNumber) {
3034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
3044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
3054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int nFirstPageObjNum = GetFirstPageObjectNumber();
3074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (nFirstPageObjNum < 0)
3084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
3094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  uint32_t dwPrevObjLen = 0;
3114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  uint32_t dwCurObjLen = 0;
3124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  FX_SAFE_UINT32 required_bits = dwSharedObjTotal;
3134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  required_bits *= dwDeltaGroupLen;
3144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!CanReadFromBitStream(hStream, required_bits))
3154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
3164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  for (uint32_t i = 0; i < dwSharedObjTotal; ++i) {
3184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    dwPrevObjLen = dwCurObjLen;
3194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    FX_SAFE_UINT32 safeObjLen = hStream->GetBits(dwDeltaGroupLen);
3204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    safeObjLen += dwGroupLeastLen;
3214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (!safeObjLen.IsValid())
3224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return false;
3234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    dwCurObjLen = safeObjLen.ValueOrDie();
3254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (i < m_nFirstPageSharedObjs) {
3264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      m_dwSharedObjNumArray.push_back(nFirstPageObjNum + i);
3274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (i == 0)
3284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        m_szSharedObjOffsetArray.push_back(m_szFirstPageObjOffset);
3294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    } else {
3304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      FX_SAFE_UINT32 safeObjNum = dwFirstSharedObjNum;
3314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      safeObjNum += i - m_nFirstPageSharedObjs;
3324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (!safeObjNum.IsValid())
3334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        return false;
3344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      m_dwSharedObjNumArray.push_back(safeObjNum.ValueOrDie());
3364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (i == m_nFirstPageSharedObjs) {
3374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        FX_SAFE_FILESIZE safeLoc = dwFirstSharedObjLoc;
3384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        if (!safeLoc.IsValid())
3394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          return false;
3404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        m_szSharedObjOffsetArray.push_back(safeLoc.ValueOrDie());
3424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
3434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
3444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (i != 0 && i != m_nFirstPageSharedObjs) {
3464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      FX_SAFE_FILESIZE safeLoc = dwPrevObjLen;
3474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      safeLoc += m_szSharedObjOffsetArray[i - 1];
3484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (!safeLoc.IsValid())
3494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        return false;
3504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      m_szSharedObjOffsetArray.push_back(safeLoc.ValueOrDie());
3524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
3534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
3544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (dwSharedObjTotal > 0) {
3564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    FX_SAFE_FILESIZE safeLoc = dwCurObjLen;
3574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    safeLoc += m_szSharedObjOffsetArray[dwSharedObjTotal - 1];
3584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (!safeLoc.IsValid())
3594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return false;
3604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    m_szSharedObjOffsetArray.push_back(safeLoc.ValueOrDie());
3624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
3634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  hStream->ByteAlign();
3654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (hStream->BitsRemaining() < dwSharedObjTotal)
3664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
3674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  hStream->SkipBits(dwSharedObjTotal);
3694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  hStream->ByteAlign();
3704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return true;
3714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
3724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool CPDF_HintTables::GetPagePos(uint32_t index,
3744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                 FX_FILESIZE* szPageStartPos,
3754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                 FX_FILESIZE* szPageLength,
376d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                                 uint32_t* dwObjNum) const {
377d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (index >= m_pLinearized->GetPageCount())
378d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return false;
379d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
3804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  *szPageStartPos = m_szPageOffsetArray[index];
3814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  *szPageLength = GetItemLength(index, m_szPageOffsetArray);
3824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int nFirstPageObjNum = GetFirstPageObjectNumber();
3844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (nFirstPageObjNum < 0)
3854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
3864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int nFirstPageNum = GetFirstPageNumber();
3884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!pdfium::base::IsValueInRangeForNumericType<uint32_t>(nFirstPageNum))
3894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
3904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  uint32_t dwFirstPageNum = static_cast<uint32_t>(nFirstPageNum);
3924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (index == dwFirstPageNum) {
3934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *dwObjNum = nFirstPageObjNum;
3944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return true;
3954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
3964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // The object number of remaining pages starts from 1.
3984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  *dwObjNum = 1;
3994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  for (uint32_t i = 0; i < index; ++i) {
4004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (i == dwFirstPageNum)
4014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      continue;
4024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *dwObjNum += m_dwDeltaNObjsArray[i];
4034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
4044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return true;
4054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
4064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
407d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannCPDF_DataAvail::DocAvailStatus CPDF_HintTables::CheckPage(uint32_t index) {
4084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int nFirstPageNum = GetFirstPageNumber();
4094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!pdfium::base::IsValueInRangeForNumericType<uint32_t>(nFirstPageNum))
4104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return CPDF_DataAvail::DataError;
4114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (index == static_cast<uint32_t>(nFirstPageNum))
4134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return CPDF_DataAvail::DataAvailable;
4144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  uint32_t dwLength = GetItemLength(index, m_szPageOffsetArray);
4164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // If two pages have the same offset, it should be treated as an error.
4174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!dwLength)
4184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return CPDF_DataAvail::DataError;
4194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
420d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!m_pValidator->CheckDataRangeAndRequestIfUnavailable(
421d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          m_szPageOffsetArray[index], dwLength))
4224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return CPDF_DataAvail::DataNotAvailable;
4234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // Download data of shared objects in the page.
4254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  uint32_t offset = 0;
4264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  for (uint32_t i = 0; i < index; ++i)
4274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    offset += m_dwNSharedObjsArray[i];
4284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int nFirstPageObjNum = GetFirstPageObjectNumber();
4304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (nFirstPageObjNum < 0)
4314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return CPDF_DataAvail::DataError;
4324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  uint32_t dwIndex = 0;
4344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  uint32_t dwObjNum = 0;
4354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  for (uint32_t j = 0; j < m_dwNSharedObjsArray[index]; ++j) {
4364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    dwIndex = m_dwIdentifierArray[offset + j];
4374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (dwIndex >= m_dwSharedObjNumArray.size())
4384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return CPDF_DataAvail::DataNotAvailable;
4394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    dwObjNum = m_dwSharedObjNumArray[dwIndex];
4414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (dwObjNum >= static_cast<uint32_t>(nFirstPageObjNum) &&
4424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        dwObjNum <
4434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            static_cast<uint32_t>(nFirstPageObjNum) + m_nFirstPageSharedObjs) {
4444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      continue;
4454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
4464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    dwLength = GetItemLength(dwIndex, m_szSharedObjOffsetArray);
4484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    // If two objects have the same offset, it should be treated as an error.
4494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (!dwLength)
4504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return CPDF_DataAvail::DataError;
4514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
452d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (!m_pValidator->CheckDataRangeAndRequestIfUnavailable(
453d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            m_szSharedObjOffsetArray[dwIndex], dwLength)) {
4544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return CPDF_DataAvail::DataNotAvailable;
4554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
4564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
4574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return CPDF_DataAvail::DataAvailable;
4584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
4594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool CPDF_HintTables::LoadHintStream(CPDF_Stream* pHintStream) {
4614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!pHintStream)
4624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
4634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  CPDF_Dictionary* pDict = pHintStream->GetDict();
4654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  CPDF_Object* pOffset = pDict ? pDict->GetObjectFor("S") : nullptr;
4664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!pOffset || !pOffset->IsNumber())
4674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
4684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int shared_hint_table_offset = pOffset->GetInteger();
4704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (shared_hint_table_offset <= 0)
4714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
4724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
473d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  auto pAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pHintStream);
474d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  pAcc->LoadAllDataFiltered();
4754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
476d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  uint32_t size = pAcc->GetSize();
4774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // The header section of page offset hint table is 36 bytes.
4784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // The header section of shared object hint table is 24 bytes.
4794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  // Hint table has at least 60 bytes.
4804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  const uint32_t kMinStreamLength = 60;
4814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (size < kMinStreamLength)
4824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
4834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  FX_SAFE_UINT32 safe_shared_hint_table_offset = shared_hint_table_offset;
4854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!safe_shared_hint_table_offset.IsValid() ||
4864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      size < safe_shared_hint_table_offset.ValueOrDie()) {
4874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return false;
4884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
4894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
490d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  CFX_BitStream bs(pAcc->GetData(), size);
4914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return ReadPageHintTable(&bs) &&
4924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         ReadSharedObjHintTable(&bs, shared_hint_table_offset);
4934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
4944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint CPDF_HintTables::GetEndOfFirstPageOffset() const {
4964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return static_cast<int>(m_pLinearized->GetFirstPageEndOffset());
4974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
4984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint CPDF_HintTables::GetNumberOfPages() const {
5004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return static_cast<int>(m_pLinearized->GetPageCount());
5014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
5024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint CPDF_HintTables::GetFirstPageObjectNumber() const {
5044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return static_cast<int>(m_pLinearized->GetFirstPageObjNum());
5054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
5064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint CPDF_HintTables::GetFirstPageNumber() const {
5084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return static_cast<int>(m_pLinearized->GetFirstPageNo());
5094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
5104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint CPDF_HintTables::ReadPrimaryHintStreamOffset() const {
5124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return static_cast<int>(m_pLinearized->GetHintStart());
5134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
5144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint CPDF_HintTables::ReadPrimaryHintStreamLength() const {
5164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return static_cast<int>(m_pLinearized->GetHintLength());
5174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
518