summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/include/fpdfapi/fpdf_parser.h10
-rw-r--r--core/include/fxcrt/fx_basic.h10
-rw-r--r--core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp330
-rw-r--r--core/src/fxcodec/codec/fx_codec_flate.cpp306
4 files changed, 322 insertions, 334 deletions
diff --git a/core/include/fpdfapi/fpdf_parser.h b/core/include/fpdfapi/fpdf_parser.h
index 6194247568..04c7d90f6f 100644
--- a/core/include/fpdfapi/fpdf_parser.h
+++ b/core/include/fpdfapi/fpdf_parser.h
@@ -453,10 +453,10 @@ class CPDF_Parser {
FX_BOOL LoadAllCrossRefV5(FX_FILESIZE pos);
- FX_BOOL LoadCrossRefV4(FX_FILESIZE pos,
- FX_FILESIZE streampos,
- FX_BOOL bSkip,
- FX_BOOL bFirst);
+ bool LoadCrossRefV4(FX_FILESIZE pos,
+ FX_FILESIZE streampos,
+ FX_BOOL bSkip,
+ FX_BOOL bFirst);
FX_BOOL LoadCrossRefV5(FX_FILESIZE pos, FX_FILESIZE& prev, FX_BOOL bMainXRef);
@@ -482,6 +482,8 @@ class CPDF_Parser {
FX_BOOL IsLinearizedFile(IFX_FileRead* pFileAccess, FX_DWORD offset);
+ bool FindPosInOffsets(FX_FILESIZE pos) const;
+
int m_FileVersion;
CPDF_Dictionary* m_pTrailer;
diff --git a/core/include/fxcrt/fx_basic.h b/core/include/fxcrt/fx_basic.h
index 62d2a09476..b85d737327 100644
--- a/core/include/fxcrt/fx_basic.h
+++ b/core/include/fxcrt/fx_basic.h
@@ -1065,15 +1065,13 @@ class CFX_DataFilter {
template <typename T>
class CFX_AutoRestorer {
public:
- explicit CFX_AutoRestorer(T* location) {
- m_Location = location;
- m_OldValue = *location;
- }
+ explicit CFX_AutoRestorer(T* location)
+ : m_Location(location), m_OldValue(*location) {}
~CFX_AutoRestorer() { *m_Location = m_OldValue; }
private:
- T* m_Location;
- T m_OldValue;
+ T* const m_Location;
+ const T m_OldValue;
};
struct FxFreeDeleter {
diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp
index 8b30112cf8..1f7a42f48d 100644
--- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp
+++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp
@@ -8,12 +8,59 @@
#include <utility>
#include <vector>
+#include "../../../../third_party/base/nonstd_unique_ptr.h"
#include "../../../include/fpdfapi/fpdf_module.h"
#include "../../../include/fpdfapi/fpdf_page.h"
#include "../../../include/fpdfapi/fpdf_parser.h"
#include "../../../include/fxcrt/fx_safe_types.h"
#include "../fpdf_page/pageint.h"
+namespace {
+
+int CompareFileSize(const void* p1, const void* p2) {
+ return *(FX_FILESIZE*)p1 - *(FX_FILESIZE*)p2;
+}
+
+int32_t GetHeaderOffset(IFX_FileRead* pFile) {
+ const FX_DWORD tag = FXDWORD_FROM_LSBFIRST(0x46445025);
+ const size_t kBufSize = 4;
+ uint8_t buf[kBufSize];
+ int32_t offset = 0;
+ while (offset <= 1024) {
+ if (!pFile->ReadBlock(buf, offset, kBufSize))
+ return -1;
+
+ if (*(FX_DWORD*)buf == tag)
+ return offset;
+
+ ++offset;
+ }
+ return -1;
+}
+
+int32_t GetDirectInteger(CPDF_Dictionary* pDict, const CFX_ByteStringC& key) {
+ CPDF_Object* pObj = pDict->GetElement(key);
+ if (pObj && (pObj->GetType() == PDFOBJ_NUMBER))
+ return ((CPDF_Number*)pObj)->GetInteger();
+ return 0;
+}
+
+bool CheckDirectType(CPDF_Dictionary* pDict,
+ const CFX_ByteStringC& key,
+ int32_t iType) {
+ CPDF_Object* pObj = pDict->GetElement(key);
+ return !pObj || pObj->GetType() == iType;
+}
+
+FX_DWORD GetVarInt(const uint8_t* p, int32_t n) {
+ FX_DWORD result = 0;
+ for (int32_t i = 0; i < n; ++i)
+ result = result * 256 + p[i];
+ return result;
+}
+
+} // namespace
+
FX_BOOL IsSignatureDict(const CPDF_Dictionary* pDict) {
CPDF_Object* pType = pDict->GetElementValue(FX_BSTRC("Type"));
if (!pType) {
@@ -27,19 +74,6 @@ FX_BOOL IsSignatureDict(const CPDF_Dictionary* pDict) {
}
return FALSE;
}
-static int32_t _CompareDWord(const void* p1, const void* p2) {
- return (*(FX_DWORD*)p1) - (*(FX_DWORD*)p2);
-}
-static int _CompareFileSize(const void* p1, const void* p2) {
- FX_FILESIZE ret = (*(FX_FILESIZE*)p1) - (*(FX_FILESIZE*)p2);
- if (ret > 0) {
- return 1;
- }
- if (ret < 0) {
- return -1;
- }
- return 0;
-}
CPDF_Parser::CPDF_Parser() {
m_pDocument = NULL;
@@ -102,24 +136,6 @@ void CPDF_Parser::CloseParser(FX_BOOL bReParse) {
m_pLinearized = NULL;
}
}
-static int32_t GetHeaderOffset(IFX_FileRead* pFile) {
- FX_DWORD tag = FXDWORD_FROM_LSBFIRST(0x46445025);
- uint8_t buf[4];
- int32_t offset = 0;
- while (1) {
- if (!pFile->ReadBlock(buf, offset, 4)) {
- return -1;
- }
- if (*(FX_DWORD*)buf == tag) {
- return offset;
- }
- offset++;
- if (offset > 1024) {
- return -1;
- }
- }
- return -1;
-}
CPDF_SecurityHandler* FPDF_CreateStandardSecurityHandler();
CPDF_SecurityHandler* FPDF_CreatePubKeyHandler(void*);
FX_DWORD CPDF_Parser::StartParse(IFX_FileRead* pFileAccess,
@@ -162,7 +178,7 @@ FX_DWORD CPDF_Parser::StartParse(IFX_FileRead* pFileAccess,
FX_FILESIZE startxref_offset = m_Syntax.SavePos();
void* pResult = FXSYS_bsearch(&startxref_offset, m_SortedOffset.GetData(),
m_SortedOffset.GetSize(), sizeof(FX_FILESIZE),
- _CompareFileSize);
+ CompareFileSize);
if (pResult == NULL) {
m_SortedOffset.Add(startxref_offset);
}
@@ -210,7 +226,7 @@ FX_DWORD CPDF_Parser::StartParse(IFX_FileRead* pFileAccess,
}
}
FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(),
- sizeof(FX_FILESIZE), _CompareFileSize);
+ sizeof(FX_FILESIZE), CompareFileSize);
FX_DWORD RootObjNum = GetRootObjNum();
if (RootObjNum == 0) {
ReleaseEncryptHandler();
@@ -316,26 +332,7 @@ FX_FILESIZE CPDF_Parser::GetObjectOffset(FX_DWORD objnum) {
}
return 0;
}
-static int32_t GetDirectInteger(CPDF_Dictionary* pDict,
- const CFX_ByteStringC& key) {
- CPDF_Object* pObj = pDict->GetElement(key);
- if (pObj == NULL) {
- return 0;
- }
- if (pObj->GetType() == PDFOBJ_NUMBER) {
- return ((CPDF_Number*)pObj)->GetInteger();
- }
- return 0;
-}
-static FX_BOOL CheckDirectType(CPDF_Dictionary* pDict,
- const CFX_ByteStringC& key,
- int32_t iType) {
- CPDF_Object* pObj = pDict->GetElement(key);
- if (!pObj) {
- return TRUE;
- }
- return pObj->GetType() == iType;
-}
+
FX_BOOL CPDF_Parser::LoadAllCrossRefV4(FX_FILESIZE xrefpos) {
if (!LoadCrossRefV4(xrefpos, 0, TRUE, FALSE)) {
return FALSE;
@@ -427,7 +424,7 @@ FX_BOOL CPDF_Parser::LoadLinearizedCrossRefV4(FX_FILESIZE pos,
m_Syntax.RestorePos(dwStartPos);
void* pResult =
FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(),
- sizeof(FX_FILESIZE), _CompareFileSize);
+ sizeof(FX_FILESIZE), CompareFileSize);
if (pResult == NULL) {
m_SortedOffset.Add(pos);
}
@@ -474,7 +471,7 @@ FX_BOOL CPDF_Parser::LoadLinearizedCrossRefV4(FX_FILESIZE pos,
if (m_CrossRef[objnum] < m_Syntax.m_FileLen) {
void* pResult = FXSYS_bsearch(
&m_CrossRef[objnum], m_SortedOffset.GetData(),
- m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
+ m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), CompareFileSize);
if (pResult == NULL) {
m_SortedOffset.Add(m_CrossRef[objnum]);
}
@@ -487,51 +484,48 @@ FX_BOOL CPDF_Parser::LoadLinearizedCrossRefV4(FX_FILESIZE pos,
m_Syntax.RestorePos(SavedPos + count * recordsize);
return TRUE;
}
-FX_BOOL CPDF_Parser::LoadCrossRefV4(FX_FILESIZE pos,
- FX_FILESIZE streampos,
- FX_BOOL bSkip,
- FX_BOOL bFirst) {
+
+bool CPDF_Parser::FindPosInOffsets(FX_FILESIZE pos) const {
+ return FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(),
+ sizeof(FX_FILESIZE), CompareFileSize);
+}
+
+bool CPDF_Parser::LoadCrossRefV4(FX_FILESIZE pos,
+ FX_FILESIZE streampos,
+ FX_BOOL bSkip,
+ FX_BOOL bFirst) {
m_Syntax.RestorePos(pos);
- if (m_Syntax.GetKeyword() != FX_BSTRC("xref")) {
- return FALSE;
- }
- void* pResult =
- FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(),
- sizeof(FX_FILESIZE), _CompareFileSize);
- if (pResult == NULL) {
+ if (m_Syntax.GetKeyword() != FX_BSTRC("xref"))
+ return false;
+
+ if (!FindPosInOffsets(pos))
m_SortedOffset.Add(pos);
- }
- if (streampos) {
- void* pResult = FXSYS_bsearch(&streampos, m_SortedOffset.GetData(),
- m_SortedOffset.GetSize(), sizeof(FX_FILESIZE),
- _CompareFileSize);
- if (pResult == NULL) {
+
+ if (streampos && !FindPosInOffsets(streampos))
m_SortedOffset.Add(streampos);
- }
- }
+
while (1) {
FX_FILESIZE SavedPos = m_Syntax.SavePos();
FX_BOOL bIsNumber;
CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber);
- if (word.IsEmpty()) {
- return FALSE;
- }
+ if (word.IsEmpty())
+ return false;
+
if (!bIsNumber) {
m_Syntax.RestorePos(SavedPos);
break;
}
FX_DWORD start_objnum = FXSYS_atoi(word);
- if (start_objnum >= (1 << 20)) {
- return FALSE;
- }
+ if (start_objnum >= (1 << 20))
+ return false;
+
FX_DWORD count = m_Syntax.GetDirectNum();
m_Syntax.ToNextWord();
SavedPos = m_Syntax.SavePos();
FX_BOOL bFirstItem = FALSE;
int32_t recordsize = 20;
- if (bFirst) {
+ if (bFirst)
bFirstItem = TRUE;
- }
m_dwXrefStartObjNum = start_objnum;
if (!bSkip) {
char* pBuf = FX_Alloc(char, 1024 * recordsize + 1);
@@ -565,7 +559,7 @@ FX_BOOL CPDF_Parser::LoadCrossRefV4(FX_FILESIZE pos,
for (int32_t c = 0; c < 10; c++) {
if (pEntry[c] < '0' || pEntry[c] > '9') {
FX_Free(pBuf);
- return FALSE;
+ return false;
}
}
}
@@ -575,14 +569,9 @@ FX_BOOL CPDF_Parser::LoadCrossRefV4(FX_FILESIZE pos,
m_bVersionUpdated = TRUE;
}
m_ObjVersion.SetAtGrow(objnum, version);
- if (m_CrossRef[objnum] < m_Syntax.m_FileLen) {
- void* pResult =
- FXSYS_bsearch(&m_CrossRef[objnum], m_SortedOffset.GetData(),
- m_SortedOffset.GetSize(), sizeof(FX_FILESIZE),
- _CompareFileSize);
- if (pResult == NULL) {
- m_SortedOffset.Add(m_CrossRef[objnum]);
- }
+ if (m_CrossRef[objnum] < m_Syntax.m_FileLen &&
+ !FindPosInOffsets(m_CrossRef[objnum])) {
+ m_SortedOffset.Add(m_CrossRef[objnum]);
}
m_V5Type.SetAtGrow(objnum, 1);
}
@@ -595,12 +584,9 @@ FX_BOOL CPDF_Parser::LoadCrossRefV4(FX_FILESIZE pos,
}
m_Syntax.RestorePos(SavedPos + count * recordsize);
}
- if (streampos)
- if (!LoadCrossRefV5(streampos, streampos, FALSE)) {
- return FALSE;
- }
- return TRUE;
+ return !streampos || LoadCrossRefV5(streampos, streampos, FALSE);
}
+
FX_BOOL CPDF_Parser::LoadAllCrossRefV5(FX_FILESIZE xrefpos) {
if (!LoadCrossRefV5(xrefpos, xrefpos, TRUE)) {
return FALSE;
@@ -775,7 +761,7 @@ FX_BOOL CPDF_Parser::RebuildCrossRef() {
void* pResult =
FXSYS_bsearch(&obj_pos, m_SortedOffset.GetData(),
m_SortedOffset.GetSize(), sizeof(FX_FILESIZE),
- _CompareFileSize);
+ CompareFileSize);
if (pResult == NULL) {
m_SortedOffset.Add(obj_pos);
}
@@ -993,20 +979,14 @@ FX_BOOL CPDF_Parser::RebuildCrossRef() {
FX_FILESIZE offset = last_trailer - m_Syntax.m_HeaderOffset;
void* pResult =
FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(),
- sizeof(FX_FILESIZE), _CompareFileSize);
+ sizeof(FX_FILESIZE), CompareFileSize);
if (pResult == NULL) {
m_SortedOffset.Add(offset);
}
FX_Free(buffer);
return TRUE;
}
-static FX_DWORD _GetVarInt(const uint8_t* p, int32_t n) {
- FX_DWORD result = 0;
- for (int32_t i = 0; i < n; i++) {
- result = result * 256 + p[i];
- }
- return result;
-}
+
FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE pos,
FX_FILESIZE& prev,
FX_BOOL bMainXRef) {
@@ -1113,15 +1093,15 @@ FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE pos,
int32_t type = 1;
const uint8_t* entrystart = segstart + j * totalWidth;
if (WidthArray[0]) {
- type = _GetVarInt(entrystart, WidthArray[0]);
+ type = GetVarInt(entrystart, WidthArray[0]);
}
if (m_V5Type[startnum + j] == 255) {
FX_FILESIZE offset =
- _GetVarInt(entrystart + WidthArray[0], WidthArray[1]);
+ GetVarInt(entrystart + WidthArray[0], WidthArray[1]);
m_CrossRef[startnum + j] = offset;
void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(),
m_SortedOffset.GetSize(),
- sizeof(FX_FILESIZE), _CompareFileSize);
+ sizeof(FX_FILESIZE), CompareFileSize);
if (pResult == NULL) {
m_SortedOffset.Add(offset);
}
@@ -1135,12 +1115,12 @@ FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE pos,
m_CrossRef[startnum + j] = 0;
} else {
FX_FILESIZE offset =
- _GetVarInt(entrystart + WidthArray[0], WidthArray[1]);
+ GetVarInt(entrystart + WidthArray[0], WidthArray[1]);
m_CrossRef[startnum + j] = offset;
if (type == 1) {
void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(),
m_SortedOffset.GetSize(),
- sizeof(FX_FILESIZE), _CompareFileSize);
+ sizeof(FX_FILESIZE), CompareFileSize);
if (pResult == NULL) {
m_SortedOffset.Add(offset);
}
@@ -1202,7 +1182,7 @@ FX_BOOL CPDF_Parser::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm) {
FX_FILESIZE pos = m_CrossRef[objnum];
void* pResult =
FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(),
- sizeof(FX_FILESIZE), _CompareFileSize);
+ sizeof(FX_FILESIZE), CompareFileSize);
if (pResult == NULL) {
return TRUE;
}
@@ -1285,7 +1265,7 @@ FX_FILESIZE CPDF_Parser::GetObjectSize(FX_DWORD objnum) {
}
void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(),
m_SortedOffset.GetSize(), sizeof(FX_FILESIZE),
- _CompareFileSize);
+ CompareFileSize);
if (pResult == NULL) {
return 0;
}
@@ -1366,7 +1346,7 @@ void CPDF_Parser::GetIndirectBinary(FX_DWORD objnum,
}
void* pResult =
FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(),
- sizeof(FX_FILESIZE), _CompareFileSize);
+ sizeof(FX_FILESIZE), CompareFileSize);
if (pResult == NULL) {
m_Syntax.RestorePos(SavedPos);
return;
@@ -1645,7 +1625,7 @@ FX_DWORD CPDF_Parser::StartAsynParse(IFX_FileRead* pFileAccess,
}
}
FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(),
- sizeof(FX_FILESIZE), _CompareFileSize);
+ sizeof(FX_FILESIZE), CompareFileSize);
FX_DWORD RootObjNum = GetRootObjNum();
if (RootObjNum == 0) {
ReleaseEncryptHandler();
@@ -1717,7 +1697,7 @@ FX_DWORD CPDF_Parser::LoadLinearizedMainXRefTable() {
return PDFPARSE_ERROR_FORMAT;
}
FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(),
- sizeof(FX_FILESIZE), _CompareFileSize);
+ sizeof(FX_FILESIZE), CompareFileSize);
m_Syntax.m_MetadataObjnum = dwSaveMetadataObjnum;
return PDFPARSE_ERROR_SUCCESS;
}
@@ -1738,13 +1718,13 @@ CPDF_SyntaxParser::CPDF_SyntaxParser() {
CPDF_SyntaxParser::~CPDF_SyntaxParser() {
FX_Free(m_pFileBuf);
}
+
FX_BOOL CPDF_SyntaxParser::GetCharAt(FX_FILESIZE pos, uint8_t& ch) {
- FX_FILESIZE save_pos = m_Pos;
+ CFX_AutoRestorer<FX_FILESIZE> save_pos(&m_Pos);
m_Pos = pos;
- FX_BOOL ret = GetNextChar(ch);
- m_Pos = save_pos;
- return ret;
+ return GetNextChar(ch);
}
+
FX_BOOL CPDF_SyntaxParser::GetNextChar(uint8_t& ch) {
FX_FILESIZE pos = m_Pos + m_HeaderOffset;
if (pos >= m_FileLen) {
@@ -2699,76 +2679,67 @@ FX_BOOL CPDF_SyntaxParser::SearchWord(const CFX_ByteStringC& tag,
}
return FALSE;
}
+
struct _SearchTagRecord {
const uint8_t* m_pTag;
FX_DWORD m_Len;
FX_DWORD m_Offset;
};
+
int32_t CPDF_SyntaxParser::SearchMultiWord(const CFX_ByteStringC& tags,
FX_BOOL bWholeWord,
FX_FILESIZE limit) {
- int32_t ntags = 1, i;
- for (i = 0; i < tags.GetLength(); i++)
+ int32_t ntags = 1;
+ for (int i = 0; i < tags.GetLength(); ++i) {
if (tags[i] == 0) {
- ntags++;
+ ++ntags;
}
- _SearchTagRecord* pPatterns = FX_Alloc(_SearchTagRecord, ntags);
- FX_DWORD start = 0, itag = 0, max_len = 0;
- for (i = 0; i <= tags.GetLength(); i++) {
+ }
+
+ std::vector<_SearchTagRecord> patterns(ntags);
+ FX_DWORD start = 0;
+ FX_DWORD itag = 0;
+ FX_DWORD max_len = 0;
+ for (int i = 0; i <= tags.GetLength(); ++i) {
if (tags[i] == 0) {
FX_DWORD len = i - start;
- if (len > max_len) {
- max_len = len;
- }
- pPatterns[itag].m_pTag = tags.GetPtr() + start;
- pPatterns[itag].m_Len = len;
- pPatterns[itag].m_Offset = 0;
+ max_len = std::max(len, max_len);
+ patterns[itag].m_pTag = tags.GetPtr() + start;
+ patterns[itag].m_Len = len;
+ patterns[itag].m_Offset = 0;
start = i + 1;
- itag++;
+ ++itag;
}
}
- FX_FILESIZE pos = m_Pos;
- uint8_t byte;
- GetCharAt(pos++, byte);
- int32_t found = -1;
- while (1) {
- for (i = 0; i < ntags; i++) {
- if (pPatterns[i].m_pTag[pPatterns[i].m_Offset] == byte) {
- pPatterns[i].m_Offset++;
- if (pPatterns[i].m_Offset == pPatterns[i].m_Len) {
- if (!bWholeWord ||
- IsWholeWord(pos - pPatterns[i].m_Len, limit, pPatterns[i].m_pTag,
- pPatterns[i].m_Len, FALSE)) {
- found = i;
- goto end;
- } else {
- if (pPatterns[i].m_pTag[0] == byte) {
- pPatterns[i].m_Offset = 1;
- } else {
- pPatterns[i].m_Offset = 0;
- }
- }
- }
- } else {
- if (pPatterns[i].m_pTag[0] == byte) {
- pPatterns[i].m_Offset = 1;
- } else {
- pPatterns[i].m_Offset = 0;
- }
+
+ const FX_FILESIZE pos_limit = m_Pos + limit;
+ for (FX_FILESIZE pos = m_Pos; !limit || pos < pos_limit; ++pos) {
+ uint8_t byte;
+ if (!GetCharAt(pos, byte))
+ break;
+
+ for (int i = 0; i < ntags; ++i) {
+ _SearchTagRecord& pat = patterns[i];
+ if (pat.m_pTag[pat.m_Offset] != byte) {
+ pat.m_Offset = (pat.m_pTag[0] == byte) ? 1 : 0;
+ continue;
}
+
+ ++pat.m_Offset;
+ if (pat.m_Offset != pat.m_Len)
+ continue;
+
+ if (!bWholeWord ||
+ IsWholeWord(pos - pat.m_Len, limit, pat.m_pTag, pat.m_Len, FALSE)) {
+ return i;
+ }
+
+ pat.m_Offset = (pat.m_pTag[0] == byte) ? 1 : 0;
}
- if (limit && pos >= m_Pos + limit) {
- goto end;
- }
- if (!GetCharAt(pos, byte)) {
- goto end;
- }
- pos++;
}
-end:
- FX_Free(pPatterns);
- return found;
+ return -1;
}
+
FX_FILESIZE CPDF_SyntaxParser::FindTag(const CFX_ByteStringC& tag,
FX_FILESIZE limit) {
int32_t taglen = tag.GetLength();
@@ -2813,20 +2784,19 @@ class CPDF_DataAvail final : public IPDF_DataAvail {
CPDF_DataAvail(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRead);
~CPDF_DataAvail() override;
- virtual FX_BOOL IsDocAvail(IFX_DownloadHints* pHints) override;
+ FX_BOOL IsDocAvail(IFX_DownloadHints* pHints) override;
- virtual void SetDocument(CPDF_Document* pDoc) override;
+ void SetDocument(CPDF_Document* pDoc) override;
- virtual FX_BOOL IsPageAvail(int iPage, IFX_DownloadHints* pHints) override;
+ FX_BOOL IsPageAvail(int iPage, IFX_DownloadHints* pHints) override;
- virtual int32_t IsFormAvail(IFX_DownloadHints* pHints) override;
+ int32_t IsFormAvail(IFX_DownloadHints* pHints) override;
- virtual int32_t IsLinearizedPDF() override;
+ int32_t IsLinearizedPDF() override;
- virtual FX_BOOL IsLinearized() override { return m_bLinearized; }
+ FX_BOOL IsLinearized() override { return m_bLinearized; }
- virtual void GetLinearizedMainXRefInfo(FX_FILESIZE* pPos,
- FX_DWORD* pSize) override;
+ void GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, FX_DWORD* pSize) override;
protected:
static const int kMaxDataAvailRecursionDepth = 64;
@@ -3106,7 +3076,7 @@ FX_DWORD CPDF_DataAvail::GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset) {
}
void* pResult = FXSYS_bsearch(&offset, pParser->m_SortedOffset.GetData(),
pParser->m_SortedOffset.GetSize(),
- sizeof(FX_FILESIZE), _CompareFileSize);
+ sizeof(FX_FILESIZE), CompareFileSize);
if (pResult == NULL) {
return 0;
}
@@ -3358,7 +3328,7 @@ FX_BOOL CPDF_DataAvail::LoadAllXref(IFX_DownloadHints* pHints) {
}
FXSYS_qsort(m_parser.m_SortedOffset.GetData(),
m_parser.m_SortedOffset.GetSize(), sizeof(FX_FILESIZE),
- _CompareFileSize);
+ CompareFileSize);
m_dwRootObjNum = m_parser.GetRootObjNum();
m_dwInfoObjNum = m_parser.GetInfoObjNum();
m_pCurrentParser = &m_parser;
diff --git a/core/src/fxcodec/codec/fx_codec_flate.cpp b/core/src/fxcodec/codec/fx_codec_flate.cpp
index 37aecf106d..519ff00522 100644
--- a/core/src/fxcodec/codec/fx_codec_flate.cpp
+++ b/core/src/fxcodec/codec/fx_codec_flate.cpp
@@ -75,6 +75,8 @@ void FPDFAPI_FlateEnd(void* context) {
}
} // extern "C"
+namespace {
+
class CLZWDecoder {
public:
int Decode(uint8_t* output,
@@ -222,7 +224,8 @@ int CLZWDecoder::Decode(uint8_t* dest_buf,
src_size = (m_InPos + 7) / 8;
return 0;
}
-static uint8_t PaethPredictor(int a, int b, int c) {
+
+uint8_t PaethPredictor(int a, int b, int c) {
int p = a + b - c;
int pa = FXSYS_abs(p - a);
int pb = FXSYS_abs(p - b);
@@ -235,12 +238,13 @@ static uint8_t PaethPredictor(int a, int b, int c) {
}
return (uint8_t)c;
}
-static FX_BOOL PNG_PredictorEncode(uint8_t*& data_buf,
- FX_DWORD& data_size,
- int predictor,
- int Colors,
- int BitsPerComponent,
- int Columns) {
+
+FX_BOOL PNG_PredictorEncode(uint8_t*& data_buf,
+ FX_DWORD& data_size,
+ int predictor,
+ int Colors,
+ int BitsPerComponent,
+ int Columns) {
const int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8;
const int row_size = (Colors * BitsPerComponent * Columns + 7) / 8;
if (row_size <= 0)
@@ -324,12 +328,13 @@ static FX_BOOL PNG_PredictorEncode(uint8_t*& data_buf,
(last_row_size > 0 ? (row_size - last_row_size) : 0);
return TRUE;
}
-static void PNG_PredictLine(uint8_t* pDestData,
- const uint8_t* pSrcData,
- const uint8_t* pLastLine,
- int bpc,
- int nColors,
- int nPixels) {
+
+void PNG_PredictLine(uint8_t* pDestData,
+ const uint8_t* pSrcData,
+ const uint8_t* pLastLine,
+ int bpc,
+ int nColors,
+ int nPixels) {
int row_size = (nPixels * bpc * nColors + 7) / 8;
int BytesPerPixel = (bpc * nColors + 7) / 8;
uint8_t tag = pSrcData[0];
@@ -390,11 +395,12 @@ static void PNG_PredictLine(uint8_t* pDestData,
}
}
}
-static FX_BOOL PNG_Predictor(uint8_t*& data_buf,
- FX_DWORD& data_size,
- int Colors,
- int BitsPerComponent,
- int Columns) {
+
+FX_BOOL PNG_Predictor(uint8_t*& data_buf,
+ FX_DWORD& data_size,
+ int Colors,
+ int BitsPerComponent,
+ int Columns) {
const int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8;
const int row_size = (Colors * BitsPerComponent * Columns + 7) / 8;
if (row_size <= 0)
@@ -483,11 +489,12 @@ static FX_BOOL PNG_Predictor(uint8_t*& data_buf,
(last_row_size > 0 ? (row_size + 1 - last_row_size) : 0);
return TRUE;
}
-static void TIFF_PredictorEncodeLine(uint8_t* dest_buf,
- int row_size,
- int BitsPerComponent,
- int Colors,
- int Columns) {
+
+void TIFF_PredictorEncodeLine(uint8_t* dest_buf,
+ int row_size,
+ int BitsPerComponent,
+ int Colors,
+ int Columns) {
int BytesPerPixel = BitsPerComponent * Colors / 8;
if (BitsPerComponent < 8) {
uint8_t mask = 0x01;
@@ -528,11 +535,12 @@ static void TIFF_PredictorEncodeLine(uint8_t* dest_buf,
}
}
}
-static FX_BOOL TIFF_PredictorEncode(uint8_t*& data_buf,
- FX_DWORD& data_size,
- int Colors,
- int BitsPerComponent,
- int Columns) {
+
+FX_BOOL TIFF_PredictorEncode(uint8_t*& data_buf,
+ FX_DWORD& data_size,
+ int Colors,
+ int BitsPerComponent,
+ int Columns) {
int row_size = (Colors * BitsPerComponent * Columns + 7) / 8;
if (row_size == 0)
return FALSE;
@@ -548,11 +556,12 @@ static FX_BOOL TIFF_PredictorEncode(uint8_t*& data_buf,
}
return TRUE;
}
-static void TIFF_PredictLine(uint8_t* dest_buf,
- int row_size,
- int BitsPerComponent,
- int Colors,
- int Columns) {
+
+void TIFF_PredictLine(uint8_t* dest_buf,
+ int row_size,
+ int BitsPerComponent,
+ int Colors,
+ int Columns) {
if (BitsPerComponent == 1) {
int row_bits = FX_MIN(BitsPerComponent * Colors * Columns, row_size * 8);
int index_pre = 0;
@@ -586,11 +595,12 @@ static void TIFF_PredictLine(uint8_t* dest_buf,
}
}
}
-static FX_BOOL TIFF_Predictor(uint8_t*& data_buf,
- FX_DWORD& data_size,
- int Colors,
- int BitsPerComponent,
- int Columns) {
+
+FX_BOOL TIFF_Predictor(uint8_t*& data_buf,
+ FX_DWORD& data_size,
+ int Colors,
+ int BitsPerComponent,
+ int Columns) {
int row_size = (Colors * BitsPerComponent * Columns + 7) / 8;
if (row_size == 0)
return FALSE;
@@ -606,6 +616,120 @@ static FX_BOOL TIFF_Predictor(uint8_t*& data_buf,
return TRUE;
}
+void FlateUncompress(const uint8_t* src_buf,
+ FX_DWORD src_size,
+ FX_DWORD orig_size,
+ uint8_t*& dest_buf,
+ FX_DWORD& dest_size,
+ FX_DWORD& offset) {
+ FX_DWORD guess_size = orig_size ? orig_size : src_size * 2;
+ const FX_DWORD kStepSize = 10240;
+ FX_DWORD alloc_step = orig_size ? kStepSize : std::min(src_size, kStepSize);
+ static const FX_DWORD kMaxInitialAllocSize = 10000000;
+ if (guess_size > kMaxInitialAllocSize) {
+ guess_size = kMaxInitialAllocSize;
+ alloc_step = kMaxInitialAllocSize;
+ }
+ FX_DWORD buf_size = guess_size;
+ FX_DWORD last_buf_size = buf_size;
+
+ dest_buf = nullptr;
+ dest_size = 0;
+ void* context = FPDFAPI_FlateInit(my_alloc_func, my_free_func);
+ if (!context)
+ return;
+
+ nonstd::unique_ptr<uint8_t, FxFreeDeleter> guess_buf(
+ FX_Alloc(uint8_t, guess_size + 1));
+ guess_buf.get()[guess_size] = '\0';
+
+ FPDFAPI_FlateInput(context, src_buf, src_size);
+
+ if (src_size < kStepSize) {
+ // This is the old implementation.
+ uint8_t* cur_buf = guess_buf.get();
+ while (1) {
+ int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size);
+ if (ret != Z_OK)
+ break;
+ int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context);
+ if (avail_buf_size != 0)
+ break;
+
+ FX_DWORD old_size = guess_size;
+ guess_size += alloc_step;
+ if (guess_size < old_size || guess_size + 1 < guess_size) {
+ FPDFAPI_FlateEnd(context);
+ return;
+ }
+
+ {
+ uint8_t* new_buf =
+ FX_Realloc(uint8_t, guess_buf.release(), guess_size + 1);
+ guess_buf.reset(new_buf);
+ }
+ guess_buf.get()[guess_size] = '\0';
+ cur_buf = guess_buf.get() + old_size;
+ buf_size = guess_size - old_size;
+ }
+ dest_size = FPDFAPI_FlateGetTotalOut(context);
+ offset = FPDFAPI_FlateGetTotalIn(context);
+ if (guess_size / 2 > dest_size) {
+ {
+ uint8_t* new_buf =
+ FX_Realloc(uint8_t, guess_buf.release(), dest_size + 1);
+ guess_buf.reset(new_buf);
+ }
+ guess_size = dest_size;
+ guess_buf.get()[guess_size] = '\0';
+ }
+ dest_buf = guess_buf.release();
+ } else {
+ CFX_ArrayTemplate<uint8_t*> result_tmp_bufs;
+ uint8_t* cur_buf = guess_buf.release();
+ while (1) {
+ int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size);
+ int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context);
+ if (ret != Z_OK) {
+ last_buf_size = buf_size - avail_buf_size;
+ result_tmp_bufs.Add(cur_buf);
+ break;
+ }
+ if (avail_buf_size != 0) {
+ last_buf_size = buf_size - avail_buf_size;
+ result_tmp_bufs.Add(cur_buf);
+ break;
+ }
+
+ result_tmp_bufs.Add(cur_buf);
+ cur_buf = FX_Alloc(uint8_t, buf_size + 1);
+ cur_buf[buf_size] = '\0';
+ }
+ dest_size = FPDFAPI_FlateGetTotalOut(context);
+ offset = FPDFAPI_FlateGetTotalIn(context);
+ if (result_tmp_bufs.GetSize() == 1) {
+ dest_buf = result_tmp_bufs[0];
+ } else {
+ uint8_t* result_buf = FX_Alloc(uint8_t, dest_size);
+ FX_DWORD result_pos = 0;
+ for (int32_t i = 0; i < result_tmp_bufs.GetSize(); i++) {
+ uint8_t* tmp_buf = result_tmp_bufs[i];
+ FX_DWORD tmp_buf_size = buf_size;
+ if (i == result_tmp_bufs.GetSize() - 1) {
+ tmp_buf_size = last_buf_size;
+ }
+ FXSYS_memcpy(result_buf + result_pos, tmp_buf, tmp_buf_size);
+ result_pos += tmp_buf_size;
+ FX_Free(result_tmp_bufs[i]);
+ }
+ dest_buf = result_buf;
+ }
+ }
+ FPDFAPI_FlateEnd(context);
+}
+
+} // namespace
+
class CCodec_FlateScanlineDecoder : public CCodec_ScanlineDecoder {
public:
CCodec_FlateScanlineDecoder();
@@ -761,113 +885,7 @@ uint8_t* CCodec_FlateScanlineDecoder::v_GetNextLine() {
FX_DWORD CCodec_FlateScanlineDecoder::GetSrcOffset() {
return FPDFAPI_FlateGetTotalIn(m_pFlate);
}
-static void FlateUncompress(const uint8_t* src_buf,
- FX_DWORD src_size,
- FX_DWORD orig_size,
- uint8_t*& dest_buf,
- FX_DWORD& dest_size,
- FX_DWORD& offset) {
- const FX_BOOL useOldImpl = src_size < 10240;
- FX_DWORD guess_size = orig_size ? orig_size : src_size * 2;
- FX_DWORD alloc_step =
- orig_size ? 10240 : (src_size < 10240 ? 10240 : src_size);
- static const FX_DWORD kMaxInitialAllocSize = 10000000;
- if (guess_size > kMaxInitialAllocSize) {
- guess_size = kMaxInitialAllocSize;
- alloc_step = kMaxInitialAllocSize;
- }
- FX_DWORD buf_size = guess_size;
- FX_DWORD last_buf_size = buf_size;
- void* context = nullptr;
- uint8_t* guess_buf = FX_Alloc(uint8_t, guess_size + 1);
- uint8_t* cur_buf = guess_buf;
- guess_buf[guess_size] = '\0';
- context = FPDFAPI_FlateInit(my_alloc_func, my_free_func);
- if (!context)
- goto fail;
- FPDFAPI_FlateInput(context, src_buf, src_size);
- if (useOldImpl) {
- while (1) {
- int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size);
- if (ret != Z_OK)
- break;
- int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context);
- if (avail_buf_size != 0)
- break;
-
- // |avail_buf_size| == 0 case.
- FX_DWORD old_size = guess_size;
- guess_size += alloc_step;
- if (guess_size < old_size || guess_size + 1 < guess_size)
- goto fail;
- guess_buf = FX_Realloc(uint8_t, guess_buf, guess_size + 1);
- if (!guess_buf)
- goto fail;
- guess_buf[guess_size] = '\0';
- cur_buf = guess_buf + old_size;
- buf_size = guess_size - old_size;
- }
- dest_size = FPDFAPI_FlateGetTotalOut(context);
- offset = FPDFAPI_FlateGetTotalIn(context);
- if (guess_size / 2 > dest_size) {
- guess_buf = FX_Realloc(uint8_t, guess_buf, dest_size + 1);
- if (!guess_buf)
- goto fail;
- guess_size = dest_size;
- guess_buf[guess_size] = '\0';
- }
- dest_buf = guess_buf;
- } else {
- CFX_ArrayTemplate<uint8_t*> result_tmp_bufs;
- while (1) {
- int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size);
- int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context);
- if (ret != Z_OK) {
- last_buf_size = buf_size - avail_buf_size;
- result_tmp_bufs.Add(cur_buf);
- break;
- }
- if (avail_buf_size != 0) {
- last_buf_size = buf_size - avail_buf_size;
- result_tmp_bufs.Add(cur_buf);
- break;
- }
-
- // |avail_buf_size| == 0 case.
- result_tmp_bufs.Add(cur_buf);
- cur_buf = FX_Alloc(uint8_t, buf_size + 1);
- cur_buf[buf_size] = '\0';
- }
- dest_size = FPDFAPI_FlateGetTotalOut(context);
- offset = FPDFAPI_FlateGetTotalIn(context);
- if (result_tmp_bufs.GetSize() == 1) {
- dest_buf = result_tmp_bufs[0];
- } else {
- uint8_t* result_buf = FX_Alloc(uint8_t, dest_size);
- FX_DWORD result_pos = 0;
- for (int32_t i = 0; i < result_tmp_bufs.GetSize(); i++) {
- uint8_t* tmp_buf = result_tmp_bufs[i];
- FX_DWORD tmp_buf_size = buf_size;
- if (i == result_tmp_bufs.GetSize() - 1) {
- tmp_buf_size = last_buf_size;
- }
- FXSYS_memcpy(result_buf + result_pos, tmp_buf, tmp_buf_size);
- result_pos += tmp_buf_size;
- FX_Free(result_tmp_bufs[i]);
- }
- dest_buf = result_buf;
- }
- }
- FPDFAPI_FlateEnd(context);
- return;
-
-fail:
- FX_Free(guess_buf);
- dest_buf = nullptr;
- dest_size = 0;
- return;
-}
ICodec_ScanlineDecoder* CCodec_FlateModule::CreateDecoder(
const uint8_t* src_buf,
FX_DWORD src_size,