| Index: core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp
|
| diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp
|
| index 51c779fb86e78dfbfa4d3b270d2c4ed0a8db769e..4aa99d08e33ace4766b20d12d3b3528e6d234784 100644
|
| --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp
|
| +++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp
|
| @@ -6,6 +6,7 @@
|
|
|
| #include "parser_int.h"
|
|
|
| +#include <algorithm>
|
| #include <memory>
|
| #include <set>
|
| #include <utility>
|
| @@ -619,21 +620,24 @@ FX_BOOL CPDF_Parser::RebuildCrossRef() {
|
| }
|
| int32_t status = 0;
|
| int32_t inside_index = 0;
|
| - FX_DWORD objnum = 0, gennum = 0;
|
| + FX_DWORD objnum = 0;
|
| + FX_DWORD gennum = 0;
|
| int32_t depth = 0;
|
| - uint8_t* buffer = FX_Alloc(uint8_t, 4096);
|
| + const FX_DWORD kBufferSize = 4096;
|
| + std::vector<uint8_t> buffer(kBufferSize);
|
| FX_FILESIZE pos = m_Syntax.m_HeaderOffset;
|
| - FX_FILESIZE start_pos = 0, start_pos1 = 0;
|
| - FX_FILESIZE last_obj = -1, last_xref = -1, last_trailer = -1;
|
| + FX_FILESIZE start_pos = 0;
|
| + FX_FILESIZE start_pos1 = 0;
|
| + FX_FILESIZE last_obj = -1;
|
| + FX_FILESIZE last_xref = -1;
|
| + FX_FILESIZE last_trailer = -1;
|
| while (pos < m_Syntax.m_FileLen) {
|
| - FX_BOOL bOverFlow = FALSE;
|
| - FX_DWORD size = (FX_DWORD)(m_Syntax.m_FileLen - pos);
|
| - if (size > 4096) {
|
| - size = 4096;
|
| - }
|
| - if (!m_Syntax.m_pFileAccess->ReadBlock(buffer, pos, size)) {
|
| + const FX_FILESIZE saved_pos = pos;
|
| + bool bOverFlow = false;
|
| + FX_DWORD size = std::min((FX_DWORD)(m_Syntax.m_FileLen - pos), kBufferSize);
|
| + if (!m_Syntax.m_pFileAccess->ReadBlock(buffer.data(), pos, size))
|
| break;
|
| - }
|
| +
|
| for (FX_DWORD i = 0; i < size; i++) {
|
| uint8_t byte = buffer[i];
|
| switch (status) {
|
| @@ -807,7 +811,7 @@ FX_BOOL CPDF_Parser::RebuildCrossRef() {
|
| FX_FILESIZE nLen = obj_end - obj_pos - offset;
|
| if ((FX_DWORD)nLen > size - i) {
|
| pos = obj_end + m_Syntax.m_HeaderOffset;
|
| - bOverFlow = TRUE;
|
| + bOverFlow = true;
|
| } else {
|
| i += (FX_DWORD)nLen;
|
| }
|
| @@ -854,11 +858,11 @@ FX_BOOL CPDF_Parser::RebuildCrossRef() {
|
| if (!pRoot ||
|
| (pRef && IsValidObjectNumber(pRef->GetRefObjNum()) &&
|
| m_ObjectInfo[pRef->GetRefObjNum()].pos != 0)) {
|
| - FX_POSITION pos = pTrailer->GetStartPos();
|
| - while (pos) {
|
| + FX_POSITION trailer_pos = pTrailer->GetStartPos();
|
| + while (trailer_pos) {
|
| CFX_ByteString key;
|
| CPDF_Object* pElement =
|
| - pTrailer->GetNextElement(pos, key);
|
| + pTrailer->GetNextElement(trailer_pos, key);
|
| FX_DWORD dwObjNum =
|
| pElement ? pElement->GetObjNum() : 0;
|
| if (dwObjNum) {
|
| @@ -965,6 +969,11 @@ FX_BOOL CPDF_Parser::RebuildCrossRef() {
|
| }
|
| }
|
| pos += size;
|
| +
|
| + // If the position has not changed at all in a loop iteration, then break
|
| + // out to prevent infinite looping.
|
| + if (pos == saved_pos)
|
| + break;
|
| }
|
| if (last_xref != -1 && last_xref > last_obj) {
|
| last_trailer = last_xref;
|
| @@ -978,7 +987,6 @@ FX_BOOL CPDF_Parser::RebuildCrossRef() {
|
| if (!pResult) {
|
| m_SortedOffset.Add(offset);
|
| }
|
| - FX_Free(buffer);
|
| return m_pTrailer && !m_ObjectInfo.empty();
|
| }
|
|
|
|
|