diff options
author | Nico Weber <thakis@chromium.org> | 2015-08-04 12:19:10 -0700 |
---|---|---|
committer | Nico Weber <thakis@chromium.org> | 2015-08-04 12:19:10 -0700 |
commit | b048f791a15f2da781a01eba5b09eb9d389f9c11 (patch) | |
tree | 6850a73c18bbc41eaf4b1fdc6b3c96646d45587b /core/src/fpdfapi/fpdf_parser | |
parent | c8eeed31f217d99a706b0cbf5e4ce0bcc12beb64 (diff) | |
download | pdfium-b048f791a15f2da781a01eba5b09eb9d389f9c11.tar.xz |
clang-format all pdfium code.
No behavior change.
Generated by:
find . -name '*.cpp' -o -name '*.h' | \
grep -E -v 'third_party|thirdparties|lpng_v163' | \
xargs ../../buildtools/mac/clang-format -i
See thread "tabs vs spaces" on pdfium@googlegroups.com for discussion.
BUG=none
R=tsepez@chromium.org
Review URL: https://codereview.chromium.org/1265503005 .
Diffstat (limited to 'core/src/fpdfapi/fpdf_parser')
-rw-r--r-- | core/src/fpdfapi/fpdf_parser/filters_int.h | 231 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_parser/fpdf_parser_decode.cpp | 1035 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_parser/fpdf_parser_decode_embeddertest.cpp | 73 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_parser/fpdf_parser_document.cpp | 650 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_parser/fpdf_parser_encrypt.cpp | 1843 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_parser/fpdf_parser_fdf.cpp | 303 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_parser/fpdf_parser_filters.cpp | 1754 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp | 2389 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp | 8252 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_parser/fpdf_parser_parser_embeddertest.cpp | 3 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_parser/fpdf_parser_utility.cpp | 820 |
11 files changed, 8776 insertions, 8577 deletions
diff --git a/core/src/fpdfapi/fpdf_parser/filters_int.h b/core/src/fpdfapi/fpdf_parser/filters_int.h index 2ec54fb1f5..571801481d 100644 --- a/core/src/fpdfapi/fpdf_parser/filters_int.h +++ b/core/src/fpdfapi/fpdf_parser/filters_int.h @@ -7,120 +7,139 @@ #ifndef CORE_SRC_FPDFAPI_FPDF_PARSER_FILTERS_INT_H_ #define CORE_SRC_FPDFAPI_FPDF_PARSER_FILTERS_INT_H_ -class CPDF_DecryptFilter : public CFX_DataFilter -{ -public: - CPDF_DecryptFilter(CPDF_CryptoHandler* pCryptoHandler, FX_DWORD objnum, FX_DWORD gennum); - virtual ~CPDF_DecryptFilter(); - virtual void v_FilterIn(const uint8_t* src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf); - virtual void v_FilterFinish(CFX_BinaryBuf& dest_buf); - CPDF_CryptoHandler* m_pCryptoHandler; - void* m_pContext; - FX_DWORD m_ObjNum, m_GenNum; +class CPDF_DecryptFilter : public CFX_DataFilter { + public: + CPDF_DecryptFilter(CPDF_CryptoHandler* pCryptoHandler, + FX_DWORD objnum, + FX_DWORD gennum); + virtual ~CPDF_DecryptFilter(); + virtual void v_FilterIn(const uint8_t* src_buf, + FX_DWORD src_size, + CFX_BinaryBuf& dest_buf); + virtual void v_FilterFinish(CFX_BinaryBuf& dest_buf); + CPDF_CryptoHandler* m_pCryptoHandler; + void* m_pContext; + FX_DWORD m_ObjNum, m_GenNum; }; -class CPDF_FlateFilter : public CFX_DataFilter -{ -public: - CPDF_FlateFilter(); - virtual ~CPDF_FlateFilter(); - virtual void v_FilterIn(const uint8_t* src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf); - virtual void v_FilterFinish(CFX_BinaryBuf& dest_buf) {} - void* m_pContext; - uint8_t m_DestBuffer[FPDF_FILTER_BUFFER_SIZE]; +class CPDF_FlateFilter : public CFX_DataFilter { + public: + CPDF_FlateFilter(); + virtual ~CPDF_FlateFilter(); + virtual void v_FilterIn(const uint8_t* src_buf, + FX_DWORD src_size, + CFX_BinaryBuf& dest_buf); + virtual void v_FilterFinish(CFX_BinaryBuf& dest_buf) {} + void* m_pContext; + uint8_t m_DestBuffer[FPDF_FILTER_BUFFER_SIZE]; }; -class CPDF_LzwFilter : public CFX_DataFilter -{ -public: - CPDF_LzwFilter(FX_BOOL bEarlyChange); - virtual ~CPDF_LzwFilter() {} - virtual void v_FilterIn(const uint8_t* src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf); - virtual void v_FilterFinish(CFX_BinaryBuf& dest_buf) {} - FX_BOOL m_bEarlyChange; - FX_DWORD m_CodeArray[5021]; - FX_DWORD m_nCodes; - FX_DWORD m_CodeLen; - FX_DWORD m_OldCode; - uint8_t m_LastChar; - FX_DWORD m_nLeftBits, m_LeftBits; - uint8_t m_DecodeStack[4000]; - FX_DWORD m_StackLen; - void AddCode(FX_DWORD prefix_code, uint8_t append_char); - void DecodeString(FX_DWORD code); +class CPDF_LzwFilter : public CFX_DataFilter { + public: + CPDF_LzwFilter(FX_BOOL bEarlyChange); + virtual ~CPDF_LzwFilter() {} + virtual void v_FilterIn(const uint8_t* src_buf, + FX_DWORD src_size, + CFX_BinaryBuf& dest_buf); + virtual void v_FilterFinish(CFX_BinaryBuf& dest_buf) {} + FX_BOOL m_bEarlyChange; + FX_DWORD m_CodeArray[5021]; + FX_DWORD m_nCodes; + FX_DWORD m_CodeLen; + FX_DWORD m_OldCode; + uint8_t m_LastChar; + FX_DWORD m_nLeftBits, m_LeftBits; + uint8_t m_DecodeStack[4000]; + FX_DWORD m_StackLen; + void AddCode(FX_DWORD prefix_code, uint8_t append_char); + void DecodeString(FX_DWORD code); }; -class CPDF_PredictorFilter : public CFX_DataFilter -{ -public: - CPDF_PredictorFilter(int predictor, int colors, int bpc, int cols); - virtual ~CPDF_PredictorFilter(); - virtual void v_FilterIn(const uint8_t* src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf); - virtual void v_FilterFinish(CFX_BinaryBuf& dest_buf) {} - FX_BOOL m_bTiff; - FX_DWORD m_Pitch, m_Bpp; - uint8_t* m_pRefLine; - uint8_t* m_pCurLine; - FX_DWORD m_iLine, m_LineInSize; +class CPDF_PredictorFilter : public CFX_DataFilter { + public: + CPDF_PredictorFilter(int predictor, int colors, int bpc, int cols); + virtual ~CPDF_PredictorFilter(); + virtual void v_FilterIn(const uint8_t* src_buf, + FX_DWORD src_size, + CFX_BinaryBuf& dest_buf); + virtual void v_FilterFinish(CFX_BinaryBuf& dest_buf) {} + FX_BOOL m_bTiff; + FX_DWORD m_Pitch, m_Bpp; + uint8_t* m_pRefLine; + uint8_t* m_pCurLine; + FX_DWORD m_iLine, m_LineInSize; }; -class CPDF_AsciiHexFilter : public CFX_DataFilter -{ -public: - CPDF_AsciiHexFilter(); - virtual ~CPDF_AsciiHexFilter() {} - virtual void v_FilterIn(const uint8_t* src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf); - virtual void v_FilterFinish(CFX_BinaryBuf& dest_buf) {} - int m_State; - int m_FirstDigit; +class CPDF_AsciiHexFilter : public CFX_DataFilter { + public: + CPDF_AsciiHexFilter(); + virtual ~CPDF_AsciiHexFilter() {} + virtual void v_FilterIn(const uint8_t* src_buf, + FX_DWORD src_size, + CFX_BinaryBuf& dest_buf); + virtual void v_FilterFinish(CFX_BinaryBuf& dest_buf) {} + int m_State; + int m_FirstDigit; }; -class CPDF_Ascii85Filter : public CFX_DataFilter -{ -public: - CPDF_Ascii85Filter(); - virtual ~CPDF_Ascii85Filter() {} - virtual void v_FilterIn(const uint8_t* src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf); - virtual void v_FilterFinish(CFX_BinaryBuf& dest_buf) {} - int m_State; - int m_CharCount; - FX_DWORD m_CurDWord; +class CPDF_Ascii85Filter : public CFX_DataFilter { + public: + CPDF_Ascii85Filter(); + virtual ~CPDF_Ascii85Filter() {} + virtual void v_FilterIn(const uint8_t* src_buf, + FX_DWORD src_size, + CFX_BinaryBuf& dest_buf); + virtual void v_FilterFinish(CFX_BinaryBuf& dest_buf) {} + int m_State; + int m_CharCount; + FX_DWORD m_CurDWord; }; -class CPDF_RunLenFilter : public CFX_DataFilter -{ -public: - CPDF_RunLenFilter(); - virtual ~CPDF_RunLenFilter() {} - virtual void v_FilterIn(const uint8_t* src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf); - virtual void v_FilterFinish(CFX_BinaryBuf& dest_buf) {} - int m_State; - FX_DWORD m_Count; +class CPDF_RunLenFilter : public CFX_DataFilter { + public: + CPDF_RunLenFilter(); + virtual ~CPDF_RunLenFilter() {} + virtual void v_FilterIn(const uint8_t* src_buf, + FX_DWORD src_size, + CFX_BinaryBuf& dest_buf); + virtual void v_FilterFinish(CFX_BinaryBuf& dest_buf) {} + int m_State; + FX_DWORD m_Count; }; -class CPDF_JpegFilter : public CFX_DataFilter -{ -public: - CPDF_JpegFilter(); - virtual ~CPDF_JpegFilter(); - virtual void v_FilterIn(const uint8_t* src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf); - virtual void v_FilterFinish(CFX_BinaryBuf& dest_buf) {} - void* m_pContext; - CFX_BinaryBuf m_InputBuf; - uint8_t* m_pScanline; - int m_Pitch, m_Height, m_Width, m_nComps, m_iLine; - FX_BOOL m_bGotHeader; +class CPDF_JpegFilter : public CFX_DataFilter { + public: + CPDF_JpegFilter(); + virtual ~CPDF_JpegFilter(); + virtual void v_FilterIn(const uint8_t* src_buf, + FX_DWORD src_size, + CFX_BinaryBuf& dest_buf); + virtual void v_FilterFinish(CFX_BinaryBuf& dest_buf) {} + void* m_pContext; + CFX_BinaryBuf m_InputBuf; + uint8_t* m_pScanline; + int m_Pitch, m_Height, m_Width, m_nComps, m_iLine; + FX_BOOL m_bGotHeader; }; -class CPDF_FaxFilter : public CFX_DataFilter -{ -public: - CPDF_FaxFilter(); - virtual ~CPDF_FaxFilter(); - FX_BOOL Initialize(int Encoding, int bEndOfLine, int bByteAlign, int bBlack, int nRows, int nColumns); - virtual void v_FilterIn(const uint8_t* src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf); - virtual void v_FilterFinish(CFX_BinaryBuf& dest_buf); - int m_Encoding, m_bEndOfLine, m_bByteAlign, m_bBlack; - int m_nRows, m_nColumns, m_Pitch, m_iRow; - uint8_t* m_pScanlineBuf; - uint8_t* m_pRefBuf; - CFX_BinaryBuf m_InputBuf; - int m_InputBitPos; - void ProcessData(const uint8_t* src_buf, FX_DWORD src_size, int& bitpos, FX_BOOL bFinish, - CFX_BinaryBuf& dest_buf); - FX_BOOL ReadLine(const uint8_t* src_buf, int bitsize, int& bitpos); +class CPDF_FaxFilter : public CFX_DataFilter { + public: + CPDF_FaxFilter(); + virtual ~CPDF_FaxFilter(); + FX_BOOL Initialize(int Encoding, + int bEndOfLine, + int bByteAlign, + int bBlack, + int nRows, + int nColumns); + virtual void v_FilterIn(const uint8_t* src_buf, + FX_DWORD src_size, + CFX_BinaryBuf& dest_buf); + virtual void v_FilterFinish(CFX_BinaryBuf& dest_buf); + int m_Encoding, m_bEndOfLine, m_bByteAlign, m_bBlack; + int m_nRows, m_nColumns, m_Pitch, m_iRow; + uint8_t* m_pScanlineBuf; + uint8_t* m_pRefBuf; + CFX_BinaryBuf m_InputBuf; + int m_InputBitPos; + void ProcessData(const uint8_t* src_buf, + FX_DWORD src_size, + int& bitpos, + FX_BOOL bFinish, + CFX_BinaryBuf& dest_buf); + FX_BOOL ReadLine(const uint8_t* src_buf, int bitsize, int& bitpos); }; #endif // CORE_SRC_FPDFAPI_FPDF_PARSER_FILTERS_INT_H_ diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode.cpp index 47c08fb4a3..85ba130b77 100644 --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode.cpp +++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode.cpp @@ -8,520 +8,575 @@ #include "../../../include/fpdfapi/fpdf_module.h" #include "../../../include/fxcodec/fx_codec.h" #include <limits.h> -#define _STREAM_MAX_SIZE_ 20 * 1024 * 1024 -FX_DWORD _A85Decode(const uint8_t* src_buf, FX_DWORD src_size, uint8_t*& dest_buf, FX_DWORD& dest_size) -{ - dest_size = 0; - dest_buf = NULL; - if (src_size == 0) { - return 0; - } - FX_DWORD zcount = 0; - FX_DWORD pos = 0; - while (pos < src_size) { - uint8_t ch = src_buf[pos]; - if (ch < '!' && ch != '\n' && ch != '\r' && ch != ' ' && ch != '\t') { - break; - } - if (ch == 'z') { - zcount ++; - } else if (ch > 'u') { - break; - } - pos ++; - } - if (pos == 0) { - return 0; - } - if (zcount > UINT_MAX / 4) { - return (FX_DWORD) - 1; - } - if (zcount * 4 > UINT_MAX - (pos - zcount)) { - return (FX_DWORD) - 1; - } - dest_buf = FX_Alloc(uint8_t, zcount * 4 + (pos - zcount)); - int state = 0; - uint32_t res = 0; - pos = dest_size = 0; - while (pos < src_size) { - uint8_t ch = src_buf[pos++]; - if (ch == '\n' || ch == '\r' || ch == ' ' || ch == '\t') { - continue; - } - if (ch == 'z') { - FXSYS_memset(dest_buf + dest_size, 0, 4); - state = 0; - res = 0; - dest_size += 4; - } else { - if (ch < '!' || ch > 'u') { - break; - } - res = res * 85 + ch - 33; - state ++; - if (state == 5) { - for (int i = 0; i < 4; i ++) { - dest_buf[dest_size++] = (uint8_t)(res >> (3 - i) * 8); - } - state = 0; - res = 0; - } - } - } - if (state) { - int i; - for (i = state; i < 5; i ++) { - res = res * 85 + 84; - } - for (i = 0; i < state - 1; i ++) { - dest_buf[dest_size++] = (uint8_t)(res >> (3 - i) * 8); +#define _STREAM_MAX_SIZE_ 20 * 1024 * 1024 +FX_DWORD _A85Decode(const uint8_t* src_buf, + FX_DWORD src_size, + uint8_t*& dest_buf, + FX_DWORD& dest_size) { + dest_size = 0; + dest_buf = NULL; + if (src_size == 0) { + return 0; + } + FX_DWORD zcount = 0; + FX_DWORD pos = 0; + while (pos < src_size) { + uint8_t ch = src_buf[pos]; + if (ch < '!' && ch != '\n' && ch != '\r' && ch != ' ' && ch != '\t') { + break; + } + if (ch == 'z') { + zcount++; + } else if (ch > 'u') { + break; + } + pos++; + } + if (pos == 0) { + return 0; + } + if (zcount > UINT_MAX / 4) { + return (FX_DWORD)-1; + } + if (zcount * 4 > UINT_MAX - (pos - zcount)) { + return (FX_DWORD)-1; + } + dest_buf = FX_Alloc(uint8_t, zcount * 4 + (pos - zcount)); + int state = 0; + uint32_t res = 0; + pos = dest_size = 0; + while (pos < src_size) { + uint8_t ch = src_buf[pos++]; + if (ch == '\n' || ch == '\r' || ch == ' ' || ch == '\t') { + continue; + } + if (ch == 'z') { + FXSYS_memset(dest_buf + dest_size, 0, 4); + state = 0; + res = 0; + dest_size += 4; + } else { + if (ch < '!' || ch > 'u') { + break; + } + res = res * 85 + ch - 33; + state++; + if (state == 5) { + for (int i = 0; i < 4; i++) { + dest_buf[dest_size++] = (uint8_t)(res >> (3 - i) * 8); } - } - if (pos < src_size && src_buf[pos] == '>') { - pos ++; - } - return pos; + state = 0; + res = 0; + } + } + } + if (state) { + int i; + for (i = state; i < 5; i++) { + res = res * 85 + 84; + } + for (i = 0; i < state - 1; i++) { + dest_buf[dest_size++] = (uint8_t)(res >> (3 - i) * 8); + } + } + if (pos < src_size && src_buf[pos] == '>') { + pos++; + } + return pos; } -FX_DWORD _HexDecode(const uint8_t* src_buf, FX_DWORD src_size, uint8_t*& dest_buf, FX_DWORD& dest_size) -{ - FX_DWORD i; - for (i = 0; i < src_size; i ++) - if (src_buf[i] == '>') { - break; - } - dest_buf = FX_Alloc( uint8_t, i / 2 + 1); - dest_size = 0; - FX_BOOL bFirstDigit = TRUE; - for (i = 0; i < src_size; i ++) { - uint8_t ch = src_buf[i]; - if (ch == ' ' || ch == '\n' || ch == '\t' || ch == '\r') { - continue; - } - int digit; - if (ch <= '9' && ch >= '0') { - digit = ch - '0'; - } else if (ch <= 'f' && ch >= 'a') { - digit = ch - 'a' + 10; - } else if (ch <= 'F' && ch >= 'A') { - digit = ch - 'A' + 10; - } else if (ch == '>') { - i ++; - break; - } else { - continue; - } - if (bFirstDigit) { - dest_buf[dest_size] = digit * 16; - } else { - dest_buf[dest_size ++] += digit; - } - bFirstDigit = !bFirstDigit; - } - if (!bFirstDigit) { - dest_size ++; +FX_DWORD _HexDecode(const uint8_t* src_buf, + FX_DWORD src_size, + uint8_t*& dest_buf, + FX_DWORD& dest_size) { + FX_DWORD i; + for (i = 0; i < src_size; i++) + if (src_buf[i] == '>') { + break; + } + dest_buf = FX_Alloc(uint8_t, i / 2 + 1); + dest_size = 0; + FX_BOOL bFirstDigit = TRUE; + for (i = 0; i < src_size; i++) { + uint8_t ch = src_buf[i]; + if (ch == ' ' || ch == '\n' || ch == '\t' || ch == '\r') { + continue; + } + int digit; + if (ch <= '9' && ch >= '0') { + digit = ch - '0'; + } else if (ch <= 'f' && ch >= 'a') { + digit = ch - 'a' + 10; + } else if (ch <= 'F' && ch >= 'A') { + digit = ch - 'A' + 10; + } else if (ch == '>') { + i++; + break; + } else { + continue; } - return i; + if (bFirstDigit) { + dest_buf[dest_size] = digit * 16; + } else { + dest_buf[dest_size++] += digit; + } + bFirstDigit = !bFirstDigit; + } + if (!bFirstDigit) { + dest_size++; + } + return i; } -FX_DWORD RunLengthDecode(const uint8_t* src_buf, FX_DWORD src_size, uint8_t*& dest_buf, FX_DWORD& dest_size) -{ - FX_DWORD i = 0; - FX_DWORD old; - dest_size = 0; - while (i < src_size) { - if (src_buf[i] < 128) { - old = dest_size; - dest_size += src_buf[i] + 1; - if (dest_size < old) { - return (FX_DWORD) - 1; - } - i += src_buf[i] + 2; - } else if (src_buf[i] > 128) { - old = dest_size; - dest_size += 257 - src_buf[i]; - if (dest_size < old) { - return (FX_DWORD) - 1; - } - i += 2; - } else { - break; - } - } - if (dest_size >= _STREAM_MAX_SIZE_) { - return -1; - } - dest_buf = FX_Alloc( uint8_t, dest_size); - i = 0; - int dest_count = 0; - while (i < src_size) { - if (src_buf[i] < 128) { - FX_DWORD copy_len = src_buf[i] + 1; - FX_DWORD buf_left = src_size - i - 1; - if (buf_left < copy_len) { - FX_DWORD delta = copy_len - buf_left; - copy_len = buf_left; - FXSYS_memset(dest_buf + dest_count + copy_len, '\0', delta); - } - FXSYS_memcpy(dest_buf + dest_count, src_buf + i + 1, copy_len); - dest_count += src_buf[i] + 1; - i += src_buf[i] + 2; - } else if (src_buf[i] > 128) { - int fill = 0; - if (i < src_size - 1) { - fill = src_buf[i + 1]; - } - FXSYS_memset(dest_buf + dest_count, fill, 257 - src_buf[i]); - dest_count += 257 - src_buf[i]; - i += 2; - } else { - break; - } - } - FX_DWORD ret = i + 1; - if (ret > src_size) { - ret = src_size; - } - return ret; +FX_DWORD RunLengthDecode(const uint8_t* src_buf, + FX_DWORD src_size, + uint8_t*& dest_buf, + FX_DWORD& dest_size) { + FX_DWORD i = 0; + FX_DWORD old; + dest_size = 0; + while (i < src_size) { + if (src_buf[i] < 128) { + old = dest_size; + dest_size += src_buf[i] + 1; + if (dest_size < old) { + return (FX_DWORD)-1; + } + i += src_buf[i] + 2; + } else if (src_buf[i] > 128) { + old = dest_size; + dest_size += 257 - src_buf[i]; + if (dest_size < old) { + return (FX_DWORD)-1; + } + i += 2; + } else { + break; + } + } + if (dest_size >= _STREAM_MAX_SIZE_) { + return -1; + } + dest_buf = FX_Alloc(uint8_t, dest_size); + i = 0; + int dest_count = 0; + while (i < src_size) { + if (src_buf[i] < 128) { + FX_DWORD copy_len = src_buf[i] + 1; + FX_DWORD buf_left = src_size - i - 1; + if (buf_left < copy_len) { + FX_DWORD delta = copy_len - buf_left; + copy_len = buf_left; + FXSYS_memset(dest_buf + dest_count + copy_len, '\0', delta); + } + FXSYS_memcpy(dest_buf + dest_count, src_buf + i + 1, copy_len); + dest_count += src_buf[i] + 1; + i += src_buf[i] + 2; + } else if (src_buf[i] > 128) { + int fill = 0; + if (i < src_size - 1) { + fill = src_buf[i + 1]; + } + FXSYS_memset(dest_buf + dest_count, fill, 257 - src_buf[i]); + dest_count += 257 - src_buf[i]; + i += 2; + } else { + break; + } + } + FX_DWORD ret = i + 1; + if (ret > src_size) { + ret = src_size; + } + return ret; } -ICodec_ScanlineDecoder* FPDFAPI_CreateFaxDecoder(const uint8_t* src_buf, FX_DWORD src_size, int width, int height, - const CPDF_Dictionary* pParams) -{ - int K = 0; - FX_BOOL EndOfLine = FALSE; - FX_BOOL ByteAlign = FALSE; - FX_BOOL BlackIs1 = FALSE; - int Columns = 1728; - int Rows = 0; - if (pParams) { - K = pParams->GetInteger(FX_BSTRC("K")); - EndOfLine = pParams->GetInteger(FX_BSTRC("EndOfLine")); - ByteAlign = pParams->GetInteger(FX_BSTRC("EncodedByteAlign")); - BlackIs1 = pParams->GetInteger(FX_BSTRC("BlackIs1")); - Columns = pParams->GetInteger(FX_BSTRC("Columns"), 1728); - Rows = pParams->GetInteger(FX_BSTRC("Rows")); - if (Rows > USHRT_MAX) { - Rows = 0; - } - if (Columns <= 0 || Rows < 0 || Columns > USHRT_MAX || Rows > USHRT_MAX) { - return NULL; - } - } - return CPDF_ModuleMgr::Get()->GetFaxModule()->CreateDecoder(src_buf, src_size, width, height, - K, EndOfLine, ByteAlign, BlackIs1, Columns, Rows); +ICodec_ScanlineDecoder* FPDFAPI_CreateFaxDecoder( + const uint8_t* src_buf, + FX_DWORD src_size, + int width, + int height, + const CPDF_Dictionary* pParams) { + int K = 0; + FX_BOOL EndOfLine = FALSE; + FX_BOOL ByteAlign = FALSE; + FX_BOOL BlackIs1 = FALSE; + int Columns = 1728; + int Rows = 0; + if (pParams) { + K = pParams->GetInteger(FX_BSTRC("K")); + EndOfLine = pParams->GetInteger(FX_BSTRC("EndOfLine")); + ByteAlign = pParams->GetInteger(FX_BSTRC("EncodedByteAlign")); + BlackIs1 = pParams->GetInteger(FX_BSTRC("BlackIs1")); + Columns = pParams->GetInteger(FX_BSTRC("Columns"), 1728); + Rows = pParams->GetInteger(FX_BSTRC("Rows")); + if (Rows > USHRT_MAX) { + Rows = 0; + } + if (Columns <= 0 || Rows < 0 || Columns > USHRT_MAX || Rows > USHRT_MAX) { + return NULL; + } + } + return CPDF_ModuleMgr::Get()->GetFaxModule()->CreateDecoder( + src_buf, src_size, width, height, K, EndOfLine, ByteAlign, BlackIs1, + Columns, Rows); } -static FX_BOOL CheckFlateDecodeParams(int Colors, int BitsPerComponent, int Columns) -{ - if (Columns < 0) { - return FALSE; - } - int check = Columns; - if (Colors < 0 || (check > 0 && Colors > INT_MAX / check)) { - return FALSE; - } - check *= Colors; - if (BitsPerComponent < 0 || - (check > 0 && BitsPerComponent > INT_MAX / check)) { - return FALSE; - } - check *= BitsPerComponent; - if (check > INT_MAX - 7) { - return FALSE; - } - return TRUE; +static FX_BOOL CheckFlateDecodeParams(int Colors, + int BitsPerComponent, + int Columns) { + if (Columns < 0) { + return FALSE; + } + int check = Columns; + if (Colors < 0 || (check > 0 && Colors > INT_MAX / check)) { + return FALSE; + } + check *= Colors; + if (BitsPerComponent < 0 || + (check > 0 && BitsPerComponent > INT_MAX / check)) { + return FALSE; + } + check *= BitsPerComponent; + if (check > INT_MAX - 7) { + return FALSE; + } + return TRUE; } -ICodec_ScanlineDecoder* FPDFAPI_CreateFlateDecoder(const uint8_t* src_buf, FX_DWORD src_size, int width, int height, - int nComps, int bpc, const CPDF_Dictionary* pParams) -{ - int predictor = 0; - int Colors = 0, BitsPerComponent = 0, Columns = 0; - if (pParams) { - predictor = ((CPDF_Dictionary*)pParams)->GetInteger(FX_BSTRC("Predictor")); - Colors = pParams->GetInteger(FX_BSTRC("Colors"), 1); - BitsPerComponent = pParams->GetInteger(FX_BSTRC("BitsPerComponent"), 8); - Columns = pParams->GetInteger(FX_BSTRC("Columns"), 1); - if (!CheckFlateDecodeParams(Colors, BitsPerComponent, Columns)) { - return NULL; - } - } - return CPDF_ModuleMgr::Get()->GetFlateModule()->CreateDecoder(src_buf, src_size, width, height, - nComps, bpc, predictor, Colors, BitsPerComponent, Columns); +ICodec_ScanlineDecoder* FPDFAPI_CreateFlateDecoder( + const uint8_t* src_buf, + FX_DWORD src_size, + int width, + int height, + int nComps, + int bpc, + const CPDF_Dictionary* pParams) { + int predictor = 0; + int Colors = 0, BitsPerComponent = 0, Columns = 0; + if (pParams) { + predictor = ((CPDF_Dictionary*)pParams)->GetInteger(FX_BSTRC("Predictor")); + Colors = pParams->GetInteger(FX_BSTRC("Colors"), 1); + BitsPerComponent = pParams->GetInteger(FX_BSTRC("BitsPerComponent"), 8); + Columns = pParams->GetInteger(FX_BSTRC("Columns"), 1); + if (!CheckFlateDecodeParams(Colors, BitsPerComponent, Columns)) { + return NULL; + } + } + return CPDF_ModuleMgr::Get()->GetFlateModule()->CreateDecoder( + src_buf, src_size, width, height, nComps, bpc, predictor, Colors, + BitsPerComponent, Columns); } -FX_DWORD FPDFAPI_FlateOrLZWDecode(FX_BOOL bLZW, const uint8_t* src_buf, FX_DWORD src_size, CPDF_Dictionary* pParams, - FX_DWORD estimated_size, uint8_t*& dest_buf, FX_DWORD& dest_size) -{ - int predictor = 0; - FX_BOOL bEarlyChange = TRUE; - int Colors = 0, BitsPerComponent = 0, Columns = 0; - if (pParams) { - predictor = ((CPDF_Dictionary*)pParams)->GetInteger(FX_BSTRC("Predictor")); - bEarlyChange = ((CPDF_Dictionary*)pParams)->GetInteger(FX_BSTRC("EarlyChange"), 1); - Colors = pParams->GetInteger(FX_BSTRC("Colors"), 1); - BitsPerComponent = pParams->GetInteger(FX_BSTRC("BitsPerComponent"), 8); - Columns = pParams->GetInteger(FX_BSTRC("Columns"), 1); - if (!CheckFlateDecodeParams(Colors, BitsPerComponent, Columns)) { - return (FX_DWORD) - 1; - } - } - return CPDF_ModuleMgr::Get()->GetFlateModule()->FlateOrLZWDecode(bLZW, src_buf, src_size, - bEarlyChange, predictor, Colors, BitsPerComponent, Columns, estimated_size, - dest_buf, dest_size); +FX_DWORD FPDFAPI_FlateOrLZWDecode(FX_BOOL bLZW, + const uint8_t* src_buf, + FX_DWORD src_size, + CPDF_Dictionary* pParams, + FX_DWORD estimated_size, + uint8_t*& dest_buf, + FX_DWORD& dest_size) { + int predictor = 0; + FX_BOOL bEarlyChange = TRUE; + int Colors = 0, BitsPerComponent = 0, Columns = 0; + if (pParams) { + predictor = ((CPDF_Dictionary*)pParams)->GetInteger(FX_BSTRC("Predictor")); + bEarlyChange = + ((CPDF_Dictionary*)pParams)->GetInteger(FX_BSTRC("EarlyChange"), 1); + Colors = pParams->GetInteger(FX_BSTRC("Colors"), 1); + BitsPerComponent = pParams->GetInteger(FX_BSTRC("BitsPerComponent"), 8); + Columns = pParams->GetInteger(FX_BSTRC("Columns"), 1); + if (!CheckFlateDecodeParams(Colors, BitsPerComponent, Columns)) { + return (FX_DWORD)-1; + } + } + return CPDF_ModuleMgr::Get()->GetFlateModule()->FlateOrLZWDecode( + bLZW, src_buf, src_size, bEarlyChange, predictor, Colors, + BitsPerComponent, Columns, estimated_size, dest_buf, dest_size); } -FX_BOOL PDF_DataDecode(const uint8_t* src_buf, FX_DWORD src_size, const CPDF_Dictionary* pDict, - uint8_t*& dest_buf, FX_DWORD& dest_size, CFX_ByteString& ImageEncoding, - CPDF_Dictionary*& pImageParms, FX_DWORD last_estimated_size, FX_BOOL bImageAcc) +FX_BOOL PDF_DataDecode(const uint8_t* src_buf, + FX_DWORD src_size, + const CPDF_Dictionary* pDict, + uint8_t*& dest_buf, + FX_DWORD& dest_size, + CFX_ByteString& ImageEncoding, + CPDF_Dictionary*& pImageParms, + FX_DWORD last_estimated_size, + FX_BOOL bImageAcc) { - CPDF_Object* pDecoder = pDict ? pDict->GetElementValue(FX_BSTRC("Filter")) : NULL; - if (pDecoder == NULL || (pDecoder->GetType() != PDFOBJ_ARRAY && pDecoder->GetType() != PDFOBJ_NAME)) { - return FALSE; - } - CPDF_Object* pParams = pDict ? pDict->GetElementValue(FX_BSTRC("DecodeParms")) : NULL; - CFX_ByteStringArray DecoderList; - CFX_PtrArray ParamList; - if (pDecoder->GetType() == PDFOBJ_ARRAY) { - if (pParams && pParams->GetType() != PDFOBJ_ARRAY) { - pParams = NULL; - } - CPDF_Array* pDecoders = (CPDF_Array*)pDecoder; - for (FX_DWORD i = 0; i < pDecoders->GetCount(); i ++) { - CFX_ByteStringC str = pDecoders->GetConstString(i); - DecoderList.Add(str); - if (pParams) { - ParamList.Add(((CPDF_Array*)pParams)->GetDict(i)); - } else { - ParamList.Add(NULL); - } - } + CPDF_Object* pDecoder = + pDict ? pDict->GetElementValue(FX_BSTRC("Filter")) : NULL; + if (pDecoder == NULL || (pDecoder->GetType() != PDFOBJ_ARRAY && + pDecoder->GetType() != PDFOBJ_NAME)) { + return FALSE; + } + CPDF_Object* pParams = + pDict ? pDict->GetElementValue(FX_BSTRC("DecodeParms")) : NULL; + CFX_ByteStringArray DecoderList; + CFX_PtrArray ParamList; + if (pDecoder->GetType() == PDFOBJ_ARRAY) { + if (pParams && pParams->GetType() != PDFOBJ_ARRAY) { + pParams = NULL; + } + CPDF_Array* pDecoders = (CPDF_Array*)pDecoder; + for (FX_DWORD i = 0; i < pDecoders->GetCount(); i++) { + CFX_ByteStringC str = pDecoders->GetConstString(i); + DecoderList.Add(str); + if (pParams) { + ParamList.Add(((CPDF_Array*)pParams)->GetDict(i)); + } else { + ParamList.Add(NULL); + } + } + } else { + DecoderList.Add(pDecoder->GetConstString()); + ParamList.Add(pParams ? pParams->GetDict() : NULL); + } + uint8_t* last_buf = (uint8_t*)src_buf; + FX_DWORD last_size = src_size; + for (int i = 0; i < DecoderList.GetSize(); i++) { + int estimated_size = + i == DecoderList.GetSize() - 1 ? last_estimated_size : 0; + CFX_ByteString decoder = DecoderList[i]; + CPDF_Dictionary* pParam = (CPDF_Dictionary*)ParamList[i]; + uint8_t* new_buf = NULL; + FX_DWORD new_size = (FX_DWORD)-1; + int offset = -1; + if (decoder == FX_BSTRC("FlateDecode") || decoder == FX_BSTRC("Fl")) { + if (bImageAcc && i == DecoderList.GetSize() - 1) { + ImageEncoding = FX_BSTRC("FlateDecode"); + dest_buf = (uint8_t*)last_buf; + dest_size = last_size; + pImageParms = pParam; + return TRUE; + } + offset = FPDFAPI_FlateOrLZWDecode(FALSE, last_buf, last_size, pParam, + estimated_size, new_buf, new_size); + } else if (decoder == FX_BSTRC("LZWDecode") || decoder == FX_BSTRC("LZW")) { + offset = FPDFAPI_FlateOrLZWDecode(TRUE, last_buf, last_size, pParam, + estimated_size, new_buf, new_size); + } else if (decoder == FX_BSTRC("ASCII85Decode") || + decoder == FX_BSTRC("A85")) { + offset = _A85Decode(last_buf, last_size, new_buf, new_size); + } else if (decoder == FX_BSTRC("ASCIIHexDecode") || + decoder == FX_BSTRC("AHx")) { + offset = _HexDecode(last_buf, last_size, new_buf, new_size); + } else if (decoder == FX_BSTRC("RunLengthDecode") || + decoder == FX_BSTRC("RL")) { + if (bImageAcc && i == DecoderList.GetSize() - 1) { + ImageEncoding = FX_BSTRC("RunLengthDecode"); + dest_buf = (uint8_t*)last_buf; + dest_size = last_size; + pImageParms = pParam; + return TRUE; + } + offset = RunLengthDecode(last_buf, last_size, new_buf, new_size); } else { - DecoderList.Add(pDecoder->GetConstString()); - ParamList.Add(pParams ? pParams->GetDict() : NULL); - } - uint8_t* last_buf = (uint8_t*)src_buf; - FX_DWORD last_size = src_size; - for (int i = 0; i < DecoderList.GetSize(); i ++) { - int estimated_size = i == DecoderList.GetSize() - 1 ? last_estimated_size : 0; - CFX_ByteString decoder = DecoderList[i]; - CPDF_Dictionary* pParam = (CPDF_Dictionary*)ParamList[i]; - uint8_t* new_buf = NULL; - FX_DWORD new_size = (FX_DWORD) - 1; - int offset = -1; - if (decoder == FX_BSTRC("FlateDecode") || decoder == FX_BSTRC("Fl")) { - if (bImageAcc && i == DecoderList.GetSize() - 1) { - ImageEncoding = FX_BSTRC("FlateDecode"); - dest_buf = (uint8_t*)last_buf; - dest_size = last_size; - pImageParms = pParam; - return TRUE; - } - offset = FPDFAPI_FlateOrLZWDecode(FALSE, last_buf, last_size, pParam, estimated_size, new_buf, new_size); - } else if (decoder == FX_BSTRC("LZWDecode") || decoder == FX_BSTRC("LZW")) { - offset = FPDFAPI_FlateOrLZWDecode(TRUE, last_buf, last_size, pParam, estimated_size, new_buf, new_size); - } else if (decoder == FX_BSTRC("ASCII85Decode") || decoder == FX_BSTRC("A85")) { - offset = _A85Decode(last_buf, last_size, new_buf, new_size); - } else if (decoder == FX_BSTRC("ASCIIHexDecode") || decoder == FX_BSTRC("AHx")) { - offset = _HexDecode(last_buf, last_size, new_buf, new_size); - } else if (decoder == FX_BSTRC("RunLengthDecode") || decoder == FX_BSTRC("RL")) { - if (bImageAcc && i == DecoderList.GetSize() - 1) { - ImageEncoding = FX_BSTRC("RunLengthDecode"); - dest_buf = (uint8_t*)last_buf; - dest_size = last_size; - pImageParms = pParam; - return TRUE; - } - offset = RunLengthDecode(last_buf, last_size, new_buf, new_size); - } else { - if (decoder == FX_BSTRC("DCT")) { - decoder = "DCTDecode"; - } else if (decoder == FX_BSTRC("CCF")) { - decoder = "CCITTFaxDecode"; - } else if (decoder == FX_BSTRC("Crypt")) { - continue; - } - ImageEncoding = decoder; - pImageParms = pParam; - dest_buf = (uint8_t*)last_buf; - dest_size = last_size; - return TRUE; - } - if (last_buf != src_buf) { - FX_Free(last_buf); - } - if (offset == -1) { - return FALSE; - } - last_buf = new_buf; - last_size = new_size; - } - ImageEncoding = ""; - pImageParms = NULL; - dest_buf = last_buf; - dest_size = last_size; - return TRUE; + if (decoder == FX_BSTRC("DCT")) { + decoder = "DCTDecode"; + } else if (decoder == FX_BSTRC("CCF")) { + decoder = "CCITTFaxDecode"; + } else if (decoder == FX_BSTRC("Crypt")) { + continue; + } + ImageEncoding = decoder; + pImageParms = pParam; + dest_buf = (uint8_t*)last_buf; + dest_size = last_size; + return TRUE; + } + if (last_buf != src_buf) { + FX_Free(last_buf); + } + if (offset == -1) { + return FALSE; + } + last_buf = new_buf; + last_size = new_size; + } + ImageEncoding = ""; + pImageParms = NULL; + dest_buf = last_buf; + dest_size = last_size; + return TRUE; } extern const FX_WORD PDFDocEncoding[256] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, - 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, - 0x0014, 0x0015, 0x0016, 0x0017, 0x02d8, 0x02c7, 0x02c6, 0x02d9, 0x02dd, 0x02db, - 0x02da, 0x02dc, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, - 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, - 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, - 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, - 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, - 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, - 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, - 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, - 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, - 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x0000, 0x2022, 0x2020, - 0x2021, 0x2026, 0x2014, 0x2013, 0x0192, 0x2044, 0x2039, 0x203a, 0x2212, 0x2030, - 0x201e, 0x201c, 0x201d, 0x2018, 0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x0141, - 0x0152, 0x0160, 0x0178, 0x017d, 0x0131, 0x0142, 0x0153, 0x0161, 0x017e, 0x0000, - 0x20ac, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, - 0x00aa, 0x00ab, 0x00ac, 0x0000, 0x00ae, 0x00af, 0x00b0, 0x00b1, 0x00b2, 0x00b3, - 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, - 0x00be, 0x00bf, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, - 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, 0x00d0, 0x00d1, - 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, - 0x00dc, 0x00dd, 0x00de, 0x00df, 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, - 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, - 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, - 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff -}; -CFX_WideString PDF_DecodeText(const uint8_t* src_data, FX_DWORD src_len, CFX_CharMap* pCharMap) -{ - CFX_WideString result; - if (src_len >= 2 && ((src_data[0] == 0xfe && src_data[1] == 0xff) || (src_data[0] == 0xff && src_data[1] == 0xfe))) { - FX_BOOL bBE = src_data[0] == 0xfe; - FX_DWORD max_chars = (src_len - 2) / 2; - if (!max_chars) { - return result; - } - if (src_data[0] == 0xff) { - bBE = !src_data[2]; - } - FX_WCHAR* dest_buf = result.GetBuffer(max_chars); - const uint8_t* uni_str = src_data + 2; - int dest_pos = 0; - for (FX_DWORD i = 0; i < max_chars * 2; i += 2) { - FX_WORD unicode = bBE ? (uni_str[i] << 8 | uni_str[i + 1]) : (uni_str[i + 1] << 8 | uni_str[i]); - if (unicode == 0x1b) { - i += 2; - while (i < max_chars * 2) { - FX_WORD unicode = bBE ? (uni_str[i] << 8 | uni_str[i + 1]) : (uni_str[i + 1] << 8 | uni_str[i]); - i += 2; - if (unicode == 0x1b) { - break; - } - } - } else { - dest_buf[dest_pos++] = unicode; - } - } - result.ReleaseBuffer(dest_pos); - } else if (pCharMap == NULL) { - FX_WCHAR* dest_buf = result.GetBuffer(src_len); - for (FX_DWORD i = 0; i < src_len; i ++) { - dest_buf[i] = PDFDocEncoding[src_data[i]]; + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, + 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, + 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x02d8, 0x02c7, 0x02c6, + 0x02d9, 0x02dd, 0x02db, 0x02da, 0x02dc, 0x0020, 0x0021, 0x0022, 0x0023, + 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, + 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, + 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, + 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, + 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, + 0x007e, 0x0000, 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x0192, + 0x2044, 0x2039, 0x203a, 0x2212, 0x2030, 0x201e, 0x201c, 0x201d, 0x2018, + 0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x0141, 0x0152, 0x0160, 0x0178, + 0x017d, 0x0131, 0x0142, 0x0153, 0x0161, 0x017e, 0x0000, 0x20ac, 0x00a1, + 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, + 0x00ab, 0x00ac, 0x0000, 0x00ae, 0x00af, 0x00b0, 0x00b1, 0x00b2, 0x00b3, + 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, + 0x00bd, 0x00be, 0x00bf, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, + 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, + 0x00cf, 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, 0x00e0, + 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, + 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x00f0, 0x00f1, 0x00f2, + 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, + 0x00fc, 0x00fd, 0x00fe, 0x00ff}; +CFX_WideString PDF_DecodeText(const uint8_t* src_data, + FX_DWORD src_len, + CFX_CharMap* pCharMap) { + CFX_WideString result; + if (src_len >= 2 && ((src_data[0] == 0xfe && src_data[1] == 0xff) || + (src_data[0] == 0xff && src_data[1] == 0xfe))) { + FX_BOOL bBE = src_data[0] == 0xfe; + FX_DWORD max_chars = (src_len - 2) / 2; + if (!max_chars) { + return result; + } + if (src_data[0] == 0xff) { + bBE = !src_data[2]; + } + FX_WCHAR* dest_buf = result.GetBuffer(max_chars); + const uint8_t* uni_str = src_data + 2; + int dest_pos = 0; + for (FX_DWORD i = 0; i < max_chars * 2; i += 2) { + FX_WORD unicode = bBE ? (uni_str[i] << 8 | uni_str[i + 1]) + : (uni_str[i + 1] << 8 | uni_str[i]); + if (unicode == 0x1b) { + i += 2; + while (i < max_chars * 2) { + FX_WORD unicode = bBE ? (uni_str[i] << 8 | uni_str[i + 1]) + : (uni_str[i + 1] << 8 | uni_str[i]); + i += 2; + if (unicode == 0x1b) { + break; + } } - result.ReleaseBuffer(src_len); - } else { - return (*pCharMap->m_GetWideString)(pCharMap, CFX_ByteString((const FX_CHAR*)src_data, src_len)); - } - return result; + } else { + dest_buf[dest_pos++] = unicode; + } + } + result.ReleaseBuffer(dest_pos); + } else if (pCharMap == NULL) { + FX_WCHAR* dest_buf = result.GetBuffer(src_len); + for (FX_DWORD i = 0; i < src_len; i++) { + dest_buf[i] = PDFDocEncoding[src_data[i]]; + } + result.ReleaseBuffer(src_len); + } else { + return (*pCharMap->m_GetWideString)( + pCharMap, CFX_ByteString((const FX_CHAR*)src_data, src_len)); + } + return result; } -CFX_ByteString PDF_EncodeText(const FX_WCHAR* pString, int len, CFX_CharMap* pCharMap) -{ - if (len == -1) { - len = FXSYS_wcslen(pString); - } - CFX_ByteString result; - if (pCharMap == NULL) { - FX_CHAR* dest_buf1 = result.GetBuffer(len); - int i; - for (i = 0; i < len; i ++) { - int code; - for (code = 0; code < 256; code ++) - if (PDFDocEncoding[code] == pString[i]) { - break; - } - if (code == 256) { - break; - } - dest_buf1[i] = code; - } - result.ReleaseBuffer(i); - if (i == len) { - return result; +CFX_ByteString PDF_EncodeText(const FX_WCHAR* pString, + int len, + CFX_CharMap* pCharMap) { + if (len == -1) { + len = FXSYS_wcslen(pString); + } + CFX_ByteString result; + if (pCharMap == NULL) { + FX_CHAR* dest_buf1 = result.GetBuffer(len); + int i; + for (i = 0; i < len; i++) { + int code; + for (code = 0; code < 256; code++) + if (PDFDocEncoding[code] == pString[i]) { + break; } + if (code == 256) { + break; + } + dest_buf1[i] = code; } - - if(len > INT_MAX/2-1) - { - result.ReleaseBuffer(0); - return result; + result.ReleaseBuffer(i); + if (i == len) { + return result; } + } - int encLen = len * 2 + 2; - - uint8_t* dest_buf2 = (uint8_t*)result.GetBuffer(encLen); - dest_buf2[0] = 0xfe; - dest_buf2[1] = 0xff; - dest_buf2 += 2; - for (int i = 0; i < len; i ++) { - *dest_buf2++ = pString[i] >> 8; - *dest_buf2++ = (uint8_t)pString[i]; - } - result.ReleaseBuffer(encLen); + if (len > INT_MAX / 2 - 1) { + result.ReleaseBuffer(0); return result; + } + + int encLen = len * 2 + 2; + + uint8_t* dest_buf2 = (uint8_t*)result.GetBuffer(encLen); + dest_buf2[0] = 0xfe; + dest_buf2[1] = 0xff; + dest_buf2 += 2; + for (int i = 0; i < len; i++) { + *dest_buf2++ = pString[i] >> 8; + *dest_buf2++ = (uint8_t)pString[i]; + } + result.ReleaseBuffer(encLen); + return result; } -CFX_ByteString PDF_EncodeString(const CFX_ByteString& src, FX_BOOL bHex) -{ - CFX_ByteTextBuf result; - int srclen = src.GetLength(); - if (bHex) { - result.AppendChar('<'); - for (int i = 0; i < srclen; i ++) { - result.AppendChar("0123456789ABCDEF"[src[i] / 16]); - result.AppendChar("0123456789ABCDEF"[src[i] % 16]); - } - result.AppendChar('>'); - return result.GetByteString(); - } - result.AppendChar('('); - for (int i = 0; i < srclen; i ++) { - uint8_t ch = src[i]; - if (ch == ')' || ch == '\\' || ch == '(') { - result.AppendChar('\\'); - } else if (ch == 0x0a) { - result << FX_BSTRC("\\n"); - continue; - } else if (ch == 0x0d) { - result << FX_BSTRC("\\r"); - continue; - } - result.AppendChar(ch); - } - result.AppendChar(')'); +CFX_ByteString PDF_EncodeString(const CFX_ByteString& src, FX_BOOL bHex) { + CFX_ByteTextBuf result; + int srclen = src.GetLength(); + if (bHex) { + result.AppendChar('<'); + for (int i = 0; i < srclen; i++) { + result.AppendChar("0123456789ABCDEF"[src[i] / 16]); + result.AppendChar("0123456789ABCDEF"[src[i] % 16]); + } + result.AppendChar('>'); return result.GetByteString(); + } + result.AppendChar('('); + for (int i = 0; i < srclen; i++) { + uint8_t ch = src[i]; + if (ch == ')' || ch == '\\' || ch == '(') { + result.AppendChar('\\'); + } else if (ch == 0x0a) { + result << FX_BSTRC("\\n"); + continue; + } else if (ch == 0x0d) { + result << FX_BSTRC("\\r"); + continue; + } + result.AppendChar(ch); + } + result.AppendChar(')'); + return result.GetByteString(); } -void FlateEncode(const uint8_t* src_buf, FX_DWORD src_size, uint8_t*& dest_buf, FX_DWORD& dest_size) -{ - CCodec_ModuleMgr* pEncoders = CPDF_ModuleMgr::Get()->GetCodecModule(); - if (pEncoders) { - pEncoders->GetFlateModule()->Encode(src_buf, src_size, dest_buf, dest_size); - } +void FlateEncode(const uint8_t* src_buf, + FX_DWORD src_size, + uint8_t*& dest_buf, + FX_DWORD& dest_size) { + CCodec_ModuleMgr* pEncoders = CPDF_ModuleMgr::Get()->GetCodecModule(); + if (pEncoders) { + pEncoders->GetFlateModule()->Encode(src_buf, src_size, dest_buf, dest_size); + } } -void FlateEncode(const uint8_t* src_buf, FX_DWORD src_size, int predictor, int Colors, int BitsPerComponent, int Columns, - uint8_t*& dest_buf, FX_DWORD& dest_size) -{ - CCodec_ModuleMgr* pEncoders = CPDF_ModuleMgr::Get()->GetCodecModule(); - if (pEncoders) { - pEncoders->GetFlateModule()->Encode(src_buf, src_size, predictor, Colors, BitsPerComponent, Columns, dest_buf, dest_size); - } +void FlateEncode(const uint8_t* src_buf, + FX_DWORD src_size, + int predictor, + int Colors, + int BitsPerComponent, + int Columns, + uint8_t*& dest_buf, + FX_DWORD& dest_size) { + CCodec_ModuleMgr* pEncoders = CPDF_ModuleMgr::Get()->GetCodecModule(); + if (pEncoders) { + pEncoders->GetFlateModule()->Encode(src_buf, src_size, predictor, Colors, + BitsPerComponent, Columns, dest_buf, + dest_size); + } } -FX_DWORD FlateDecode(const uint8_t* src_buf, FX_DWORD src_size, uint8_t*& dest_buf, FX_DWORD& dest_size) -{ - CCodec_ModuleMgr* pEncoders = CPDF_ModuleMgr::Get()->GetCodecModule(); - if (pEncoders) { - return pEncoders->GetFlateModule()->FlateOrLZWDecode(FALSE, src_buf, src_size, FALSE, 0, 0, 0, 0, 0, dest_buf, dest_size); - } - return 0; +FX_DWORD FlateDecode(const uint8_t* src_buf, + FX_DWORD src_size, + uint8_t*& dest_buf, + FX_DWORD& dest_size) { + CCodec_ModuleMgr* pEncoders = CPDF_ModuleMgr::Get()->GetCodecModule(); + if (pEncoders) { + return pEncoders->GetFlateModule()->FlateOrLZWDecode( + FALSE, src_buf, src_size, FALSE, 0, 0, 0, 0, 0, dest_buf, dest_size); + } + return 0; } diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode_embeddertest.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode_embeddertest.cpp index 6f97c08d2d..3da522da4e 100644 --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode_embeddertest.cpp +++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode_embeddertest.cpp @@ -12,15 +12,16 @@ #include "../../../testing/embedder_test.h" #include "testing/gtest/include/gtest/gtest.h" -class FPDFParserDecodeEmbeddertest : public EmbedderTest { -}; +class FPDFParserDecodeEmbeddertest : public EmbedderTest {}; // NOTE: python's zlib.compress() and zlib.decompress() may be useful for // external validation of the FlateEncode/FlateDecode test cases. -#define TEST_CASE(input_literal, expected_literal) \ - { (const unsigned char*)input_literal, sizeof(input_literal) - 1, \ - (const unsigned char*)expected_literal, sizeof(expected_literal) - 1 } +#define TEST_CASE(input_literal, expected_literal) \ + { \ + (const unsigned char*) input_literal, sizeof(input_literal) - 1, \ + (const unsigned char*)expected_literal, sizeof(expected_literal) - 1 \ + } TEST_F(FPDFParserDecodeEmbeddertest, FlateEncode) { struct FlateEncodeCase { @@ -29,21 +30,20 @@ TEST_F(FPDFParserDecodeEmbeddertest, FlateEncode) { const unsigned char* expected; unsigned int expected_size; } flate_encode_cases[] = { - TEST_CASE("", "\x78\x9c\x03\x00\x00\x00\x00\x01"), - TEST_CASE(" ", "\x78\x9c\x53\x00\x00\x00\x21\x00\x21"), - TEST_CASE("123", "\x78\x9c\x33\x34\x32\x06\x00\01\x2d\x00\x97"), - TEST_CASE("\x00\xff", "\x78\x9c\x63\xf8\x0f\x00\x01\x01\x01\x00"), - TEST_CASE("1 0 0 -1 29 763 cm\n0 0 555 735 re\nW n\nq\n0 0 555 734.394 re\n" - "W n\nq\n0.8009 0 0 0.8009 0 0 cm\n1 1 1 RG 1 1 1 rg\n/G0 gs\n" - "0 0 693 917 re\nf\nQ\nQ\n" - , - "\x78\x9c\x33\x54\x30\x00\x42\x5d\x43\x05\x23\x4b\x05\x73\x33\x63" - "\x85\xe4\x5c\x2e\x90\x80\xa9\xa9\xa9\x82\xb9\xb1\xa9\x42\x51\x2a" - "\x57\xb8\x42\x1e\x57\x21\x92\xa0\x89\x9e\xb1\xa5\x09\x92\x84\x9e" - "\x85\x81\x81\x25\xd8\x14\x24\x26\xd0\x18\x43\x05\x10\x0c\x72\x57" - "\x80\x30\x8a\xd2\xb9\xf4\xdd\x0d\x14\xd2\x8b\xc1\x46\x99\x59\x1a" - "\x2b\x58\x1a\x9a\x83\x8c\x49\xe3\x0a\x04\x42\x00\x37\x4c\x1b\x42" - ), + TEST_CASE("", "\x78\x9c\x03\x00\x00\x00\x00\x01"), + TEST_CASE(" ", "\x78\x9c\x53\x00\x00\x00\x21\x00\x21"), + TEST_CASE("123", "\x78\x9c\x33\x34\x32\x06\x00\01\x2d\x00\x97"), + TEST_CASE("\x00\xff", "\x78\x9c\x63\xf8\x0f\x00\x01\x01\x01\x00"), + TEST_CASE( + "1 0 0 -1 29 763 cm\n0 0 555 735 re\nW n\nq\n0 0 555 734.394 re\n" + "W n\nq\n0.8009 0 0 0.8009 0 0 cm\n1 1 1 RG 1 1 1 rg\n/G0 gs\n" + "0 0 693 917 re\nf\nQ\nQ\n", + "\x78\x9c\x33\x54\x30\x00\x42\x5d\x43\x05\x23\x4b\x05\x73\x33\x63" + "\x85\xe4\x5c\x2e\x90\x80\xa9\xa9\xa9\x82\xb9\xb1\xa9\x42\x51\x2a" + "\x57\xb8\x42\x1e\x57\x21\x92\xa0\x89\x9e\xb1\xa5\x09\x92\x84\x9e" + "\x85\x81\x81\x25\xd8\x14\x24\x26\xd0\x18\x43\x05\x10\x0c\x72\x57" + "\x80\x30\x8a\xd2\xb9\xf4\xdd\x0d\x14\xd2\x8b\xc1\x46\x99\x59\x1a" + "\x2b\x58\x1a\x9a\x83\x8c\x49\xe3\x0a\x04\x42\x00\x37\x4c\x1b\x42"), }; for (size_t i = 0; i < FX_ArraySize(flate_encode_cases); ++i) { @@ -66,23 +66,21 @@ TEST_F(FPDFParserDecodeEmbeddertest, FlateDecode) { const unsigned char* expected; unsigned int expected_size; } flate_decode_cases[] = { - TEST_CASE("", ""), - TEST_CASE("preposterous nonsense", ""), - TEST_CASE("\x78\x9c\x03\x00\x00\x00\x00\x01", ""), - TEST_CASE("\x78\x9c\x53\x00\x00\x00\x21\x00\x21", " "), - TEST_CASE("\x78\x9c\x33\x34\x32\x06\x00\01\x2d\x00\x97", "123"), - TEST_CASE("\x78\x9c\x63\xf8\x0f\x00\x01\x01\x01\x00", "\x00\xff"), - TEST_CASE("\x78\x9c\x33\x54\x30\x00\x42\x5d\x43\x05\x23\x4b\x05\x73\x33\x63" - "\x85\xe4\x5c\x2e\x90\x80\xa9\xa9\xa9\x82\xb9\xb1\xa9\x42\x51\x2a" - "\x57\xb8\x42\x1e\x57\x21\x92\xa0\x89\x9e\xb1\xa5\x09\x92\x84\x9e" - "\x85\x81\x81\x25\xd8\x14\x24\x26\xd0\x18\x43\x05\x10\x0c\x72\x57" - "\x80\x30\x8a\xd2\xb9\xf4\xdd\x0d\x14\xd2\x8b\xc1\x46\x99\x59\x1a" - "\x2b\x58\x1a\x9a\x83\x8c\x49\xe3\x0a\x04\x42\x00\x37\x4c\x1b\x42" - , - "1 0 0 -1 29 763 cm\n0 0 555 735 re\nW n\nq\n0 0 555 734.394 re\n" - "W n\nq\n0.8009 0 0 0.8009 0 0 cm\n1 1 1 RG 1 1 1 rg\n/G0 gs\n" - "0 0 693 917 re\nf\nQ\nQ\n" - ), + TEST_CASE("", ""), TEST_CASE("preposterous nonsense", ""), + TEST_CASE("\x78\x9c\x03\x00\x00\x00\x00\x01", ""), + TEST_CASE("\x78\x9c\x53\x00\x00\x00\x21\x00\x21", " "), + TEST_CASE("\x78\x9c\x33\x34\x32\x06\x00\01\x2d\x00\x97", "123"), + TEST_CASE("\x78\x9c\x63\xf8\x0f\x00\x01\x01\x01\x00", "\x00\xff"), + TEST_CASE( + "\x78\x9c\x33\x54\x30\x00\x42\x5d\x43\x05\x23\x4b\x05\x73\x33\x63" + "\x85\xe4\x5c\x2e\x90\x80\xa9\xa9\xa9\x82\xb9\xb1\xa9\x42\x51\x2a" + "\x57\xb8\x42\x1e\x57\x21\x92\xa0\x89\x9e\xb1\xa5\x09\x92\x84\x9e" + "\x85\x81\x81\x25\xd8\x14\x24\x26\xd0\x18\x43\x05\x10\x0c\x72\x57" + "\x80\x30\x8a\xd2\xb9\xf4\xdd\x0d\x14\xd2\x8b\xc1\x46\x99\x59\x1a" + "\x2b\x58\x1a\x9a\x83\x8c\x49\xe3\x0a\x04\x42\x00\x37\x4c\x1b\x42", + "1 0 0 -1 29 763 cm\n0 0 555 735 re\nW n\nq\n0 0 555 734.394 re\n" + "W n\nq\n0.8009 0 0 0.8009 0 0 cm\n1 1 1 RG 1 1 1 rg\n/G0 gs\n" + "0 0 693 917 re\nf\nQ\nQ\n"), }; for (size_t i = 0; i < FX_ArraySize(flate_decode_cases); ++i) { @@ -98,5 +96,4 @@ TEST_F(FPDFParserDecodeEmbeddertest, FlateDecode) { } } - #undef TEST_CASE diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_document.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_document.cpp index c0f45c5379..0d7bdd8379 100644 --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_document.cpp +++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_document.cpp @@ -7,363 +7,355 @@ #include "../../../include/fpdfapi/fpdf_parser.h" #include "../../../include/fpdfapi/fpdf_module.h" -CPDF_Document::CPDF_Document(CPDF_Parser* pParser) : CPDF_IndirectObjects(pParser) -{ - ASSERT(pParser != NULL); - m_pRootDict = NULL; - m_pInfoDict = NULL; - m_bLinearized = FALSE; - m_dwFirstPageNo = 0; - m_dwFirstPageObjNum = 0; - m_pDocPage = CPDF_ModuleMgr::Get()->GetPageModule()->CreateDocData(this); - m_pDocRender = CPDF_ModuleMgr::Get()->GetRenderModule()->CreateDocData(this); +CPDF_Document::CPDF_Document(CPDF_Parser* pParser) + : CPDF_IndirectObjects(pParser) { + ASSERT(pParser != NULL); + m_pRootDict = NULL; + m_pInfoDict = NULL; + m_bLinearized = FALSE; + m_dwFirstPageNo = 0; + m_dwFirstPageObjNum = 0; + m_pDocPage = CPDF_ModuleMgr::Get()->GetPageModule()->CreateDocData(this); + m_pDocRender = CPDF_ModuleMgr::Get()->GetRenderModule()->CreateDocData(this); } -CPDF_DocPageData* CPDF_Document::GetValidatePageData() -{ - if (m_pDocPage) { - return m_pDocPage; - } - m_pDocPage = CPDF_ModuleMgr::Get()->GetPageModule()->CreateDocData(this); +CPDF_DocPageData* CPDF_Document::GetValidatePageData() { + if (m_pDocPage) { return m_pDocPage; + } + m_pDocPage = CPDF_ModuleMgr::Get()->GetPageModule()->CreateDocData(this); + return m_pDocPage; } -CPDF_DocRenderData* CPDF_Document::GetValidateRenderData() -{ - if (m_pDocRender) { - return m_pDocRender; - } - m_pDocRender = CPDF_ModuleMgr::Get()->GetRenderModule()->CreateDocData(this); +CPDF_DocRenderData* CPDF_Document::GetValidateRenderData() { + if (m_pDocRender) { return m_pDocRender; + } + m_pDocRender = CPDF_ModuleMgr::Get()->GetRenderModule()->CreateDocData(this); + return m_pDocRender; } -void CPDF_Document::LoadDoc() -{ - m_LastObjNum = m_pParser->GetLastObjNum(); - CPDF_Object* pRootObj = GetIndirectObject(m_pParser->GetRootObjNum()); - if (pRootObj == NULL) { - return; - } - m_pRootDict = pRootObj->GetDict(); - if (m_pRootDict == NULL) { - return; - } - CPDF_Object* pInfoObj = GetIndirectObject(m_pParser->GetInfoObjNum()); - if (pInfoObj) { - m_pInfoDict = pInfoObj->GetDict(); - } - CPDF_Array* pIDArray = m_pParser->GetIDArray(); - if (pIDArray) { - m_ID1 = pIDArray->GetString(0); - m_ID2 = pIDArray->GetString(1); - } - m_PageList.SetSize(_GetPageCount()); +void CPDF_Document::LoadDoc() { + m_LastObjNum = m_pParser->GetLastObjNum(); + CPDF_Object* pRootObj = GetIndirectObject(m_pParser->GetRootObjNum()); + if (pRootObj == NULL) { + return; + } + m_pRootDict = pRootObj->GetDict(); + if (m_pRootDict == NULL) { + return; + } + CPDF_Object* pInfoObj = GetIndirectObject(m_pParser->GetInfoObjNum()); + if (pInfoObj) { + m_pInfoDict = pInfoObj->GetDict(); + } + CPDF_Array* pIDArray = m_pParser->GetIDArray(); + if (pIDArray) { + m_ID1 = pIDArray->GetString(0); + m_ID2 = pIDArray->GetString(1); + } + m_PageList.SetSize(_GetPageCount()); } -void CPDF_Document::LoadAsynDoc(CPDF_Dictionary *pLinearized) -{ - m_bLinearized = TRUE; - m_LastObjNum = m_pParser->GetLastObjNum(); - CPDF_Object* indirectObj = GetIndirectObject(m_pParser->GetRootObjNum()); - m_pRootDict = indirectObj ? indirectObj->GetDict() : NULL; - if (m_pRootDict == NULL) { - return; - } - indirectObj = GetIndirectObject(m_pParser->GetInfoObjNum()); - m_pInfoDict = indirectObj ? indirectObj->GetDict() : NULL; - CPDF_Array* pIDArray = m_pParser->GetIDArray(); - if (pIDArray) { - m_ID1 = pIDArray->GetString(0); - m_ID2 = pIDArray->GetString(1); - } - FX_DWORD dwPageCount = 0; - CPDF_Object *pCount = pLinearized->GetElement(FX_BSTRC("N")); - if (pCount && pCount->GetType() == PDFOBJ_NUMBER) { - dwPageCount = pCount->GetInteger(); - } - m_PageList.SetSize(dwPageCount); - CPDF_Object *pNo = pLinearized->GetElement(FX_BSTRC("P")); - if (pNo && pNo->GetType() == PDFOBJ_NUMBER) { - m_dwFirstPageNo = pNo->GetInteger(); - } - CPDF_Object *pObjNum = pLinearized->GetElement(FX_BSTRC("O")); - if (pObjNum && pObjNum->GetType() == PDFOBJ_NUMBER) { - m_dwFirstPageObjNum = pObjNum->GetInteger(); - } +void CPDF_Document::LoadAsynDoc(CPDF_Dictionary* pLinearized) { + m_bLinearized = TRUE; + m_LastObjNum = m_pParser->GetLastObjNum(); + CPDF_Object* indirectObj = GetIndirectObject(m_pParser->GetRootObjNum()); + m_pRootDict = indirectObj ? indirectObj->GetDict() : NULL; + if (m_pRootDict == NULL) { + return; + } + indirectObj = GetIndirectObject(m_pParser->GetInfoObjNum()); + m_pInfoDict = indirectObj ? indirectObj->GetDict() : NULL; + CPDF_Array* pIDArray = m_pParser->GetIDArray(); + if (pIDArray) { + m_ID1 = pIDArray->GetString(0); + m_ID2 = pIDArray->GetString(1); + } + FX_DWORD dwPageCount = 0; + CPDF_Object* pCount = pLinearized->GetElement(FX_BSTRC("N")); + if (pCount && pCount->GetType() == PDFOBJ_NUMBER) { + dwPageCount = pCount->GetInteger(); + } + m_PageList.SetSize(dwPageCount); + CPDF_Object* pNo = pLinearized->GetElement(FX_BSTRC("P")); + if (pNo && pNo->GetType() == PDFOBJ_NUMBER) { + m_dwFirstPageNo = pNo->GetInteger(); + } + CPDF_Object* pObjNum = pLinearized->GetElement(FX_BSTRC("O")); + if (pObjNum && pObjNum->GetType() == PDFOBJ_NUMBER) { + m_dwFirstPageObjNum = pObjNum->GetInteger(); + } } -void CPDF_Document::LoadPages() -{ - m_PageList.SetSize(_GetPageCount()); +void CPDF_Document::LoadPages() { + m_PageList.SetSize(_GetPageCount()); } extern void FPDF_TTFaceMapper_ReleaseDoc(CPDF_Document*); -CPDF_Document::~CPDF_Document() -{ - if (m_pDocPage) { - CPDF_ModuleMgr::Get()->GetPageModule()->ReleaseDoc(this); - CPDF_ModuleMgr::Get()->GetPageModule()->ClearStockFont(this); - } - if (m_pDocRender) { - CPDF_ModuleMgr::Get()->GetRenderModule()->DestroyDocData(m_pDocRender); - } +CPDF_Document::~CPDF_Document() { + if (m_pDocPage) { + CPDF_ModuleMgr::Get()->GetPageModule()->ReleaseDoc(this); + CPDF_ModuleMgr::Get()->GetPageModule()->ClearStockFont(this); + } + if (m_pDocRender) { + CPDF_ModuleMgr::Get()->GetRenderModule()->DestroyDocData(m_pDocRender); + } } -#define FX_MAX_PAGE_LEVEL 1024 -CPDF_Dictionary* CPDF_Document::_FindPDFPage(CPDF_Dictionary* pPages, int iPage, int nPagesToGo, int level) -{ - CPDF_Array* pKidList = pPages->GetArray(FX_BSTRC("Kids")); - if (pKidList == NULL) { - if (nPagesToGo == 0) { - return pPages; - } - return NULL; - } - if (level >= FX_MAX_PAGE_LEVEL) { - return NULL; - } - int nKids = pKidList->GetCount(); - for (int i = 0; i < nKids; i ++) { - CPDF_Dictionary* pKid = pKidList->GetDict(i); - if (pKid == NULL) { - nPagesToGo --; - continue; - } - if (pKid == pPages) { - continue; - } - if (!pKid->KeyExist(FX_BSTRC("Kids"))) { - if (nPagesToGo == 0) { - return pKid; - } - m_PageList.SetAt(iPage - nPagesToGo, pKid->GetObjNum()); - nPagesToGo --; - } else { - int nPages = pKid->GetInteger(FX_BSTRC("Count")); - if (nPagesToGo < nPages) { - return _FindPDFPage(pKid, iPage, nPagesToGo, level + 1); - } - nPagesToGo -= nPages; - } +#define FX_MAX_PAGE_LEVEL 1024 +CPDF_Dictionary* CPDF_Document::_FindPDFPage(CPDF_Dictionary* pPages, + int iPage, + int nPagesToGo, + int level) { + CPDF_Array* pKidList = pPages->GetArray(FX_BSTRC("Kids")); + if (pKidList == NULL) { + if (nPagesToGo == 0) { + return pPages; } return NULL; + } + if (level >= FX_MAX_PAGE_LEVEL) { + return NULL; + } + int nKids = pKidList->GetCount(); + for (int i = 0; i < nKids; i++) { + CPDF_Dictionary* pKid = pKidList->GetDict(i); + if (pKid == NULL) { + nPagesToGo--; + continue; + } + if (pKid == pPages) { + continue; + } + if (!pKid->KeyExist(FX_BSTRC("Kids"))) { + if (nPagesToGo == 0) { + return pKid; + } + m_PageList.SetAt(iPage - nPagesToGo, pKid->GetObjNum()); + nPagesToGo--; + } else { + int nPages = pKid->GetInteger(FX_BSTRC("Count")); + if (nPagesToGo < nPages) { + return _FindPDFPage(pKid, iPage, nPagesToGo, level + 1); + } + nPagesToGo -= nPages; + } + } + return NULL; +} +CPDF_Dictionary* CPDF_Document::GetPage(int iPage) { + if (iPage < 0 || iPage >= m_PageList.GetSize()) { + return NULL; + } + if (m_bLinearized && (iPage == (int)m_dwFirstPageNo)) { + CPDF_Object* pObj = GetIndirectObject(m_dwFirstPageObjNum); + if (pObj && pObj->GetType() == PDFOBJ_DICTIONARY) { + return (CPDF_Dictionary*)pObj; + } + } + int objnum = m_PageList.GetAt(iPage); + if (objnum) { + CPDF_Object* pObj = GetIndirectObject(objnum); + ASSERT(pObj->GetType() == PDFOBJ_DICTIONARY); + return (CPDF_Dictionary*)pObj; + } + CPDF_Dictionary* pRoot = GetRoot(); + if (pRoot == NULL) { + return NULL; + } + CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages")); + if (pPages == NULL) { + return NULL; + } + CPDF_Dictionary* pPage = _FindPDFPage(pPages, iPage, iPage, 0); + if (pPage == NULL) { + return NULL; + } + m_PageList.SetAt(iPage, pPage->GetObjNum()); + return pPage; } -CPDF_Dictionary* CPDF_Document::GetPage(int iPage) -{ - if (iPage < 0 || iPage >= m_PageList.GetSize()) { - return NULL; +int CPDF_Document::_FindPageIndex(CPDF_Dictionary* pNode, + FX_DWORD& skip_count, + FX_DWORD objnum, + int& index, + int level) { + if (pNode->KeyExist(FX_BSTRC("Kids"))) { + CPDF_Array* pKidList = pNode->GetArray(FX_BSTRC("Kids")); + if (pKidList == NULL) { + return -1; } - if (m_bLinearized && (iPage == (int)m_dwFirstPageNo)) { - CPDF_Object* pObj = GetIndirectObject(m_dwFirstPageObjNum); - if (pObj && pObj->GetType() == PDFOBJ_DICTIONARY) { - return (CPDF_Dictionary*)pObj; + if (level >= FX_MAX_PAGE_LEVEL) { + return -1; + } + FX_DWORD count = pNode->GetInteger(FX_BSTRC("Count")); + if (count <= skip_count) { + skip_count -= count; + index += count; + return -1; + } + if (count && count == pKidList->GetCount()) { + for (FX_DWORD i = 0; i < count; i++) { + CPDF_Object* pKid = pKidList->GetElement(i); + if (pKid && pKid->GetType() == PDFOBJ_REFERENCE) { + if (((CPDF_Reference*)pKid)->GetRefObjNum() == objnum) { + m_PageList.SetAt(index + i, objnum); + return index + i; + } } - } - int objnum = m_PageList.GetAt(iPage); - if (objnum) { - CPDF_Object* pObj = GetIndirectObject(objnum); - ASSERT(pObj->GetType() == PDFOBJ_DICTIONARY); - return (CPDF_Dictionary*)pObj; - } - CPDF_Dictionary* pRoot = GetRoot(); - if (pRoot == NULL) { - return NULL; - } - CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages")); - if (pPages == NULL) { - return NULL; - } - CPDF_Dictionary* pPage = _FindPDFPage(pPages, iPage, iPage, 0); - if (pPage == NULL) { - return NULL; - } - m_PageList.SetAt(iPage, pPage->GetObjNum()); - return pPage; + } + } + for (FX_DWORD i = 0; i < pKidList->GetCount(); i++) { + CPDF_Dictionary* pKid = pKidList->GetDict(i); + if (pKid == NULL) { + continue; + } + if (pKid == pNode) { + continue; + } + int found_index = + _FindPageIndex(pKid, skip_count, objnum, index, level + 1); + if (found_index >= 0) { + return found_index; + } + } + } else { + if (objnum == pNode->GetObjNum()) { + return index; + } + if (skip_count) { + skip_count--; + } + index++; + } + return -1; } -int CPDF_Document::_FindPageIndex(CPDF_Dictionary* pNode, FX_DWORD& skip_count, FX_DWORD objnum, int& index, int level) -{ - if (pNode->KeyExist(FX_BSTRC("Kids"))) { - CPDF_Array* pKidList = pNode->GetArray(FX_BSTRC("Kids")); - if (pKidList == NULL) { - return -1; - } - if (level >= FX_MAX_PAGE_LEVEL) { - return -1; - } - FX_DWORD count = pNode->GetInteger(FX_BSTRC("Count")); - if (count <= skip_count) { - skip_count -= count; - index += count; - return -1; - } - if (count && count == pKidList->GetCount()) { - for (FX_DWORD i = 0; i < count; i ++) { - CPDF_Object* pKid = pKidList->GetElement(i); - if (pKid && pKid->GetType() == PDFOBJ_REFERENCE) { - if (((CPDF_Reference*) pKid)->GetRefObjNum() == objnum) { - m_PageList.SetAt(index + i, objnum); - return index + i; - } - } - } - } - for (FX_DWORD i = 0; i < pKidList->GetCount(); i ++) { - CPDF_Dictionary* pKid = pKidList->GetDict(i); - if (pKid == NULL) { - continue; - } - if (pKid == pNode) { - continue; - } - int found_index = _FindPageIndex(pKid, skip_count, objnum, index, level + 1); - if (found_index >= 0) { - return found_index; - } - } - } else { - if (objnum == pNode->GetObjNum()) { - return index; - } - if (skip_count) { - skip_count--; - } - index ++; - } +int CPDF_Document::GetPageIndex(FX_DWORD objnum) { + FX_DWORD nPages = m_PageList.GetSize(); + FX_DWORD skip_count = 0; + FX_BOOL bSkipped = FALSE; + for (FX_DWORD i = 0; i < nPages; i++) { + FX_DWORD objnum1 = m_PageList.GetAt(i); + if (objnum1 == objnum) { + return i; + } + if (!bSkipped && objnum1 == 0) { + skip_count = i; + bSkipped = TRUE; + } + } + CPDF_Dictionary* pRoot = GetRoot(); + if (pRoot == NULL) { return -1; + } + CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages")); + if (pPages == NULL) { + return -1; + } + int index = 0; + return _FindPageIndex(pPages, skip_count, objnum, index); } -int CPDF_Document::GetPageIndex(FX_DWORD objnum) -{ - FX_DWORD nPages = m_PageList.GetSize(); - FX_DWORD skip_count = 0; - FX_BOOL bSkipped = FALSE; - for (FX_DWORD i = 0; i < nPages; i ++) { - FX_DWORD objnum1 = m_PageList.GetAt(i); - if (objnum1 == objnum) { - return i; - } - if (!bSkipped && objnum1 == 0) { - skip_count = i; - bSkipped = TRUE; - } - } - CPDF_Dictionary* pRoot = GetRoot(); - if (pRoot == NULL) { - return -1; - } - CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages")); - if (pPages == NULL) { - return -1; - } - int index = 0; - return _FindPageIndex(pPages, skip_count, objnum, index); -} -int CPDF_Document::GetPageCount() const -{ - return m_PageList.GetSize(); +int CPDF_Document::GetPageCount() const { + return m_PageList.GetSize(); } -static int _CountPages(CPDF_Dictionary* pPages, int level) -{ - if (level > 128) { - return 0; - } - int count = pPages->GetInteger(FX_BSTRC("Count")); - if (count > 0 && count < FPDF_PAGE_MAX_NUM) { - return count; - } - CPDF_Array* pKidList = pPages->GetArray(FX_BSTRC("Kids")); - if (pKidList == NULL) { - return 0; - } - count = 0; - for (FX_DWORD i = 0; i < pKidList->GetCount(); i ++) { - CPDF_Dictionary* pKid = pKidList->GetDict(i); - if (pKid == NULL) { - continue; - } - if (!pKid->KeyExist(FX_BSTRC("Kids"))) { - count ++; - } else { - count += _CountPages(pKid, level + 1); - } - } - pPages->SetAtInteger(FX_BSTRC("Count"), count); +static int _CountPages(CPDF_Dictionary* pPages, int level) { + if (level > 128) { + return 0; + } + int count = pPages->GetInteger(FX_BSTRC("Count")); + if (count > 0 && count < FPDF_PAGE_MAX_NUM) { return count; -} -int CPDF_Document::_GetPageCount() const -{ - CPDF_Dictionary* pRoot = GetRoot(); - if (pRoot == NULL) { - return 0; - } - CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages")); - if (pPages == NULL) { - return 0; - } - if (!pPages->KeyExist(FX_BSTRC("Kids"))) { - return 1; + } + CPDF_Array* pKidList = pPages->GetArray(FX_BSTRC("Kids")); + if (pKidList == NULL) { + return 0; + } + count = 0; + for (FX_DWORD i = 0; i < pKidList->GetCount(); i++) { + CPDF_Dictionary* pKid = pKidList->GetDict(i); + if (pKid == NULL) { + continue; + } + if (!pKid->KeyExist(FX_BSTRC("Kids"))) { + count++; + } else { + count += _CountPages(pKid, level + 1); } - return _CountPages(pPages, 0); + } + pPages->SetAtInteger(FX_BSTRC("Count"), count); + return count; } -FX_BOOL CPDF_Document::IsContentUsedElsewhere(FX_DWORD objnum, CPDF_Dictionary* pThisPageDict) -{ - for (int i = 0; i < m_PageList.GetSize(); i ++) { - CPDF_Dictionary* pPageDict = GetPage(i); - if (pPageDict == pThisPageDict) { - continue; - } - CPDF_Object* pContents = pPageDict ? pPageDict->GetElement(FX_BSTRC("Contents")) : NULL; - if (pContents == NULL) { - continue; +int CPDF_Document::_GetPageCount() const { + CPDF_Dictionary* pRoot = GetRoot(); + if (pRoot == NULL) { + return 0; + } + CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages")); + if (pPages == NULL) { + return 0; + } + if (!pPages->KeyExist(FX_BSTRC("Kids"))) { + return 1; + } + return _CountPages(pPages, 0); +} +FX_BOOL CPDF_Document::IsContentUsedElsewhere(FX_DWORD objnum, + CPDF_Dictionary* pThisPageDict) { + for (int i = 0; i < m_PageList.GetSize(); i++) { + CPDF_Dictionary* pPageDict = GetPage(i); + if (pPageDict == pThisPageDict) { + continue; + } + CPDF_Object* pContents = + pPageDict ? pPageDict->GetElement(FX_BSTRC("Contents")) : NULL; + if (pContents == NULL) { + continue; + } + if (pContents->GetDirectType() == PDFOBJ_ARRAY) { + CPDF_Array* pArray = (CPDF_Array*)pContents->GetDirect(); + for (FX_DWORD j = 0; j < pArray->GetCount(); j++) { + CPDF_Object* pRef = pArray->GetElement(j); + if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) { + continue; } - if (pContents->GetDirectType() == PDFOBJ_ARRAY) { - CPDF_Array* pArray = (CPDF_Array*)pContents->GetDirect(); - for (FX_DWORD j = 0; j < pArray->GetCount(); j ++) { - CPDF_Object* pRef = pArray->GetElement(j); - if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) { - continue; - } - if (((CPDF_Reference*) pRef)->GetRefObjNum() == objnum) { - return TRUE; - } - } - } else if (pContents->GetObjNum() == objnum) { - return TRUE; + if (((CPDF_Reference*)pRef)->GetRefObjNum() == objnum) { + return TRUE; } + } + } else if (pContents->GetObjNum() == objnum) { + return TRUE; } - return FALSE; + } + return FALSE; } -FX_DWORD CPDF_Document::GetUserPermissions(FX_BOOL bCheckRevision) const -{ - if (m_pParser == NULL) { - return (FX_DWORD) - 1; - } - return m_pParser->GetPermissions(bCheckRevision); +FX_DWORD CPDF_Document::GetUserPermissions(FX_BOOL bCheckRevision) const { + if (m_pParser == NULL) { + return (FX_DWORD)-1; + } + return m_pParser->GetPermissions(bCheckRevision); } -FX_BOOL CPDF_Document::IsOwner() const -{ - if (m_pParser == NULL) { - return TRUE; - } - return m_pParser->IsOwner(); +FX_BOOL CPDF_Document::IsOwner() const { + if (m_pParser == NULL) { + return TRUE; + } + return m_pParser->IsOwner(); } -FX_BOOL CPDF_Document::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm) const -{ - { - CPDF_Object* pObj; - if (m_IndirectObjs.Lookup((void*)(uintptr_t)objnum, (void*&)pObj)) { - bForm = pObj->GetType() == PDFOBJ_STREAM && - ((CPDF_Stream*)pObj)->GetDict()->GetString(FX_BSTRC("Subtype")) == FX_BSTRC("Form"); - return TRUE; - } - } - if (m_pParser == NULL) { - bForm = FALSE; - return TRUE; - } - return m_pParser->IsFormStream(objnum, bForm); +FX_BOOL CPDF_Document::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm) const { + { + CPDF_Object* pObj; + if (m_IndirectObjs.Lookup((void*)(uintptr_t)objnum, (void*&)pObj)) { + bForm = pObj->GetType() == PDFOBJ_STREAM && + ((CPDF_Stream*)pObj)->GetDict()->GetString(FX_BSTRC("Subtype")) == + FX_BSTRC("Form"); + return TRUE; + } + } + if (m_pParser == NULL) { + bForm = FALSE; + return TRUE; + } + return m_pParser->IsFormStream(objnum, bForm); } -void CPDF_Document::ClearPageData() -{ - if (m_pDocPage) { - CPDF_ModuleMgr::Get()->GetPageModule()->ClearDoc(this); - } +void CPDF_Document::ClearPageData() { + if (m_pDocPage) { + CPDF_ModuleMgr::Get()->GetPageModule()->ClearDoc(this); + } } -void CPDF_Document::ClearRenderData() -{ - if (m_pDocRender) { - CPDF_ModuleMgr::Get()->GetRenderModule()->ClearDocData(m_pDocRender); - } +void CPDF_Document::ClearRenderData() { + if (m_pDocRender) { + CPDF_ModuleMgr::Get()->GetRenderModule()->ClearDocData(m_pDocRender); + } } diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_encrypt.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_encrypt.cpp index 9f356a4748..55e648a054 100644 --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_encrypt.cpp +++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_encrypt.cpp @@ -8,952 +8,1039 @@ #include "../../../include/fpdfapi/fpdf_parser.h" #include "../../../include/fdrm/fx_crypt.h" const uint8_t defpasscode[32] = { - 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, - 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08, - 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80, - 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a -}; -void CalcEncryptKey(CPDF_Dictionary* pEncrypt, const uint8_t* password, FX_DWORD pass_size, - uint8_t* key, int keylen, FX_BOOL bIgnoreMeta, CPDF_Array* pIdArray) -{ - int revision = pEncrypt->GetInteger(FX_BSTRC("R")); - uint8_t passcode[32]; - for (FX_DWORD i = 0; i < 32; i ++) { - passcode[i] = i < pass_size ? password[i] : defpasscode[i - pass_size]; - } - uint8_t md5[100]; - CRYPT_MD5Start(md5); - CRYPT_MD5Update(md5, passcode, 32); - CFX_ByteString okey = pEncrypt->GetString(FX_BSTRC("O")); - CRYPT_MD5Update(md5, (uint8_t*)okey.c_str(), okey.GetLength()); - FX_DWORD perm = pEncrypt->GetInteger(FX_BSTRC("P")); - CRYPT_MD5Update(md5, (uint8_t*)&perm, 4); - if (pIdArray) { - CFX_ByteString id = pIdArray->GetString(0); - CRYPT_MD5Update(md5, (uint8_t*)id.c_str(), id.GetLength()); - } - if (!bIgnoreMeta && revision >= 3 && !pEncrypt->GetInteger(FX_BSTRC("EncryptMetadata"), 1)) { - FX_DWORD tag = (FX_DWORD) - 1; - CRYPT_MD5Update(md5, (uint8_t*)&tag, 4); - } - uint8_t digest[16]; - CRYPT_MD5Finish(md5, digest); - FX_DWORD copy_len = keylen; - if (copy_len > sizeof(digest)) { - copy_len = sizeof(digest); - } - if (revision >= 3) { - for (int i = 0; i < 50; i ++) { - CRYPT_MD5Generate(digest, copy_len, digest); - } - } - FXSYS_memset(key, 0, keylen); - FXSYS_memcpy(key, digest, copy_len); + 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, 0x64, 0x00, 0x4e, + 0x56, 0xff, 0xfa, 0x01, 0x08, 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, + 0x3e, 0x80, 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a}; +void CalcEncryptKey(CPDF_Dictionary* pEncrypt, + const uint8_t* password, + FX_DWORD pass_size, + uint8_t* key, + int keylen, + FX_BOOL bIgnoreMeta, + CPDF_Array* pIdArray) { + int revision = pEncrypt->GetInteger(FX_BSTRC("R")); + uint8_t passcode[32]; + for (FX_DWORD i = 0; i < 32; i++) { + passcode[i] = i < pass_size ? password[i] : defpasscode[i - pass_size]; + } + uint8_t md5[100]; + CRYPT_MD5Start(md5); + CRYPT_MD5Update(md5, passcode, 32); + CFX_ByteString okey = pEncrypt->GetString(FX_BSTRC("O")); + CRYPT_MD5Update(md5, (uint8_t*)okey.c_str(), okey.GetLength()); + FX_DWORD perm = pEncrypt->GetInteger(FX_BSTRC("P")); + CRYPT_MD5Update(md5, (uint8_t*)&perm, 4); + if (pIdArray) { + CFX_ByteString id = pIdArray->GetString(0); + CRYPT_MD5Update(md5, (uint8_t*)id.c_str(), id.GetLength()); + } + if (!bIgnoreMeta && revision >= 3 && + !pEncrypt->GetInteger(FX_BSTRC("EncryptMetadata"), 1)) { + FX_DWORD tag = (FX_DWORD)-1; + CRYPT_MD5Update(md5, (uint8_t*)&tag, 4); + } + uint8_t digest[16]; + CRYPT_MD5Finish(md5, digest); + FX_DWORD copy_len = keylen; + if (copy_len > sizeof(digest)) { + copy_len = sizeof(digest); + } + if (revision >= 3) { + for (int i = 0; i < 50; i++) { + CRYPT_MD5Generate(digest, copy_len, digest); + } + } + FXSYS_memset(key, 0, keylen); + FXSYS_memcpy(key, digest, copy_len); } -CPDF_CryptoHandler* CPDF_StandardSecurityHandler::CreateCryptoHandler() -{ - return new CPDF_StandardCryptoHandler; +CPDF_CryptoHandler* CPDF_StandardSecurityHandler::CreateCryptoHandler() { + return new CPDF_StandardCryptoHandler; } -typedef struct _PDF_CRYPTOITEM { - int32_t m_Cipher; - int32_t m_KeyLen; - FX_BOOL m_bChecked; - CPDF_StandardCryptoHandler* m_pCryptoHandler; +typedef struct _PDF_CRYPTOITEM { + int32_t m_Cipher; + int32_t m_KeyLen; + FX_BOOL m_bChecked; + CPDF_StandardCryptoHandler* m_pCryptoHandler; } PDF_CRYPTOITEM; -CPDF_StandardSecurityHandler::CPDF_StandardSecurityHandler() -{ - m_Version = 0; - m_Revision = 0; - m_pParser = NULL; - m_pEncryptDict = NULL; - m_bOwner = FALSE; - m_Permissions = 0; - m_Cipher = FXCIPHER_NONE; - m_KeyLen = 0; -} -CPDF_StandardSecurityHandler::~CPDF_StandardSecurityHandler() -{ -} -FX_BOOL CPDF_StandardSecurityHandler::OnInit(CPDF_Parser* pParser, CPDF_Dictionary* pEncryptDict) -{ - m_pParser = pParser; - if (!LoadDict(pEncryptDict)) { - return FALSE; - } - if (m_Cipher == FXCIPHER_NONE) { - return TRUE; - } - return CheckSecurity(m_KeyLen); +CPDF_StandardSecurityHandler::CPDF_StandardSecurityHandler() { + m_Version = 0; + m_Revision = 0; + m_pParser = NULL; + m_pEncryptDict = NULL; + m_bOwner = FALSE; + m_Permissions = 0; + m_Cipher = FXCIPHER_NONE; + m_KeyLen = 0; } -FX_BOOL CPDF_StandardSecurityHandler::CheckSecurity(int32_t key_len) -{ - CFX_ByteString password = m_pParser->GetPassword(); - if (CheckPassword(password, password.GetLength(), TRUE, m_EncryptKey, key_len)) { - if (password.IsEmpty()) { - if (!CheckPassword(password, password.GetLength(), FALSE, m_EncryptKey, key_len)) { - return FALSE; - } - } - m_bOwner = TRUE; - return TRUE; - } - return CheckPassword(password, password.GetLength(), FALSE, m_EncryptKey, key_len); -} -FX_DWORD CPDF_StandardSecurityHandler::GetPermissions() -{ - return m_Permissions; -} -static FX_BOOL _LoadCryptInfo(CPDF_Dictionary* pEncryptDict, const CFX_ByteStringC& name, int& cipher, int& keylen) -{ - int Version = pEncryptDict->GetInteger(FX_BSTRC("V")); - cipher = FXCIPHER_RC4; - keylen = 0; - if (Version >= 4) { - CPDF_Dictionary* pCryptFilters = pEncryptDict->GetDict(FX_BSTRC("CF")); - if (pCryptFilters == NULL) { - return FALSE; - } - if (name == FX_BSTRC("Identity")) { - cipher = FXCIPHER_NONE; - } else { - CPDF_Dictionary* pDefFilter = pCryptFilters->GetDict(name); - if (pDefFilter == NULL) { - return FALSE; - } - int nKeyBits = 0; - if (Version == 4) { - nKeyBits = pDefFilter->GetInteger(FX_BSTRC("Length"), 0); - if (nKeyBits == 0) { - nKeyBits = pEncryptDict->GetInteger(FX_BSTRC("Length"), 128); - } - } else { - nKeyBits = pEncryptDict->GetInteger(FX_BSTRC("Length"), 256); - } - if (nKeyBits < 40) { - nKeyBits *= 8; - } - keylen = nKeyBits / 8; - CFX_ByteString cipher_name = pDefFilter->GetString(FX_BSTRC("CFM")); - if (cipher_name == FX_BSTRC("AESV2") || cipher_name == FX_BSTRC("AESV3")) { - cipher = FXCIPHER_AES; - } - } - } else { - keylen = Version > 1 ? pEncryptDict->GetInteger(FX_BSTRC("Length"), 40) / 8 : 5; - } - if (keylen > 32 || keylen < 0) { - return FALSE; - } +CPDF_StandardSecurityHandler::~CPDF_StandardSecurityHandler() {} +FX_BOOL CPDF_StandardSecurityHandler::OnInit(CPDF_Parser* pParser, + CPDF_Dictionary* pEncryptDict) { + m_pParser = pParser; + if (!LoadDict(pEncryptDict)) { + return FALSE; + } + if (m_Cipher == FXCIPHER_NONE) { return TRUE; + } + return CheckSecurity(m_KeyLen); } -FX_BOOL CPDF_StandardSecurityHandler::LoadDict(CPDF_Dictionary* pEncryptDict) -{ - m_pEncryptDict = pEncryptDict; - m_bOwner = FALSE; - m_Version = pEncryptDict->GetInteger(FX_BSTRC("V")); - m_Revision = pEncryptDict->GetInteger(FX_BSTRC("R")); - m_Permissions = pEncryptDict->GetInteger(FX_BSTRC("P"), -1); - if (m_Version < 4) { - return _LoadCryptInfo(pEncryptDict, CFX_ByteString(), m_Cipher, m_KeyLen); - } - CFX_ByteString stmf_name = pEncryptDict->GetString(FX_BSTRC("StmF")); - CFX_ByteString strf_name = pEncryptDict->GetString(FX_BSTRC("StrF")); - if (stmf_name != strf_name) { - return FALSE; - } - if (!_LoadCryptInfo(pEncryptDict, strf_name, m_Cipher, m_KeyLen)) { +FX_BOOL CPDF_StandardSecurityHandler::CheckSecurity(int32_t key_len) { + CFX_ByteString password = m_pParser->GetPassword(); + if (CheckPassword(password, password.GetLength(), TRUE, m_EncryptKey, + key_len)) { + if (password.IsEmpty()) { + if (!CheckPassword(password, password.GetLength(), FALSE, m_EncryptKey, + key_len)) { return FALSE; + } } + m_bOwner = TRUE; return TRUE; + } + return CheckPassword(password, password.GetLength(), FALSE, m_EncryptKey, + key_len); } -FX_BOOL CPDF_StandardSecurityHandler::LoadDict(CPDF_Dictionary* pEncryptDict, FX_DWORD type, int& cipher, int& key_len) -{ - m_pEncryptDict = pEncryptDict; - m_bOwner = FALSE; - m_Version = pEncryptDict->GetInteger(FX_BSTRC("V")); - m_Revision = pEncryptDict->GetInteger(FX_BSTRC("R")); - m_Permissions = pEncryptDict->GetInteger(FX_BSTRC("P"), -1); - CFX_ByteString strf_name, stmf_name; - if (m_Version >= 4) { - stmf_name = pEncryptDict->GetString(FX_BSTRC("StmF")); - strf_name = pEncryptDict->GetString(FX_BSTRC("StrF")); - if (stmf_name != strf_name) { - return FALSE; - } - } - if (!_LoadCryptInfo(pEncryptDict, strf_name, cipher, key_len)) { +FX_DWORD CPDF_StandardSecurityHandler::GetPermissions() { + return m_Permissions; +} +static FX_BOOL _LoadCryptInfo(CPDF_Dictionary* pEncryptDict, + const CFX_ByteStringC& name, + int& cipher, + int& keylen) { + int Version = pEncryptDict->GetInteger(FX_BSTRC("V")); + cipher = FXCIPHER_RC4; + keylen = 0; + if (Version >= 4) { + CPDF_Dictionary* pCryptFilters = pEncryptDict->GetDict(FX_BSTRC("CF")); + if (pCryptFilters == NULL) { + return FALSE; + } + if (name == FX_BSTRC("Identity")) { + cipher = FXCIPHER_NONE; + } else { + CPDF_Dictionary* pDefFilter = pCryptFilters->GetDict(name); + if (pDefFilter == NULL) { return FALSE; + } + int nKeyBits = 0; + if (Version == 4) { + nKeyBits = pDefFilter->GetInteger(FX_BSTRC("Length"), 0); + if (nKeyBits == 0) { + nKeyBits = pEncryptDict->GetInteger(FX_BSTRC("Length"), 128); + } + } else { + nKeyBits = pEncryptDict->GetInteger(FX_BSTRC("Length"), 256); + } + if (nKeyBits < 40) { + nKeyBits *= 8; + } + keylen = nKeyBits / 8; + CFX_ByteString cipher_name = pDefFilter->GetString(FX_BSTRC("CFM")); + if (cipher_name == FX_BSTRC("AESV2") || + cipher_name == FX_BSTRC("AESV3")) { + cipher = FXCIPHER_AES; + } + } + } else { + keylen = + Version > 1 ? pEncryptDict->GetInteger(FX_BSTRC("Length"), 40) / 8 : 5; + } + if (keylen > 32 || keylen < 0) { + return FALSE; + } + return TRUE; +} +FX_BOOL CPDF_StandardSecurityHandler::LoadDict(CPDF_Dictionary* pEncryptDict) { + m_pEncryptDict = pEncryptDict; + m_bOwner = FALSE; + m_Version = pEncryptDict->GetInteger(FX_BSTRC("V")); + m_Revision = pEncryptDict->GetInteger(FX_BSTRC("R")); + m_Permissions = pEncryptDict->GetInteger(FX_BSTRC("P"), -1); + if (m_Version < 4) { + return _LoadCryptInfo(pEncryptDict, CFX_ByteString(), m_Cipher, m_KeyLen); + } + CFX_ByteString stmf_name = pEncryptDict->GetString(FX_BSTRC("StmF")); + CFX_ByteString strf_name = pEncryptDict->GetString(FX_BSTRC("StrF")); + if (stmf_name != strf_name) { + return FALSE; + } + if (!_LoadCryptInfo(pEncryptDict, strf_name, m_Cipher, m_KeyLen)) { + return FALSE; + } + return TRUE; +} +FX_BOOL CPDF_StandardSecurityHandler::LoadDict(CPDF_Dictionary* pEncryptDict, + FX_DWORD type, + int& cipher, + int& key_len) { + m_pEncryptDict = pEncryptDict; + m_bOwner = FALSE; + m_Version = pEncryptDict->GetInteger(FX_BSTRC("V")); + m_Revision = pEncryptDict->GetInteger(FX_BSTRC("R")); + m_Permissions = pEncryptDict->GetInteger(FX_BSTRC("P"), -1); + CFX_ByteString strf_name, stmf_name; + if (m_Version >= 4) { + stmf_name = pEncryptDict->GetString(FX_BSTRC("StmF")); + strf_name = pEncryptDict->GetString(FX_BSTRC("StrF")); + if (stmf_name != strf_name) { + return FALSE; } - m_Cipher = cipher; - m_KeyLen = key_len; - return TRUE; - return TRUE; + } + if (!_LoadCryptInfo(pEncryptDict, strf_name, cipher, key_len)) { + return FALSE; + } + m_Cipher = cipher; + m_KeyLen = key_len; + return TRUE; + return TRUE; } -FX_BOOL CPDF_StandardSecurityHandler::GetCryptInfo(int& cipher, const uint8_t*& buffer, int& keylen) -{ - cipher = m_Cipher; - buffer = m_EncryptKey; - keylen = m_KeyLen; - return TRUE; +FX_BOOL CPDF_StandardSecurityHandler::GetCryptInfo(int& cipher, + const uint8_t*& buffer, + int& keylen) { + cipher = m_Cipher; + buffer = m_EncryptKey; + keylen = m_KeyLen; + return TRUE; } -#define FX_GET_32WORD(n,b,i) \ - { \ - (n) = (FX_DWORD)(( (uint64_t) (b)[(i)] << 24 ) \ - | ( (uint64_t) (b)[(i) + 1] << 16 ) \ - | ( (uint64_t) (b)[(i) + 2] << 8 ) \ - | ( (uint64_t) (b)[(i) + 3] )); \ - } -int BigOrder64BitsMod3(uint8_t* data) -{ - uint64_t ret = 0; - for (int i = 0; i < 4; ++i) { - FX_DWORD value; - FX_GET_32WORD(value, data, 4 * i); - ret <<= 32; - ret |= value; - ret %= 3; - } - return (int)ret; -} -void Revision6_Hash(const uint8_t* password, FX_DWORD size, const uint8_t* salt, const uint8_t* vector, uint8_t* hash) -{ - int iBlockSize = 32; - uint8_t sha[128]; +#define FX_GET_32WORD(n, b, i) \ + { \ + (n) = (FX_DWORD)( \ + ((uint64_t)(b)[(i)] << 24) | ((uint64_t)(b)[(i) + 1] << 16) | \ + ((uint64_t)(b)[(i) + 2] << 8) | ((uint64_t)(b)[(i) + 3])); \ + } +int BigOrder64BitsMod3(uint8_t* data) { + uint64_t ret = 0; + for (int i = 0; i < 4; ++i) { + FX_DWORD value; + FX_GET_32WORD(value, data, 4 * i); + ret <<= 32; + ret |= value; + ret %= 3; + } + return (int)ret; +} +void Revision6_Hash(const uint8_t* password, + FX_DWORD size, + const uint8_t* salt, + const uint8_t* vector, + uint8_t* hash) { + int iBlockSize = 32; + uint8_t sha[128]; + CRYPT_SHA256Start(sha); + CRYPT_SHA256Update(sha, password, size); + CRYPT_SHA256Update(sha, salt, 8); + if (vector) { + CRYPT_SHA256Update(sha, vector, 48); + } + uint8_t digest[32]; + CRYPT_SHA256Finish(sha, digest); + CFX_ByteTextBuf buf; + uint8_t* input = digest; + uint8_t* key = input; + uint8_t* iv = input + 16; + uint8_t* E = buf.GetBuffer(); + int iBufLen = buf.GetLength(); + CFX_ByteTextBuf interDigest; + int i = 0; + uint8_t* aes = FX_Alloc(uint8_t, 2048); + while (i < 64 || i < E[iBufLen - 1] + 32) { + int iRoundSize = size + iBlockSize; + if (vector) { + iRoundSize += 48; + } + iBufLen = iRoundSize * 64; + buf.EstimateSize(iBufLen); + E = buf.GetBuffer(); + CFX_ByteTextBuf content; + for (int j = 0; j < 64; ++j) { + content.AppendBlock(password, size); + content.AppendBlock(input, iBlockSize); + if (vector) { + content.AppendBlock(vector, 48); + } + } + CRYPT_AESSetKey(aes, 16, key, 16, TRUE); + CRYPT_AESSetIV(aes, iv); + CRYPT_AESEncrypt(aes, E, content.GetBuffer(), iBufLen); + int iHash = 0; + switch (BigOrder64BitsMod3(E)) { + case 0: + iHash = 0; + iBlockSize = 32; + break; + case 1: + iHash = 1; + iBlockSize = 48; + break; + default: + iHash = 2; + iBlockSize = 64; + break; + } + interDigest.EstimateSize(iBlockSize); + input = interDigest.GetBuffer(); + if (iHash == 0) { + CRYPT_SHA256Generate(E, iBufLen, input); + } else if (iHash == 1) { + CRYPT_SHA384Generate(E, iBufLen, input); + } else if (iHash == 2) { + CRYPT_SHA512Generate(E, iBufLen, input); + } + key = input; + iv = input + 16; + ++i; + } + FX_Free(aes); + if (hash) { + FXSYS_memcpy(hash, input, 32); + } +} +FX_BOOL CPDF_StandardSecurityHandler::AES256_CheckPassword( + const uint8_t* password, + FX_DWORD size, + FX_BOOL bOwner, + uint8_t* key) { + CFX_ByteString okey = m_pEncryptDict + ? m_pEncryptDict->GetString(FX_BSTRC("O")) + : CFX_ByteString(); + if (okey.GetLength() < 48) { + return FALSE; + } + CFX_ByteString ukey = m_pEncryptDict + ? m_pEncryptDict->GetString(FX_BSTRC("U")) + : CFX_ByteString(); + if (ukey.GetLength() < 48) { + return FALSE; + } + const uint8_t* pkey = bOwner ? (const uint8_t*)okey : (const uint8_t*)ukey; + uint8_t sha[128]; + uint8_t digest[32]; + if (m_Revision >= 6) { + Revision6_Hash(password, size, (const uint8_t*)pkey + 32, + (bOwner ? (const uint8_t*)ukey : NULL), digest); + } else { CRYPT_SHA256Start(sha); CRYPT_SHA256Update(sha, password, size); - CRYPT_SHA256Update(sha, salt, 8); - if (vector) { - CRYPT_SHA256Update(sha, vector, 48); + CRYPT_SHA256Update(sha, pkey + 32, 8); + if (bOwner) { + CRYPT_SHA256Update(sha, ukey, 48); } - uint8_t digest[32]; CRYPT_SHA256Finish(sha, digest); - CFX_ByteTextBuf buf; - uint8_t* input = digest; - uint8_t* key = input; - uint8_t* iv = input + 16; - uint8_t* E = buf.GetBuffer(); - int iBufLen = buf.GetLength(); - CFX_ByteTextBuf interDigest; - int i = 0; - uint8_t* aes = FX_Alloc(uint8_t, 2048); - while (i < 64 || i < E[iBufLen - 1] + 32) { - int iRoundSize = size + iBlockSize; - if (vector) { - iRoundSize += 48; - } - iBufLen = iRoundSize * 64; - buf.EstimateSize(iBufLen); - E = buf.GetBuffer(); - CFX_ByteTextBuf content; - for (int j = 0; j < 64; ++j) { - content.AppendBlock(password, size); - content.AppendBlock(input, iBlockSize); - if (vector) { - content.AppendBlock(vector, 48); - } - } - CRYPT_AESSetKey(aes, 16, key, 16, TRUE); - CRYPT_AESSetIV(aes, iv); - CRYPT_AESEncrypt(aes, E, content.GetBuffer(), iBufLen); - int iHash = 0; - switch (BigOrder64BitsMod3(E)) { - case 0: - iHash = 0; - iBlockSize = 32; - break; - case 1: - iHash = 1; - iBlockSize = 48; - break; - default: - iHash = 2; - iBlockSize = 64; - break; - } - interDigest.EstimateSize(iBlockSize); - input = interDigest.GetBuffer(); - if (iHash == 0) { - CRYPT_SHA256Generate(E, iBufLen, input); - } else if (iHash == 1) { - CRYPT_SHA384Generate(E, iBufLen, input); - } else if (iHash == 2) { - CRYPT_SHA512Generate(E, iBufLen, input); - } - key = input; - iv = input + 16; - ++i; - } - FX_Free(aes); - if (hash) { - FXSYS_memcpy(hash, input, 32); + } + if (FXSYS_memcmp(digest, pkey, 32) != 0) { + return FALSE; + } + if (key == NULL) { + return TRUE; + } + if (m_Revision >= 6) { + Revision6_Hash(password, size, (const uint8_t*)pkey + 40, + (bOwner ? (const uint8_t*)ukey : NULL), digest); + } else { + CRYPT_SHA256Start(sha); + CRYPT_SHA256Update(sha, password, size); + CRYPT_SHA256Update(sha, pkey + 40, 8); + if (bOwner) { + CRYPT_SHA256Update(sha, ukey, 48); } + CRYPT_SHA256Finish(sha, digest); + } + CFX_ByteString ekey = + m_pEncryptDict + ? m_pEncryptDict->GetString(bOwner ? FX_BSTRC("OE") : FX_BSTRC("UE")) + : CFX_ByteString(); + if (ekey.GetLength() < 32) { + return FALSE; + } + uint8_t* aes = FX_Alloc(uint8_t, 2048); + CRYPT_AESSetKey(aes, 16, digest, 32, FALSE); + uint8_t iv[16]; + FXSYS_memset(iv, 0, 16); + CRYPT_AESSetIV(aes, iv); + CRYPT_AESDecrypt(aes, key, ekey, 32); + CRYPT_AESSetKey(aes, 16, key, 32, FALSE); + CRYPT_AESSetIV(aes, iv); + CFX_ByteString perms = m_pEncryptDict->GetString(FX_BSTRC("Perms")); + if (perms.IsEmpty()) { + return FALSE; + } + uint8_t perms_buf[16]; + FXSYS_memset(perms_buf, 0, sizeof(perms_buf)); + FX_DWORD copy_len = sizeof(perms_buf); + if (copy_len > (FX_DWORD)perms.GetLength()) { + copy_len = perms.GetLength(); + } + FXSYS_memcpy(perms_buf, (const uint8_t*)perms, copy_len); + uint8_t buf[16]; + CRYPT_AESDecrypt(aes, buf, perms_buf, 16); + FX_Free(aes); + if (buf[9] != 'a' || buf[10] != 'd' || buf[11] != 'b') { + return FALSE; + } + if (FXDWORD_GET_LSBFIRST(buf) != m_Permissions) { + return FALSE; + } + if ((buf[8] == 'T' && !IsMetadataEncrypted()) || + (buf[8] == 'F' && IsMetadataEncrypted())) { + return FALSE; + } + return TRUE; } -FX_BOOL CPDF_StandardSecurityHandler::AES256_CheckPassword(const uint8_t* password, FX_DWORD size, - FX_BOOL bOwner, uint8_t* key) -{ - CFX_ByteString okey = m_pEncryptDict ? m_pEncryptDict->GetString(FX_BSTRC("O")) : CFX_ByteString(); - if (okey.GetLength() < 48) { - return FALSE; - } - CFX_ByteString ukey = m_pEncryptDict ? m_pEncryptDict->GetString(FX_BSTRC("U")) : CFX_ByteString(); - if (ukey.GetLength() < 48) { - return FALSE; - } - const uint8_t* pkey = bOwner ? (const uint8_t*)okey : (const uint8_t*)ukey; - uint8_t sha[128]; - uint8_t digest[32]; - if (m_Revision >= 6) { - Revision6_Hash(password, size, (const uint8_t*)pkey + 32, (bOwner ? (const uint8_t*)ukey : NULL), digest); - } else { - CRYPT_SHA256Start(sha); - CRYPT_SHA256Update(sha, password, size); - CRYPT_SHA256Update(sha, pkey + 32, 8); - if (bOwner) { - CRYPT_SHA256Update(sha, ukey, 48); - } - CRYPT_SHA256Finish(sha, digest); - } - if (FXSYS_memcmp(digest, pkey, 32) != 0) { - return FALSE; - } - if (key == NULL) { - return TRUE; - } - if (m_Revision >= 6) { - Revision6_Hash(password, size, (const uint8_t*)pkey + 40, (bOwner ? (const uint8_t*)ukey : NULL), digest); - } else { - CRYPT_SHA256Start(sha); - CRYPT_SHA256Update(sha, password, size); - CRYPT_SHA256Update(sha, pkey + 40, 8); - if (bOwner) { - CRYPT_SHA256Update(sha, ukey, 48); - } - CRYPT_SHA256Finish(sha, digest); - } - CFX_ByteString ekey = m_pEncryptDict ? m_pEncryptDict->GetString(bOwner ? FX_BSTRC("OE") : FX_BSTRC("UE")) : CFX_ByteString(); - if (ekey.GetLength() < 32) { - return FALSE; - } - uint8_t* aes = FX_Alloc(uint8_t, 2048); - CRYPT_AESSetKey(aes, 16, digest, 32, FALSE); - uint8_t iv[16]; - FXSYS_memset(iv, 0, 16); - CRYPT_AESSetIV(aes, iv); - CRYPT_AESDecrypt(aes, key, ekey, 32); - CRYPT_AESSetKey(aes, 16, key, 32, FALSE); - CRYPT_AESSetIV(aes, iv); - CFX_ByteString perms = m_pEncryptDict->GetString(FX_BSTRC("Perms")); - if (perms.IsEmpty()) { - return FALSE; - } - uint8_t perms_buf[16]; - FXSYS_memset(perms_buf, 0, sizeof(perms_buf)); - FX_DWORD copy_len = sizeof(perms_buf); - if (copy_len > (FX_DWORD)perms.GetLength()) { - copy_len = perms.GetLength(); - } - FXSYS_memcpy(perms_buf, (const uint8_t*)perms, copy_len); - uint8_t buf[16]; - CRYPT_AESDecrypt(aes, buf, perms_buf, 16); - FX_Free(aes); - if (buf[9] != 'a' || buf[10] != 'd' || buf[11] != 'b') { - return FALSE; - } - if (FXDWORD_GET_LSBFIRST(buf) != m_Permissions) { - return FALSE; +int CPDF_StandardSecurityHandler::CheckPassword(const uint8_t* password, + FX_DWORD pass_size, + FX_BOOL bOwner, + uint8_t* key) { + return CheckPassword(password, pass_size, bOwner, key, m_KeyLen); +} +int CPDF_StandardSecurityHandler::CheckPassword(const uint8_t* password, + FX_DWORD size, + FX_BOOL bOwner, + uint8_t* key, + int32_t key_len) { + if (m_Revision >= 5) { + return AES256_CheckPassword(password, size, bOwner, key); + } + uint8_t keybuf[32]; + if (key == NULL) { + key = keybuf; + } + if (bOwner) { + return CheckOwnerPassword(password, size, key, key_len); + } + return CheckUserPassword(password, size, FALSE, key, key_len) || + CheckUserPassword(password, size, TRUE, key, key_len); +} +FX_BOOL CPDF_StandardSecurityHandler::CheckUserPassword( + const uint8_t* password, + FX_DWORD pass_size, + FX_BOOL bIgnoreEncryptMeta, + uint8_t* key, + int32_t key_len) { + CalcEncryptKey(m_pEncryptDict, password, pass_size, key, key_len, + bIgnoreEncryptMeta, m_pParser->GetIDArray()); + CFX_ByteString ukey = m_pEncryptDict + ? m_pEncryptDict->GetString(FX_BSTRC("U")) + : CFX_ByteString(); + if (ukey.GetLength() < 16) { + return FALSE; + } + uint8_t ukeybuf[32]; + if (m_Revision == 2) { + FXSYS_memcpy(ukeybuf, defpasscode, 32); + CRYPT_ArcFourCryptBlock(ukeybuf, 32, key, key_len); + } else { + uint8_t test[32], tmpkey[32]; + FX_DWORD copy_len = sizeof(test); + if (copy_len > (FX_DWORD)ukey.GetLength()) { + copy_len = ukey.GetLength(); + } + FXSYS_memset(test, 0, sizeof(test)); + FXSYS_memset(tmpkey, 0, sizeof(tmpkey)); + FXSYS_memcpy(test, ukey.c_str(), copy_len); + for (int i = 19; i >= 0; i--) { + for (int j = 0; j < key_len; j++) { + tmpkey[j] = key[j] ^ i; + } + CRYPT_ArcFourCryptBlock(test, 32, tmpkey, key_len); } - if ((buf[8] == 'T' && !IsMetadataEncrypted()) || (buf[8] == 'F' && IsMetadataEncrypted())) { - return FALSE; + uint8_t md5[100]; + CRYPT_MD5Start(md5); + CRYPT_MD5Update(md5, defpasscode, 32); + CPDF_Array* pIdArray = m_pParser->GetIDArray(); + if (pIdArray) { + CFX_ByteString id = pIdArray->GetString(0); + CRYPT_MD5Update(md5, (uint8_t*)id.c_str(), id.GetLength()); } + CRYPT_MD5Finish(md5, ukeybuf); + return FXSYS_memcmp(test, ukeybuf, 16) == 0; + } + if (FXSYS_memcmp((void*)ukey.c_str(), ukeybuf, 16) == 0) { return TRUE; + } + return FALSE; } -int CPDF_StandardSecurityHandler::CheckPassword(const uint8_t* password, FX_DWORD pass_size, FX_BOOL bOwner, uint8_t* key) -{ - return CheckPassword(password, pass_size, bOwner, key, m_KeyLen); +CFX_ByteString CPDF_StandardSecurityHandler::GetUserPassword( + const uint8_t* owner_pass, + FX_DWORD pass_size) { + return GetUserPassword(owner_pass, pass_size, m_KeyLen); } -int CPDF_StandardSecurityHandler::CheckPassword(const uint8_t* password, FX_DWORD size, FX_BOOL bOwner, uint8_t* key, int32_t key_len) -{ - if (m_Revision >= 5) { - return AES256_CheckPassword(password, size, bOwner, key); - } - uint8_t keybuf[32]; - if (key == NULL) { - key = keybuf; - } - if (bOwner) { - return CheckOwnerPassword(password, size, key, key_len); - } - return CheckUserPassword(password, size, FALSE, key, key_len) || CheckUserPassword(password, size, TRUE, key, key_len); +CFX_ByteString CPDF_StandardSecurityHandler::GetUserPassword( + const uint8_t* owner_pass, + FX_DWORD pass_size, + int32_t key_len) { + CFX_ByteString okey = m_pEncryptDict->GetString(FX_BSTRC("O")); + uint8_t passcode[32]; + FX_DWORD i; + for (i = 0; i < 32; i++) { + passcode[i] = i < pass_size ? owner_pass[i] : defpasscode[i - pass_size]; + } + uint8_t digest[16]; + CRYPT_MD5Generate(passcode, 32, digest); + if (m_Revision >= 3) { + for (int i = 0; i < 50; i++) { + CRYPT_MD5Generate(digest, 16, digest); + } + } + uint8_t enckey[32]; + FXSYS_memset(enckey, 0, sizeof(enckey)); + FX_DWORD copy_len = key_len; + if (copy_len > sizeof(digest)) { + copy_len = sizeof(digest); + } + FXSYS_memcpy(enckey, digest, copy_len); + int okeylen = okey.GetLength(); + if (okeylen > 32) { + okeylen = 32; + } + uint8_t okeybuf[64]; + FXSYS_memset(okeybuf, 0, sizeof(okeybuf)); + FXSYS_memcpy(okeybuf, okey.c_str(), okeylen); + if (m_Revision == 2) { + CRYPT_ArcFourCryptBlock(okeybuf, okeylen, enckey, key_len); + } else { + for (int i = 19; i >= 0; i--) { + uint8_t tempkey[32]; + FXSYS_memset(tempkey, 0, sizeof(tempkey)); + for (int j = 0; j < m_KeyLen; j++) { + tempkey[j] = enckey[j] ^ i; + } + CRYPT_ArcFourCryptBlock(okeybuf, okeylen, tempkey, key_len); + } + } + int len = 32; + while (len && defpasscode[len - 1] == okeybuf[len - 1]) { + len--; + } + return CFX_ByteString(okeybuf, len); } -FX_BOOL CPDF_StandardSecurityHandler::CheckUserPassword(const uint8_t* password, FX_DWORD pass_size, - FX_BOOL bIgnoreEncryptMeta, uint8_t* key, int32_t key_len) -{ - CalcEncryptKey(m_pEncryptDict, password, pass_size, key, key_len, bIgnoreEncryptMeta, - m_pParser->GetIDArray()); - CFX_ByteString ukey = m_pEncryptDict ? m_pEncryptDict->GetString(FX_BSTRC("U")) : CFX_ByteString(); - if (ukey.GetLength() < 16) { - return FALSE; - } - uint8_t ukeybuf[32]; - if (m_Revision == 2) { - FXSYS_memcpy(ukeybuf, defpasscode, 32); - CRYPT_ArcFourCryptBlock(ukeybuf, 32, key, key_len); - } else { - uint8_t test[32], tmpkey[32]; - FX_DWORD copy_len = sizeof(test); - if (copy_len > (FX_DWORD)ukey.GetLength()) { - copy_len = ukey.GetLength(); - } - FXSYS_memset(test, 0, sizeof(test)); - FXSYS_memset(tmpkey, 0, sizeof(tmpkey)); - FXSYS_memcpy(test, ukey.c_str(), copy_len); - for (int i = 19; i >= 0; i --) { - for (int j = 0; j < key_len; j ++) { - tmpkey[j] = key[j] ^ i; - } - CRYPT_ArcFourCryptBlock(test, 32, tmpkey, key_len); - } - uint8_t md5[100]; - CRYPT_MD5Start(md5); - CRYPT_MD5Update(md5, defpasscode, 32); - CPDF_Array* pIdArray = m_pParser->GetIDArray(); - if (pIdArray) { - CFX_ByteString id = pIdArray->GetString(0); - CRYPT_MD5Update(md5, (uint8_t*)id.c_str(), id.GetLength()); - } - CRYPT_MD5Finish(md5, ukeybuf); - return FXSYS_memcmp(test, ukeybuf, 16) == 0; - } - if (FXSYS_memcmp((void*)ukey.c_str(), ukeybuf, 16) == 0) { - return TRUE; - } - return FALSE; +FX_BOOL CPDF_StandardSecurityHandler::CheckOwnerPassword( + const uint8_t* password, + FX_DWORD pass_size, + uint8_t* key, + int32_t key_len) { + CFX_ByteString user_pass = GetUserPassword(password, pass_size, key_len); + if (CheckUserPassword(user_pass, user_pass.GetLength(), FALSE, key, + key_len)) { + return TRUE; + } + return CheckUserPassword(user_pass, user_pass.GetLength(), TRUE, key, + key_len); } -CFX_ByteString CPDF_StandardSecurityHandler::GetUserPassword(const uint8_t* owner_pass, FX_DWORD pass_size) -{ - return GetUserPassword(owner_pass, pass_size, m_KeyLen); +FX_BOOL CPDF_StandardSecurityHandler::IsMetadataEncrypted() { + return m_pEncryptDict->GetBoolean(FX_BSTRC("EncryptMetadata"), TRUE); } -CFX_ByteString CPDF_StandardSecurityHandler::GetUserPassword(const uint8_t* owner_pass, FX_DWORD pass_size, int32_t key_len) -{ - CFX_ByteString okey = m_pEncryptDict->GetString(FX_BSTRC("O")); +CPDF_SecurityHandler* FPDF_CreateStandardSecurityHandler() { + return new CPDF_StandardSecurityHandler; +} +void CPDF_StandardSecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict, + CPDF_Array* pIdArray, + const uint8_t* user_pass, + FX_DWORD user_size, + const uint8_t* owner_pass, + FX_DWORD owner_size, + FX_BOOL bDefault, + FX_DWORD type) { + int cipher = 0, key_len = 0; + if (!LoadDict(pEncryptDict, type, cipher, key_len)) { + return; + } + if (bDefault && (owner_pass == NULL || owner_size == 0)) { + owner_pass = user_pass; + owner_size = user_size; + } + if (m_Revision >= 5) { + int t = (int)time(NULL); + uint8_t sha[128]; + CRYPT_SHA256Start(sha); + CRYPT_SHA256Update(sha, (uint8_t*)&t, sizeof t); + CRYPT_SHA256Update(sha, m_EncryptKey, 32); + CRYPT_SHA256Update(sha, (uint8_t*)"there", 5); + CRYPT_SHA256Finish(sha, m_EncryptKey); + AES256_SetPassword(pEncryptDict, user_pass, user_size, FALSE, m_EncryptKey); + if (bDefault) { + AES256_SetPassword(pEncryptDict, owner_pass, owner_size, TRUE, + m_EncryptKey); + AES256_SetPerms( + pEncryptDict, m_Permissions, + pEncryptDict->GetBoolean(FX_BSTRC("EncryptMetadata"), TRUE), + m_EncryptKey); + } + return; + } + if (bDefault) { uint8_t passcode[32]; FX_DWORD i; - for (i = 0; i < 32; i ++) { - passcode[i] = i < pass_size ? owner_pass[i] : defpasscode[i - pass_size]; + for (i = 0; i < 32; i++) { + passcode[i] = + i < owner_size ? owner_pass[i] : defpasscode[i - owner_size]; } uint8_t digest[16]; CRYPT_MD5Generate(passcode, 32, digest); if (m_Revision >= 3) { - for (int i = 0; i < 50; i ++) { - CRYPT_MD5Generate(digest, 16, digest); - } + for (int i = 0; i < 50; i++) { + CRYPT_MD5Generate(digest, 16, digest); + } } uint8_t enckey[32]; - FXSYS_memset(enckey, 0, sizeof(enckey)); - FX_DWORD copy_len = key_len; - if (copy_len > sizeof(digest)) { - copy_len = sizeof(digest); - } - FXSYS_memcpy(enckey, digest, copy_len); - int okeylen = okey.GetLength(); - if (okeylen > 32) { - okeylen = 32; - } - uint8_t okeybuf[64]; - FXSYS_memset(okeybuf, 0, sizeof(okeybuf)); - FXSYS_memcpy(okeybuf, okey.c_str(), okeylen); - if (m_Revision == 2) { - CRYPT_ArcFourCryptBlock(okeybuf, okeylen, enckey, key_len); - } else { - for (int i = 19; i >= 0; i --) { - uint8_t tempkey[32]; - FXSYS_memset(tempkey, 0, sizeof(tempkey)); - for (int j = 0; j < m_KeyLen; j ++) { - tempkey[j] = enckey[j] ^ i; - } - CRYPT_ArcFourCryptBlock(okeybuf, okeylen, tempkey, key_len); - } + FXSYS_memcpy(enckey, digest, key_len); + for (i = 0; i < 32; i++) { + passcode[i] = i < user_size ? user_pass[i] : defpasscode[i - user_size]; } - int len = 32; - while (len && defpasscode[len - 1] == okeybuf[len - 1]) { - len --; - } - return CFX_ByteString(okeybuf, len); -} -FX_BOOL CPDF_StandardSecurityHandler::CheckOwnerPassword(const uint8_t* password, FX_DWORD pass_size, - uint8_t* key, int32_t key_len) -{ - CFX_ByteString user_pass = GetUserPassword(password, pass_size, key_len); - if (CheckUserPassword(user_pass, user_pass.GetLength(), FALSE, key, key_len)) { - return TRUE; - } - return CheckUserPassword(user_pass, user_pass.GetLength(), TRUE, key, key_len); -} -FX_BOOL CPDF_StandardSecurityHandler::IsMetadataEncrypted() -{ - return m_pEncryptDict->GetBoolean(FX_BSTRC("EncryptMetadata"), TRUE); -} -CPDF_SecurityHandler* FPDF_CreateStandardSecurityHandler() -{ - return new CPDF_StandardSecurityHandler; -} -void CPDF_StandardSecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict, CPDF_Array* pIdArray, - const uint8_t* user_pass, FX_DWORD user_size, - const uint8_t* owner_pass, FX_DWORD owner_size, FX_BOOL bDefault, FX_DWORD type) -{ - int cipher = 0, key_len = 0; - if (!LoadDict(pEncryptDict, type, cipher, key_len)) { - return; - } - if (bDefault && (owner_pass == NULL || owner_size == 0)) { - owner_pass = user_pass; - owner_size = user_size; - } - if (m_Revision >= 5) { - int t = (int)time(NULL); - uint8_t sha[128]; - CRYPT_SHA256Start(sha); - CRYPT_SHA256Update(sha, (uint8_t*)&t, sizeof t); - CRYPT_SHA256Update(sha, m_EncryptKey, 32); - CRYPT_SHA256Update(sha, (uint8_t*)"there", 5); - CRYPT_SHA256Finish(sha, m_EncryptKey); - AES256_SetPassword(pEncryptDict, user_pass, user_size, FALSE, m_EncryptKey); - if (bDefault) { - AES256_SetPassword(pEncryptDict, owner_pass, owner_size, TRUE, m_EncryptKey); - AES256_SetPerms(pEncryptDict, m_Permissions, pEncryptDict->GetBoolean(FX_BSTRC("EncryptMetadata"), TRUE), m_EncryptKey); - } - return; - } - if (bDefault) { - uint8_t passcode[32]; - FX_DWORD i; - for (i = 0; i < 32; i ++) { - passcode[i] = i < owner_size ? owner_pass[i] : defpasscode[i - owner_size]; - } - uint8_t digest[16]; - CRYPT_MD5Generate(passcode, 32, digest); - if (m_Revision >= 3) { - for (int i = 0; i < 50; i ++) { - CRYPT_MD5Generate(digest, 16, digest); - } - } - uint8_t enckey[32]; - FXSYS_memcpy(enckey, digest, key_len); - for (i = 0; i < 32; i ++) { - passcode[i] = i < user_size ? user_pass[i] : defpasscode[i - user_size]; - } - CRYPT_ArcFourCryptBlock(passcode, 32, enckey, key_len); - uint8_t tempkey[32]; - if (m_Revision >= 3) { - for (i = 1; i <= 19; i ++) { - for (int j = 0; j < key_len; j ++) { - tempkey[j] = enckey[j] ^ (uint8_t)i; - } - CRYPT_ArcFourCryptBlock(passcode, 32, tempkey, key_len); - } - } - pEncryptDict->SetAtString(FX_BSTRC("O"), CFX_ByteString(passcode, 32)); - } - CalcEncryptKey(m_pEncryptDict, (uint8_t*)user_pass, user_size, m_EncryptKey, key_len, FALSE, pIdArray); - if (m_Revision < 3) { - uint8_t tempbuf[32]; - FXSYS_memcpy(tempbuf, defpasscode, 32); - CRYPT_ArcFourCryptBlock(tempbuf, 32, m_EncryptKey, key_len); - pEncryptDict->SetAtString(FX_BSTRC("U"), CFX_ByteString(tempbuf, 32)); - } else { - uint8_t md5[100]; - CRYPT_MD5Start(md5); - CRYPT_MD5Update(md5, defpasscode, 32); - if (pIdArray) { - CFX_ByteString id = pIdArray->GetString(0); - CRYPT_MD5Update(md5, (uint8_t*)id.c_str(), id.GetLength()); - } - uint8_t digest[32]; - CRYPT_MD5Finish(md5, digest); - CRYPT_ArcFourCryptBlock(digest, 16, m_EncryptKey, key_len); - uint8_t tempkey[32]; - for (int i = 1; i <= 19; i ++) { - for (int j = 0; j < key_len; j ++) { - tempkey[j] = m_EncryptKey[j] ^ (uint8_t)i; - } - CRYPT_ArcFourCryptBlock(digest, 16, tempkey, key_len); + CRYPT_ArcFourCryptBlock(passcode, 32, enckey, key_len); + uint8_t tempkey[32]; + if (m_Revision >= 3) { + for (i = 1; i <= 19; i++) { + for (int j = 0; j < key_len; j++) { + tempkey[j] = enckey[j] ^ (uint8_t)i; } - CRYPT_MD5Generate(digest, 16, digest + 16); - pEncryptDict->SetAtString(FX_BSTRC("U"), CFX_ByteString(digest, 32)); + CRYPT_ArcFourCryptBlock(passcode, 32, tempkey, key_len); + } + } + pEncryptDict->SetAtString(FX_BSTRC("O"), CFX_ByteString(passcode, 32)); + } + CalcEncryptKey(m_pEncryptDict, (uint8_t*)user_pass, user_size, m_EncryptKey, + key_len, FALSE, pIdArray); + if (m_Revision < 3) { + uint8_t tempbuf[32]; + FXSYS_memcpy(tempbuf, defpasscode, 32); + CRYPT_ArcFourCryptBlock(tempbuf, 32, m_EncryptKey, key_len); + pEncryptDict->SetAtString(FX_BSTRC("U"), CFX_ByteString(tempbuf, 32)); + } else { + uint8_t md5[100]; + CRYPT_MD5Start(md5); + CRYPT_MD5Update(md5, defpasscode, 32); + if (pIdArray) { + CFX_ByteString id = pIdArray->GetString(0); + CRYPT_MD5Update(md5, (uint8_t*)id.c_str(), id.GetLength()); } + uint8_t digest[32]; + CRYPT_MD5Finish(md5, digest); + CRYPT_ArcFourCryptBlock(digest, 16, m_EncryptKey, key_len); + uint8_t tempkey[32]; + for (int i = 1; i <= 19; i++) { + for (int j = 0; j < key_len; j++) { + tempkey[j] = m_EncryptKey[j] ^ (uint8_t)i; + } + CRYPT_ArcFourCryptBlock(digest, 16, tempkey, key_len); + } + CRYPT_MD5Generate(digest, 16, digest + 16); + pEncryptDict->SetAtString(FX_BSTRC("U"), CFX_ByteString(digest, 32)); + } } -void CPDF_StandardSecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict, CPDF_Array* pIdArray, - const uint8_t* user_pass, FX_DWORD user_size, - const uint8_t* owner_pass, FX_DWORD owner_size, FX_DWORD type) -{ - OnCreate(pEncryptDict, pIdArray, user_pass, user_size, owner_pass, owner_size, TRUE, type); +void CPDF_StandardSecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict, + CPDF_Array* pIdArray, + const uint8_t* user_pass, + FX_DWORD user_size, + const uint8_t* owner_pass, + FX_DWORD owner_size, + FX_DWORD type) { + OnCreate(pEncryptDict, pIdArray, user_pass, user_size, owner_pass, owner_size, + TRUE, type); } -void CPDF_StandardSecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict, CPDF_Array* pIdArray, const uint8_t* user_pass, FX_DWORD user_size, FX_DWORD type) -{ - OnCreate(pEncryptDict, pIdArray, user_pass, user_size, NULL, 0, FALSE, type); +void CPDF_StandardSecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict, + CPDF_Array* pIdArray, + const uint8_t* user_pass, + FX_DWORD user_size, + FX_DWORD type) { + OnCreate(pEncryptDict, pIdArray, user_pass, user_size, NULL, 0, FALSE, type); } -void CPDF_StandardSecurityHandler::AES256_SetPassword(CPDF_Dictionary* pEncryptDict, const uint8_t* password, FX_DWORD size, FX_BOOL bOwner, const uint8_t* key) -{ - uint8_t sha[128]; - CRYPT_SHA1Start(sha); - CRYPT_SHA1Update(sha, key, 32); - CRYPT_SHA1Update(sha, (uint8_t*)"hello", 5); - uint8_t digest[20]; - CRYPT_SHA1Finish(sha, digest); - CFX_ByteString ukey = pEncryptDict->GetString(FX_BSTRC("U")); - uint8_t digest1[48]; - if (m_Revision >= 6) { - Revision6_Hash(password, size, digest, (bOwner ? (const uint8_t*)ukey : NULL), digest1); - } else { - CRYPT_SHA256Start(sha); - CRYPT_SHA256Update(sha, password, size); - CRYPT_SHA256Update(sha, digest, 8); - if (bOwner) { - CRYPT_SHA256Update(sha, ukey, ukey.GetLength()); - } - CRYPT_SHA256Finish(sha, digest1); - } - FXSYS_memcpy(digest1 + 32, digest, 16); - pEncryptDict->SetAtString(bOwner ? FX_BSTRC("O") : FX_BSTRC("U"), CFX_ByteString(digest1, 48)); - if (m_Revision >= 6) { - Revision6_Hash(password, size, digest + 8, (bOwner ? (const uint8_t*)ukey : NULL), digest1); - } else { - CRYPT_SHA256Start(sha); - CRYPT_SHA256Update(sha, password, size); - CRYPT_SHA256Update(sha, digest + 8, 8); - if (bOwner) { - CRYPT_SHA256Update(sha, ukey, ukey.GetLength()); - } - CRYPT_SHA256Finish(sha, digest1); - } - uint8_t* aes = FX_Alloc(uint8_t, 2048); - CRYPT_AESSetKey(aes, 16, digest1, 32, TRUE); - uint8_t iv[16]; - FXSYS_memset(iv, 0, 16); - CRYPT_AESSetIV(aes, iv); - CRYPT_AESEncrypt(aes, digest1, key, 32); - FX_Free(aes); - pEncryptDict->SetAtString(bOwner ? FX_BSTRC("OE") : FX_BSTRC("UE"), CFX_ByteString(digest1, 32)); -} -void CPDF_StandardSecurityHandler::AES256_SetPerms(CPDF_Dictionary* pEncryptDict, FX_DWORD permissions, - FX_BOOL bEncryptMetadata, const uint8_t* key) -{ - uint8_t buf[16]; - buf[0] = (uint8_t)permissions; - buf[1] = (uint8_t)(permissions >> 8); - buf[2] = (uint8_t)(permissions >> 16); - buf[3] = (uint8_t)(permissions >> 24); - buf[4] = 0xff; - buf[5] = 0xff; - buf[6] = 0xff; - buf[7] = 0xff; - buf[8] = bEncryptMetadata ? 'T' : 'F'; - buf[9] = 'a'; - buf[10] = 'd'; - buf[11] = 'b'; - uint8_t* aes = FX_Alloc(uint8_t, 2048); - CRYPT_AESSetKey(aes, 16, key, 32, TRUE); - uint8_t iv[16], buf1[16]; - FXSYS_memset(iv, 0, 16); - CRYPT_AESSetIV(aes, iv); - CRYPT_AESEncrypt(aes, buf1, buf, 16); - FX_Free(aes); - pEncryptDict->SetAtString(FX_BSTRC("Perms"), CFX_ByteString(buf1, 16)); -} -void CPDF_StandardCryptoHandler::CryptBlock(FX_BOOL bEncrypt, FX_DWORD objnum, FX_DWORD gennum, const uint8_t* src_buf, FX_DWORD src_size, - uint8_t* dest_buf, FX_DWORD& dest_size) -{ - if (m_Cipher == FXCIPHER_NONE) { - FXSYS_memcpy(dest_buf, src_buf, src_size); - return; - } - uint8_t realkey[16]; - int realkeylen = 16; - if (m_Cipher != FXCIPHER_AES || m_KeyLen != 32) { - uint8_t key1[32]; - FXSYS_memcpy(key1, m_EncryptKey, m_KeyLen); - key1[m_KeyLen + 0] = (uint8_t)objnum; - key1[m_KeyLen + 1] = (uint8_t)(objnum >> 8); - key1[m_KeyLen + 2] = (uint8_t)(objnum >> 16); - key1[m_KeyLen + 3] = (uint8_t)gennum; - key1[m_KeyLen + 4] = (uint8_t)(gennum >> 8); - FXSYS_memcpy(key1 + m_KeyLen, &objnum, 3); - FXSYS_memcpy(key1 + m_KeyLen + 3, &gennum, 2); - if (m_Cipher == FXCIPHER_AES) { - FXSYS_memcpy(key1 + m_KeyLen + 5, "sAlT", 4); - } - CRYPT_MD5Generate(key1, m_Cipher == FXCIPHER_AES ? m_KeyLen + 9 : m_KeyLen + 5, realkey); - realkeylen = m_KeyLen + 5; - if (realkeylen > 16) { - realkeylen = 16; - } - } - if (m_Cipher == FXCIPHER_AES) { - CRYPT_AESSetKey(m_pAESContext, 16, m_KeyLen == 32 ? m_EncryptKey : realkey, m_KeyLen, bEncrypt); - if (bEncrypt) { - uint8_t iv[16]; - for (int i = 0; i < 16; i ++) { - iv[i] = (uint8_t)rand(); - } - CRYPT_AESSetIV(m_pAESContext, iv); - FXSYS_memcpy(dest_buf, iv, 16); - int nblocks = src_size / 16; - CRYPT_AESEncrypt(m_pAESContext, dest_buf + 16, src_buf, nblocks * 16); - uint8_t padding[16]; - FXSYS_memcpy(padding, src_buf + nblocks * 16, src_size % 16); - FXSYS_memset(padding + src_size % 16, 16 - src_size % 16, 16 - src_size % 16); - CRYPT_AESEncrypt(m_pAESContext, dest_buf + nblocks * 16 + 16, padding, 16); - dest_size = 32 + nblocks * 16; - } else { - CRYPT_AESSetIV(m_pAESContext, src_buf); - CRYPT_AESDecrypt(m_pAESContext, dest_buf, src_buf + 16, src_size - 16); - dest_size = src_size - 16; - dest_size -= dest_buf[dest_size - 1]; - } - } else { - ASSERT(dest_size == src_size); - if (dest_buf != src_buf) { - FXSYS_memcpy(dest_buf, src_buf, src_size); - } - CRYPT_ArcFourCryptBlock(dest_buf, dest_size, realkey, realkeylen); - } +void CPDF_StandardSecurityHandler::AES256_SetPassword( + CPDF_Dictionary* pEncryptDict, + const uint8_t* password, + FX_DWORD size, + FX_BOOL bOwner, + const uint8_t* key) { + uint8_t sha[128]; + CRYPT_SHA1Start(sha); + CRYPT_SHA1Update(sha, key, 32); + CRYPT_SHA1Update(sha, (uint8_t*)"hello", 5); + uint8_t digest[20]; + CRYPT_SHA1Finish(sha, digest); + CFX_ByteString ukey = pEncryptDict->GetString(FX_BSTRC("U")); + uint8_t digest1[48]; + if (m_Revision >= 6) { + Revision6_Hash(password, size, digest, + (bOwner ? (const uint8_t*)ukey : NULL), digest1); + } else { + CRYPT_SHA256Start(sha); + CRYPT_SHA256Update(sha, password, size); + CRYPT_SHA256Update(sha, digest, 8); + if (bOwner) { + CRYPT_SHA256Update(sha, ukey, ukey.GetLength()); + } + CRYPT_SHA256Finish(sha, digest1); + } + FXSYS_memcpy(digest1 + 32, digest, 16); + pEncryptDict->SetAtString(bOwner ? FX_BSTRC("O") : FX_BSTRC("U"), + CFX_ByteString(digest1, 48)); + if (m_Revision >= 6) { + Revision6_Hash(password, size, digest + 8, + (bOwner ? (const uint8_t*)ukey : NULL), digest1); + } else { + CRYPT_SHA256Start(sha); + CRYPT_SHA256Update(sha, password, size); + CRYPT_SHA256Update(sha, digest + 8, 8); + if (bOwner) { + CRYPT_SHA256Update(sha, ukey, ukey.GetLength()); + } + CRYPT_SHA256Finish(sha, digest1); + } + uint8_t* aes = FX_Alloc(uint8_t, 2048); + CRYPT_AESSetKey(aes, 16, digest1, 32, TRUE); + uint8_t iv[16]; + FXSYS_memset(iv, 0, 16); + CRYPT_AESSetIV(aes, iv); + CRYPT_AESEncrypt(aes, digest1, key, 32); + FX_Free(aes); + pEncryptDict->SetAtString(bOwner ? FX_BSTRC("OE") : FX_BSTRC("UE"), + CFX_ByteString(digest1, 32)); } -typedef struct _AESCryptContext { - uint8_t m_Context[2048]; - FX_BOOL m_bIV; - uint8_t m_Block[16]; - FX_DWORD m_BlockOffset; -} AESCryptContext; -void* CPDF_StandardCryptoHandler::CryptStart(FX_DWORD objnum, FX_DWORD gennum, FX_BOOL bEncrypt) -{ - if (m_Cipher == FXCIPHER_NONE) { - return this; - } - if (m_Cipher == FXCIPHER_AES && m_KeyLen == 32) { - AESCryptContext* pContext = FX_Alloc(AESCryptContext, 1); - pContext->m_bIV = TRUE; - pContext->m_BlockOffset = 0; - CRYPT_AESSetKey(pContext->m_Context, 16, m_EncryptKey, 32, bEncrypt); - if (bEncrypt) { - for (int i = 0; i < 16; i ++) { - pContext->m_Block[i] = (uint8_t)rand(); - } - CRYPT_AESSetIV(pContext->m_Context, pContext->m_Block); - } - return pContext; - } - uint8_t key1[48]; +void CPDF_StandardSecurityHandler::AES256_SetPerms( + CPDF_Dictionary* pEncryptDict, + FX_DWORD permissions, + FX_BOOL bEncryptMetadata, + const uint8_t* key) { + uint8_t buf[16]; + buf[0] = (uint8_t)permissions; + buf[1] = (uint8_t)(permissions >> 8); + buf[2] = (uint8_t)(permissions >> 16); + buf[3] = (uint8_t)(permissions >> 24); + buf[4] = 0xff; + buf[5] = 0xff; + buf[6] = 0xff; + buf[7] = 0xff; + buf[8] = bEncryptMetadata ? 'T' : 'F'; + buf[9] = 'a'; + buf[10] = 'd'; + buf[11] = 'b'; + uint8_t* aes = FX_Alloc(uint8_t, 2048); + CRYPT_AESSetKey(aes, 16, key, 32, TRUE); + uint8_t iv[16], buf1[16]; + FXSYS_memset(iv, 0, 16); + CRYPT_AESSetIV(aes, iv); + CRYPT_AESEncrypt(aes, buf1, buf, 16); + FX_Free(aes); + pEncryptDict->SetAtString(FX_BSTRC("Perms"), CFX_ByteString(buf1, 16)); +} +void CPDF_StandardCryptoHandler::CryptBlock(FX_BOOL bEncrypt, + FX_DWORD objnum, + FX_DWORD gennum, + const uint8_t* src_buf, + FX_DWORD src_size, + uint8_t* dest_buf, + FX_DWORD& dest_size) { + if (m_Cipher == FXCIPHER_NONE) { + FXSYS_memcpy(dest_buf, src_buf, src_size); + return; + } + uint8_t realkey[16]; + int realkeylen = 16; + if (m_Cipher != FXCIPHER_AES || m_KeyLen != 32) { + uint8_t key1[32]; FXSYS_memcpy(key1, m_EncryptKey, m_KeyLen); + key1[m_KeyLen + 0] = (uint8_t)objnum; + key1[m_KeyLen + 1] = (uint8_t)(objnum >> 8); + key1[m_KeyLen + 2] = (uint8_t)(objnum >> 16); + key1[m_KeyLen + 3] = (uint8_t)gennum; + key1[m_KeyLen + 4] = (uint8_t)(gennum >> 8); FXSYS_memcpy(key1 + m_KeyLen, &objnum, 3); FXSYS_memcpy(key1 + m_KeyLen + 3, &gennum, 2); if (m_Cipher == FXCIPHER_AES) { - FXSYS_memcpy(key1 + m_KeyLen + 5, "sAlT", 4); + FXSYS_memcpy(key1 + m_KeyLen + 5, "sAlT", 4); } - uint8_t realkey[16]; - CRYPT_MD5Generate(key1, m_Cipher == FXCIPHER_AES ? m_KeyLen + 9 : m_KeyLen + 5, realkey); - int realkeylen = m_KeyLen + 5; + CRYPT_MD5Generate( + key1, m_Cipher == FXCIPHER_AES ? m_KeyLen + 9 : m_KeyLen + 5, realkey); + realkeylen = m_KeyLen + 5; if (realkeylen > 16) { - realkeylen = 16; + realkeylen = 16; } - if (m_Cipher == FXCIPHER_AES) { - AESCryptContext* pContext = FX_Alloc(AESCryptContext, 1); - pContext->m_bIV = TRUE; - pContext->m_BlockOffset = 0; - CRYPT_AESSetKey(pContext->m_Context, 16, realkey, 16, bEncrypt); - if (bEncrypt) { - for (int i = 0; i < 16; i ++) { - pContext->m_Block[i] = (uint8_t)rand(); - } - CRYPT_AESSetIV(pContext->m_Context, pContext->m_Block); - } - return pContext; - } - void* pContext = FX_Alloc(uint8_t, 1040); - CRYPT_ArcFourSetup(pContext, realkey, realkeylen); - return pContext; + } + if (m_Cipher == FXCIPHER_AES) { + CRYPT_AESSetKey(m_pAESContext, 16, m_KeyLen == 32 ? m_EncryptKey : realkey, + m_KeyLen, bEncrypt); + if (bEncrypt) { + uint8_t iv[16]; + for (int i = 0; i < 16; i++) { + iv[i] = (uint8_t)rand(); + } + CRYPT_AESSetIV(m_pAESContext, iv); + FXSYS_memcpy(dest_buf, iv, 16); + int nblocks = src_size / 16; + CRYPT_AESEncrypt(m_pAESContext, dest_buf + 16, src_buf, nblocks * 16); + uint8_t padding[16]; + FXSYS_memcpy(padding, src_buf + nblocks * 16, src_size % 16); + FXSYS_memset(padding + src_size % 16, 16 - src_size % 16, + 16 - src_size % 16); + CRYPT_AESEncrypt(m_pAESContext, dest_buf + nblocks * 16 + 16, padding, + 16); + dest_size = 32 + nblocks * 16; + } else { + CRYPT_AESSetIV(m_pAESContext, src_buf); + CRYPT_AESDecrypt(m_pAESContext, dest_buf, src_buf + 16, src_size - 16); + dest_size = src_size - 16; + dest_size -= dest_buf[dest_size - 1]; + } + } else { + ASSERT(dest_size == src_size); + if (dest_buf != src_buf) { + FXSYS_memcpy(dest_buf, src_buf, src_size); + } + CRYPT_ArcFourCryptBlock(dest_buf, dest_size, realkey, realkeylen); + } } -FX_BOOL CPDF_StandardCryptoHandler::CryptStream(void* context, const uint8_t* src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf, FX_BOOL bEncrypt) -{ - if (!context) { - return FALSE; - } - if (m_Cipher == FXCIPHER_NONE) { - dest_buf.AppendBlock(src_buf, src_size); - return TRUE; - } - if (m_Cipher == FXCIPHER_RC4) { - int old_size = dest_buf.GetSize(); - dest_buf.AppendBlock(src_buf, src_size); - CRYPT_ArcFourCrypt(context, dest_buf.GetBuffer() + old_size, src_size); - return TRUE; - } - AESCryptContext* pContext = (AESCryptContext*)context; - if (pContext->m_bIV && bEncrypt) { - dest_buf.AppendBlock(pContext->m_Block, 16); - pContext->m_bIV = FALSE; +typedef struct _AESCryptContext { + uint8_t m_Context[2048]; + FX_BOOL m_bIV; + uint8_t m_Block[16]; + FX_DWORD m_BlockOffset; +} AESCryptContext; +void* CPDF_StandardCryptoHandler::CryptStart(FX_DWORD objnum, + FX_DWORD gennum, + FX_BOOL bEncrypt) { + if (m_Cipher == FXCIPHER_NONE) { + return this; + } + if (m_Cipher == FXCIPHER_AES && m_KeyLen == 32) { + AESCryptContext* pContext = FX_Alloc(AESCryptContext, 1); + pContext->m_bIV = TRUE; + pContext->m_BlockOffset = 0; + CRYPT_AESSetKey(pContext->m_Context, 16, m_EncryptKey, 32, bEncrypt); + if (bEncrypt) { + for (int i = 0; i < 16; i++) { + pContext->m_Block[i] = (uint8_t)rand(); + } + CRYPT_AESSetIV(pContext->m_Context, pContext->m_Block); } - FX_DWORD src_off = 0; - FX_DWORD src_left = src_size; - while (1) { - FX_DWORD copy_size = 16 - pContext->m_BlockOffset; - if (copy_size > src_left) { - copy_size = src_left; - } - FXSYS_memcpy(pContext->m_Block + pContext->m_BlockOffset, src_buf + src_off, copy_size); - src_off += copy_size; - src_left -= copy_size; - pContext->m_BlockOffset += copy_size; - if (pContext->m_BlockOffset == 16) { - if (!bEncrypt && pContext->m_bIV) { - CRYPT_AESSetIV(pContext->m_Context, pContext->m_Block); - pContext->m_bIV = FALSE; - pContext->m_BlockOffset = 0; - } else if (src_off < src_size) { - uint8_t block_buf[16]; - if (bEncrypt) { - CRYPT_AESEncrypt(pContext->m_Context, block_buf, pContext->m_Block, 16); - } else { - CRYPT_AESDecrypt(pContext->m_Context, block_buf, pContext->m_Block, 16); - } - dest_buf.AppendBlock(block_buf, 16); - pContext->m_BlockOffset = 0; - } - } - if (!src_left) { - break; - } + return pContext; + } + uint8_t key1[48]; + FXSYS_memcpy(key1, m_EncryptKey, m_KeyLen); + FXSYS_memcpy(key1 + m_KeyLen, &objnum, 3); + FXSYS_memcpy(key1 + m_KeyLen + 3, &gennum, 2); + if (m_Cipher == FXCIPHER_AES) { + FXSYS_memcpy(key1 + m_KeyLen + 5, "sAlT", 4); + } + uint8_t realkey[16]; + CRYPT_MD5Generate( + key1, m_Cipher == FXCIPHER_AES ? m_KeyLen + 9 : m_KeyLen + 5, realkey); + int realkeylen = m_KeyLen + 5; + if (realkeylen > 16) { + realkeylen = 16; + } + if (m_Cipher == FXCIPHER_AES) { + AESCryptContext* pContext = FX_Alloc(AESCryptContext, 1); + pContext->m_bIV = TRUE; + pContext->m_BlockOffset = 0; + CRYPT_AESSetKey(pContext->m_Context, 16, realkey, 16, bEncrypt); + if (bEncrypt) { + for (int i = 0; i < 16; i++) { + pContext->m_Block[i] = (uint8_t)rand(); + } + CRYPT_AESSetIV(pContext->m_Context, pContext->m_Block); } - return TRUE; + return pContext; + } + void* pContext = FX_Alloc(uint8_t, 1040); + CRYPT_ArcFourSetup(pContext, realkey, realkeylen); + return pContext; } -FX_BOOL CPDF_StandardCryptoHandler::CryptFinish(void* context, CFX_BinaryBuf& dest_buf, FX_BOOL bEncrypt) -{ - if (!context) { - return FALSE; - } - if (m_Cipher == FXCIPHER_NONE) { - return TRUE; - } - if (m_Cipher == FXCIPHER_RC4) { - FX_Free(context); - return TRUE; - } - AESCryptContext* pContext = (AESCryptContext*)context; - if (bEncrypt) { +FX_BOOL CPDF_StandardCryptoHandler::CryptStream(void* context, + const uint8_t* src_buf, + FX_DWORD src_size, + CFX_BinaryBuf& dest_buf, + FX_BOOL bEncrypt) { + if (!context) { + return FALSE; + } + if (m_Cipher == FXCIPHER_NONE) { + dest_buf.AppendBlock(src_buf, src_size); + return TRUE; + } + if (m_Cipher == FXCIPHER_RC4) { + int old_size = dest_buf.GetSize(); + dest_buf.AppendBlock(src_buf, src_size); + CRYPT_ArcFourCrypt(context, dest_buf.GetBuffer() + old_size, src_size); + return TRUE; + } + AESCryptContext* pContext = (AESCryptContext*)context; + if (pContext->m_bIV && bEncrypt) { + dest_buf.AppendBlock(pContext->m_Block, 16); + pContext->m_bIV = FALSE; + } + FX_DWORD src_off = 0; + FX_DWORD src_left = src_size; + while (1) { + FX_DWORD copy_size = 16 - pContext->m_BlockOffset; + if (copy_size > src_left) { + copy_size = src_left; + } + FXSYS_memcpy(pContext->m_Block + pContext->m_BlockOffset, src_buf + src_off, + copy_size); + src_off += copy_size; + src_left -= copy_size; + pContext->m_BlockOffset += copy_size; + if (pContext->m_BlockOffset == 16) { + if (!bEncrypt && pContext->m_bIV) { + CRYPT_AESSetIV(pContext->m_Context, pContext->m_Block); + pContext->m_bIV = FALSE; + pContext->m_BlockOffset = 0; + } else if (src_off < src_size) { uint8_t block_buf[16]; - if (pContext->m_BlockOffset == 16) { - CRYPT_AESEncrypt(pContext->m_Context, block_buf, pContext->m_Block, 16); - dest_buf.AppendBlock(block_buf, 16); - pContext->m_BlockOffset = 0; + if (bEncrypt) { + CRYPT_AESEncrypt(pContext->m_Context, block_buf, pContext->m_Block, + 16); + } else { + CRYPT_AESDecrypt(pContext->m_Context, block_buf, pContext->m_Block, + 16); } - FXSYS_memset(pContext->m_Block + pContext->m_BlockOffset, (uint8_t)(16 - pContext->m_BlockOffset), 16 - pContext->m_BlockOffset); - CRYPT_AESEncrypt(pContext->m_Context, block_buf, pContext->m_Block, 16); dest_buf.AppendBlock(block_buf, 16); - } else if (pContext->m_BlockOffset == 16) { - uint8_t block_buf[16]; - CRYPT_AESDecrypt(pContext->m_Context, block_buf, pContext->m_Block, 16); - if (block_buf[15] <= 16) { - dest_buf.AppendBlock(block_buf, 16 - block_buf[15]); - } + pContext->m_BlockOffset = 0; + } } - FX_Free(pContext); + if (!src_left) { + break; + } + } + return TRUE; +} +FX_BOOL CPDF_StandardCryptoHandler::CryptFinish(void* context, + CFX_BinaryBuf& dest_buf, + FX_BOOL bEncrypt) { + if (!context) { + return FALSE; + } + if (m_Cipher == FXCIPHER_NONE) { + return TRUE; + } + if (m_Cipher == FXCIPHER_RC4) { + FX_Free(context); return TRUE; + } + AESCryptContext* pContext = (AESCryptContext*)context; + if (bEncrypt) { + uint8_t block_buf[16]; + if (pContext->m_BlockOffset == 16) { + CRYPT_AESEncrypt(pContext->m_Context, block_buf, pContext->m_Block, 16); + dest_buf.AppendBlock(block_buf, 16); + pContext->m_BlockOffset = 0; + } + FXSYS_memset(pContext->m_Block + pContext->m_BlockOffset, + (uint8_t)(16 - pContext->m_BlockOffset), + 16 - pContext->m_BlockOffset); + CRYPT_AESEncrypt(pContext->m_Context, block_buf, pContext->m_Block, 16); + dest_buf.AppendBlock(block_buf, 16); + } else if (pContext->m_BlockOffset == 16) { + uint8_t block_buf[16]; + CRYPT_AESDecrypt(pContext->m_Context, block_buf, pContext->m_Block, 16); + if (block_buf[15] <= 16) { + dest_buf.AppendBlock(block_buf, 16 - block_buf[15]); + } + } + FX_Free(pContext); + return TRUE; } -void* CPDF_StandardCryptoHandler::DecryptStart(FX_DWORD objnum, FX_DWORD gennum) -{ - return CryptStart(objnum, gennum, FALSE); +void* CPDF_StandardCryptoHandler::DecryptStart(FX_DWORD objnum, + FX_DWORD gennum) { + return CryptStart(objnum, gennum, FALSE); } -FX_DWORD CPDF_StandardCryptoHandler::DecryptGetSize(FX_DWORD src_size) -{ - return m_Cipher == FXCIPHER_AES ? src_size - 16 : src_size; +FX_DWORD CPDF_StandardCryptoHandler::DecryptGetSize(FX_DWORD src_size) { + return m_Cipher == FXCIPHER_AES ? src_size - 16 : src_size; } -FX_BOOL CPDF_StandardCryptoHandler::Init(CPDF_Dictionary* pEncryptDict, CPDF_SecurityHandler* pSecurityHandler) -{ - const uint8_t* key; - if (!pSecurityHandler->GetCryptInfo(m_Cipher, key, m_KeyLen)) { - return FALSE; - } - if (m_KeyLen > 32 || m_KeyLen < 0) { +FX_BOOL CPDF_StandardCryptoHandler::Init( + CPDF_Dictionary* pEncryptDict, + CPDF_SecurityHandler* pSecurityHandler) { + const uint8_t* key; + if (!pSecurityHandler->GetCryptInfo(m_Cipher, key, m_KeyLen)) { + return FALSE; + } + if (m_KeyLen > 32 || m_KeyLen < 0) { + return FALSE; + } + if (m_Cipher != FXCIPHER_NONE) { + FXSYS_memcpy(m_EncryptKey, key, m_KeyLen); + } + if (m_Cipher == FXCIPHER_AES) { + m_pAESContext = FX_Alloc(uint8_t, 2048); + } + return TRUE; +} +FX_BOOL CPDF_StandardCryptoHandler::Init(int cipher, + const uint8_t* key, + int keylen) { + if (cipher == FXCIPHER_AES) { + switch (keylen) { + case 16: + case 24: + case 32: + break; + default: return FALSE; } - if (m_Cipher != FXCIPHER_NONE) { - FXSYS_memcpy(m_EncryptKey, key, m_KeyLen); - } - if (m_Cipher == FXCIPHER_AES) { - m_pAESContext = FX_Alloc(uint8_t, 2048); - } - return TRUE; + } else if (cipher == FXCIPHER_AES2) { + if (keylen != 32) { + return FALSE; + } + } else if (cipher == FXCIPHER_RC4) { + if (keylen < 5 || keylen > 16) { + return FALSE; + } + } else { + if (keylen > 32) { + keylen = 32; + } + } + m_Cipher = cipher; + m_KeyLen = keylen; + FXSYS_memcpy(m_EncryptKey, key, keylen); + if (m_Cipher == FXCIPHER_AES) { + m_pAESContext = FX_Alloc(uint8_t, 2048); + } + return TRUE; } -FX_BOOL CPDF_StandardCryptoHandler::Init(int cipher, const uint8_t* key, int keylen) -{ - if (cipher == FXCIPHER_AES) { - switch(keylen) { - case 16: - case 24: - case 32: - break; - default: - return FALSE; - } - } else if (cipher == FXCIPHER_AES2) { - if (keylen != 32) { - return FALSE; - } - } else if (cipher == FXCIPHER_RC4) { - if (keylen < 5 || keylen > 16) { - return FALSE; - } - } else { - if (keylen > 32) { - keylen = 32; - } - } - m_Cipher = cipher; - m_KeyLen = keylen; - FXSYS_memcpy(m_EncryptKey, key, keylen); - if (m_Cipher == FXCIPHER_AES) { - m_pAESContext = FX_Alloc(uint8_t, 2048); - } - return TRUE; +FX_BOOL CPDF_StandardCryptoHandler::DecryptStream(void* context, + const uint8_t* src_buf, + FX_DWORD src_size, + CFX_BinaryBuf& dest_buf) { + return CryptStream(context, src_buf, src_size, dest_buf, FALSE); } -FX_BOOL CPDF_StandardCryptoHandler::DecryptStream(void* context, const uint8_t* src_buf, FX_DWORD src_size, - CFX_BinaryBuf& dest_buf) -{ - return CryptStream(context, src_buf, src_size, dest_buf, FALSE); +FX_BOOL CPDF_StandardCryptoHandler::DecryptFinish(void* context, + CFX_BinaryBuf& dest_buf) { + return CryptFinish(context, dest_buf, FALSE); } -FX_BOOL CPDF_StandardCryptoHandler::DecryptFinish(void* context, CFX_BinaryBuf& dest_buf) -{ - return CryptFinish(context, dest_buf, FALSE); +FX_DWORD CPDF_StandardCryptoHandler::EncryptGetSize(FX_DWORD objnum, + FX_DWORD version, + const uint8_t* src_buf, + FX_DWORD src_size) { + if (m_Cipher == FXCIPHER_AES) { + return src_size + 32; + } + return src_size; } -FX_DWORD CPDF_StandardCryptoHandler::EncryptGetSize(FX_DWORD objnum, FX_DWORD version, const uint8_t* src_buf, FX_DWORD src_size) -{ - if (m_Cipher == FXCIPHER_AES) { - return src_size + 32; - } - return src_size; +FX_BOOL CPDF_StandardCryptoHandler::EncryptContent(FX_DWORD objnum, + FX_DWORD gennum, + const uint8_t* src_buf, + FX_DWORD src_size, + uint8_t* dest_buf, + FX_DWORD& dest_size) { + CryptBlock(TRUE, objnum, gennum, src_buf, src_size, dest_buf, dest_size); + return TRUE; } -FX_BOOL CPDF_StandardCryptoHandler::EncryptContent(FX_DWORD objnum, FX_DWORD gennum, const uint8_t* src_buf, FX_DWORD src_size, - uint8_t* dest_buf, FX_DWORD& dest_size) -{ - CryptBlock(TRUE, objnum, gennum, src_buf, src_size, dest_buf, dest_size); - return TRUE; +void CPDF_CryptoHandler::Decrypt(FX_DWORD objnum, + FX_DWORD gennum, + CFX_ByteString& str) { + CFX_BinaryBuf dest_buf; + void* context = DecryptStart(objnum, gennum); + DecryptStream(context, (const uint8_t*)str, str.GetLength(), dest_buf); + DecryptFinish(context, dest_buf); + str = dest_buf; } -void CPDF_CryptoHandler::Decrypt(FX_DWORD objnum, FX_DWORD gennum, CFX_ByteString& str) -{ - CFX_BinaryBuf dest_buf; - void* context = DecryptStart(objnum, gennum); - DecryptStream(context, (const uint8_t*)str, str.GetLength(), dest_buf); - DecryptFinish(context, dest_buf); - str = dest_buf; -} -CPDF_StandardCryptoHandler::CPDF_StandardCryptoHandler() -{ - m_pAESContext = NULL; - m_Cipher = FXCIPHER_NONE; - m_KeyLen = 0; -} -CPDF_StandardCryptoHandler::~CPDF_StandardCryptoHandler() -{ - if (m_pAESContext) { - FX_Free(m_pAESContext); - } +CPDF_StandardCryptoHandler::CPDF_StandardCryptoHandler() { + m_pAESContext = NULL; + m_Cipher = FXCIPHER_NONE; + m_KeyLen = 0; +} +CPDF_StandardCryptoHandler::~CPDF_StandardCryptoHandler() { + if (m_pAESContext) { + FX_Free(m_pAESContext); + } } diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_fdf.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_fdf.cpp index 1958fab280..19359ad7cf 100644 --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_fdf.cpp +++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_fdf.cpp @@ -5,29 +5,25 @@ // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com #include "../../../include/fpdfapi/fpdf_serial.h" -CFDF_Document::CFDF_Document() : CPDF_IndirectObjects(NULL) -{ - m_pRootDict = NULL; - m_pFile = NULL; - m_bOwnFile = FALSE; +CFDF_Document::CFDF_Document() : CPDF_IndirectObjects(NULL) { + m_pRootDict = NULL; + m_pFile = NULL; + m_bOwnFile = FALSE; } -CFDF_Document::~CFDF_Document() -{ - if (m_bOwnFile && m_pFile) { - m_pFile->Release(); - } +CFDF_Document::~CFDF_Document() { + if (m_bOwnFile && m_pFile) { + m_pFile->Release(); + } } -CFDF_Document* CFDF_Document::CreateNewDoc() -{ - CFDF_Document* pDoc = new CFDF_Document; - pDoc->m_pRootDict = new CPDF_Dictionary; - pDoc->AddIndirectObject(pDoc->m_pRootDict); - CPDF_Dictionary* pFDFDict = new CPDF_Dictionary; - pDoc->m_pRootDict->SetAt(FX_BSTRC("FDF"), pFDFDict); - return pDoc; +CFDF_Document* CFDF_Document::CreateNewDoc() { + CFDF_Document* pDoc = new CFDF_Document; + pDoc->m_pRootDict = new CPDF_Dictionary; + pDoc->AddIndirectObject(pDoc->m_pRootDict); + CPDF_Dictionary* pFDFDict = new CPDF_Dictionary; + pDoc->m_pRootDict->SetAt(FX_BSTRC("FDF"), pFDFDict); + return pDoc; } -CFDF_Document* CFDF_Document::ParseFile(IFX_FileRead *pFile, FX_BOOL bOwnFile) -{ +CFDF_Document* CFDF_Document::ParseFile(IFX_FileRead* pFile, FX_BOOL bOwnFile) { if (!pFile) { return NULL; } @@ -39,151 +35,152 @@ CFDF_Document* CFDF_Document::ParseFile(IFX_FileRead *pFile, FX_BOOL bOwnFile) } return pDoc; } -CFDF_Document* CFDF_Document::ParseMemory(const uint8_t* pData, FX_DWORD size) -{ - return CFDF_Document::ParseFile(FX_CreateMemoryStream((uint8_t*)pData, size), TRUE); +CFDF_Document* CFDF_Document::ParseMemory(const uint8_t* pData, FX_DWORD size) { + return CFDF_Document::ParseFile(FX_CreateMemoryStream((uint8_t*)pData, size), + TRUE); } -void CFDF_Document::ParseStream(IFX_FileRead *pFile, FX_BOOL bOwnFile) -{ - m_pFile = pFile; - m_bOwnFile = bOwnFile; - CPDF_SyntaxParser parser; - parser.InitParser(m_pFile, 0); - while (1) { - FX_BOOL bNumber; - CFX_ByteString word = parser.GetNextWord(bNumber); - if (bNumber) { - FX_DWORD objnum = FXSYS_atoi(word); - word = parser.GetNextWord(bNumber); - if (!bNumber) { - break; - } - word = parser.GetNextWord(bNumber); - if (word != FX_BSTRC("obj")) { - break; - } - CPDF_Object* pObj = parser.GetObject(this, objnum, 0, 0); - if (pObj == NULL) { - break; - } - InsertIndirectObject(objnum, pObj); - word = parser.GetNextWord(bNumber); - if (word != FX_BSTRC("endobj")) { - break; - } - } else { - if (word != FX_BSTRC("trailer")) { - break; - } - CPDF_Dictionary* pMainDict = (CPDF_Dictionary*)parser.GetObject(this, 0, 0, 0); - if (pMainDict == NULL || pMainDict->GetType() != PDFOBJ_DICTIONARY) { - break; - } - m_pRootDict = pMainDict->GetDict(FX_BSTRC("Root")); - pMainDict->Release(); - break; - } - } -} -FX_BOOL CFDF_Document::WriteBuf(CFX_ByteTextBuf& buf) const -{ - if (m_pRootDict == NULL) { - return FALSE; - } - buf << FX_BSTRC("%FDF-1.2\r\n"); - FX_POSITION pos = m_IndirectObjs.GetStartPosition(); - while(pos) { - size_t objnum; - CPDF_Object* pObj; - m_IndirectObjs.GetNextAssoc(pos, (void*&)objnum, (void*&)pObj); - buf << (FX_DWORD)objnum << FX_BSTRC(" 0 obj\r\n") << pObj << FX_BSTRC("\r\nendobj\r\n\r\n"); +void CFDF_Document::ParseStream(IFX_FileRead* pFile, FX_BOOL bOwnFile) { + m_pFile = pFile; + m_bOwnFile = bOwnFile; + CPDF_SyntaxParser parser; + parser.InitParser(m_pFile, 0); + while (1) { + FX_BOOL bNumber; + CFX_ByteString word = parser.GetNextWord(bNumber); + if (bNumber) { + FX_DWORD objnum = FXSYS_atoi(word); + word = parser.GetNextWord(bNumber); + if (!bNumber) { + break; + } + word = parser.GetNextWord(bNumber); + if (word != FX_BSTRC("obj")) { + break; + } + CPDF_Object* pObj = parser.GetObject(this, objnum, 0, 0); + if (pObj == NULL) { + break; + } + InsertIndirectObject(objnum, pObj); + word = parser.GetNextWord(bNumber); + if (word != FX_BSTRC("endobj")) { + break; + } + } else { + if (word != FX_BSTRC("trailer")) { + break; + } + CPDF_Dictionary* pMainDict = + (CPDF_Dictionary*)parser.GetObject(this, 0, 0, 0); + if (pMainDict == NULL || pMainDict->GetType() != PDFOBJ_DICTIONARY) { + break; + } + m_pRootDict = pMainDict->GetDict(FX_BSTRC("Root")); + pMainDict->Release(); + break; } - buf << FX_BSTRC("trailer\r\n<</Root ") << m_pRootDict->GetObjNum() << FX_BSTRC(" 0 R>>\r\n%%EOF\r\n"); - return TRUE; + } } -CFX_WideString CFDF_Document::GetWin32Path() const -{ - CPDF_Dictionary* pDict = m_pRootDict ? m_pRootDict->GetDict(FX_BSTRC("FDF")) : NULL; - CPDF_Object* pFileSpec = pDict ? pDict->GetElementValue(FX_BSTRC("F")) : NULL; - if (pFileSpec == NULL) { - return CFX_WideString(); - } - if (pFileSpec->GetType() == PDFOBJ_STRING) { - return FPDF_FileSpec_GetWin32Path(m_pRootDict->GetDict(FX_BSTRC("FDF"))); - } - return FPDF_FileSpec_GetWin32Path(pFileSpec); +FX_BOOL CFDF_Document::WriteBuf(CFX_ByteTextBuf& buf) const { + if (m_pRootDict == NULL) { + return FALSE; + } + buf << FX_BSTRC("%FDF-1.2\r\n"); + FX_POSITION pos = m_IndirectObjs.GetStartPosition(); + while (pos) { + size_t objnum; + CPDF_Object* pObj; + m_IndirectObjs.GetNextAssoc(pos, (void*&)objnum, (void*&)pObj); + buf << (FX_DWORD)objnum << FX_BSTRC(" 0 obj\r\n") << pObj + << FX_BSTRC("\r\nendobj\r\n\r\n"); + } + buf << FX_BSTRC("trailer\r\n<</Root ") << m_pRootDict->GetObjNum() + << FX_BSTRC(" 0 R>>\r\n%%EOF\r\n"); + return TRUE; } -static CFX_WideString ChangeSlash(const FX_WCHAR* str) -{ - CFX_WideString result; - while (*str) { - if (*str == '\\') { - result += '/'; - } else if (*str == '/') { - result += '\\'; - } else { - result += *str; - } - str ++; - } - return result; +CFX_WideString CFDF_Document::GetWin32Path() const { + CPDF_Dictionary* pDict = + m_pRootDict ? m_pRootDict->GetDict(FX_BSTRC("FDF")) : NULL; + CPDF_Object* pFileSpec = pDict ? pDict->GetElementValue(FX_BSTRC("F")) : NULL; + if (pFileSpec == NULL) { + return CFX_WideString(); + } + if (pFileSpec->GetType() == PDFOBJ_STRING) { + return FPDF_FileSpec_GetWin32Path(m_pRootDict->GetDict(FX_BSTRC("FDF"))); + } + return FPDF_FileSpec_GetWin32Path(pFileSpec); } -void FPDF_FileSpec_SetWin32Path(CPDF_Object* pFileSpec, const CFX_WideString& filepath) -{ - CFX_WideString result; - if (filepath.GetLength() > 1 && filepath[1] == ':') { - result = L"/"; - result += filepath[0]; - if (filepath[2] != '\\') { - result += '/'; - } - result += ChangeSlash(filepath.c_str() + 2); - } else if (filepath.GetLength() > 1 && filepath[0] == '\\' && filepath[1] == '\\') { - result = ChangeSlash(filepath.c_str() + 1); +static CFX_WideString ChangeSlash(const FX_WCHAR* str) { + CFX_WideString result; + while (*str) { + if (*str == '\\') { + result += '/'; + } else if (*str == '/') { + result += '\\'; } else { - result = ChangeSlash(filepath.c_str()); - } - if (pFileSpec->GetType() == PDFOBJ_STRING) { - pFileSpec->SetString(CFX_ByteString::FromUnicode(result)); - } else if (pFileSpec->GetType() == PDFOBJ_DICTIONARY) { - ((CPDF_Dictionary*)pFileSpec)->SetAtString(FX_BSTRC("F"), CFX_ByteString::FromUnicode(result)); - ((CPDF_Dictionary*)pFileSpec)->SetAtString(FX_BSTRC("UF"), PDF_EncodeText(result)); - ((CPDF_Dictionary*)pFileSpec)->RemoveAt(FX_BSTRC("FS")); + result += *str; } + str++; + } + return result; } -CFX_WideString FPDF_FileSpec_GetWin32Path(const CPDF_Object* pFileSpec) -{ - CFX_WideString wsFileName; - if (pFileSpec->GetType() == PDFOBJ_DICTIONARY) { - CPDF_Dictionary* pDict = (CPDF_Dictionary*)pFileSpec; - wsFileName = pDict->GetUnicodeText(FX_BSTRC("UF")); - if (wsFileName.IsEmpty()) { - wsFileName = CFX_WideString::FromLocal(pDict->GetString(FX_BSTRC("F"))); - } - if (pDict->GetString(FX_BSTRC("FS")) == FX_BSTRC("URL")) { - return wsFileName; - } - if (wsFileName.IsEmpty() && pDict->KeyExist(FX_BSTRC("DOS"))) { - wsFileName = CFX_WideString::FromLocal(pDict->GetString(FX_BSTRC("DOS"))); - } +void FPDF_FileSpec_SetWin32Path(CPDF_Object* pFileSpec, + const CFX_WideString& filepath) { + CFX_WideString result; + if (filepath.GetLength() > 1 && filepath[1] == ':') { + result = L"/"; + result += filepath[0]; + if (filepath[2] != '\\') { + result += '/'; } - else if (!pFileSpec) - wsFileName = CFX_WideString(); - else { - wsFileName = CFX_WideString::FromLocal(pFileSpec->GetString()); + result += ChangeSlash(filepath.c_str() + 2); + } else if (filepath.GetLength() > 1 && filepath[0] == '\\' && + filepath[1] == '\\') { + result = ChangeSlash(filepath.c_str() + 1); + } else { + result = ChangeSlash(filepath.c_str()); + } + if (pFileSpec->GetType() == PDFOBJ_STRING) { + pFileSpec->SetString(CFX_ByteString::FromUnicode(result)); + } else if (pFileSpec->GetType() == PDFOBJ_DICTIONARY) { + ((CPDF_Dictionary*)pFileSpec) + ->SetAtString(FX_BSTRC("F"), CFX_ByteString::FromUnicode(result)); + ((CPDF_Dictionary*)pFileSpec) + ->SetAtString(FX_BSTRC("UF"), PDF_EncodeText(result)); + ((CPDF_Dictionary*)pFileSpec)->RemoveAt(FX_BSTRC("FS")); + } +} +CFX_WideString FPDF_FileSpec_GetWin32Path(const CPDF_Object* pFileSpec) { + CFX_WideString wsFileName; + if (pFileSpec->GetType() == PDFOBJ_DICTIONARY) { + CPDF_Dictionary* pDict = (CPDF_Dictionary*)pFileSpec; + wsFileName = pDict->GetUnicodeText(FX_BSTRC("UF")); + if (wsFileName.IsEmpty()) { + wsFileName = CFX_WideString::FromLocal(pDict->GetString(FX_BSTRC("F"))); } - if (wsFileName[0] != '/') { - return ChangeSlash(wsFileName.c_str()); + if (pDict->GetString(FX_BSTRC("FS")) == FX_BSTRC("URL")) { + return wsFileName; } - if (wsFileName[2] == '/') { - CFX_WideString result; - result += wsFileName[1]; - result += ':'; - result += ChangeSlash(wsFileName.c_str() + 2); - return result; + if (wsFileName.IsEmpty() && pDict->KeyExist(FX_BSTRC("DOS"))) { + wsFileName = CFX_WideString::FromLocal(pDict->GetString(FX_BSTRC("DOS"))); } + } else if (!pFileSpec) + wsFileName = CFX_WideString(); + else { + wsFileName = CFX_WideString::FromLocal(pFileSpec->GetString()); + } + if (wsFileName[0] != '/') { + return ChangeSlash(wsFileName.c_str()); + } + if (wsFileName[2] == '/') { CFX_WideString result; - result += '\\'; - result += ChangeSlash(wsFileName.c_str()); + result += wsFileName[1]; + result += ':'; + result += ChangeSlash(wsFileName.c_str() + 2); return result; + } + CFX_WideString result; + result += '\\'; + result += ChangeSlash(wsFileName.c_str()); + return result; } diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_filters.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_filters.cpp index fed4546fab..8cb432029c 100644 --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_filters.cpp +++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_filters.cpp @@ -12,888 +12,918 @@ extern "C" { -static void* my_alloc_func(void* opaque, unsigned int items, unsigned int size) -{ - return FX_Alloc2D(uint8_t, items, size); +static void* my_alloc_func(void* opaque, + unsigned int items, + unsigned int size) { + return FX_Alloc2D(uint8_t, items, size); } -static void my_free_func(void* opaque, void* address) -{ - FX_Free(address); +static void my_free_func(void* opaque, void* address) { + FX_Free(address); } } // extern "C" -CFX_DataFilter::CFX_DataFilter() -{ - m_bEOF = FALSE; - m_pDestFilter = NULL; - m_SrcPos = 0; -} -CFX_DataFilter::~CFX_DataFilter() -{ - delete m_pDestFilter; -} -void CFX_DataFilter::SetDestFilter(CFX_DataFilter* pFilter) -{ - if (m_pDestFilter) { - m_pDestFilter->SetDestFilter(pFilter); - } else { - m_pDestFilter = pFilter; - } -} -void CFX_DataFilter::FilterIn(const uint8_t* src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf) -{ - if (m_bEOF) { - return; - } - m_SrcPos += src_size; - if (m_pDestFilter) { - CFX_BinaryBuf temp_buf; - temp_buf.EstimateSize(FPDF_FILTER_BUFFER_SIZE, FPDF_FILTER_BUFFER_SIZE); - v_FilterIn(src_buf, src_size, temp_buf); - m_pDestFilter->FilterIn(temp_buf.GetBuffer(), temp_buf.GetSize(), dest_buf); - } else { - v_FilterIn(src_buf, src_size, dest_buf); - } -} -void CFX_DataFilter::FilterFinish(CFX_BinaryBuf& dest_buf) -{ - if (m_pDestFilter) { - CFX_BinaryBuf temp_buf; - v_FilterFinish(temp_buf); - if (temp_buf.GetSize()) { - m_pDestFilter->FilterIn(temp_buf.GetBuffer(), temp_buf.GetSize(), dest_buf); - } - m_pDestFilter->FilterFinish(dest_buf); - } else { - v_FilterFinish(dest_buf); - } - m_bEOF = TRUE; -} -void CFX_DataFilter::ReportEOF(FX_DWORD left_input) -{ - if (m_bEOF) { - return; - } - m_bEOF = TRUE; - m_SrcPos -= left_input; -} -CFX_DataFilter* FPDF_CreateFilter(const CFX_ByteStringC& name, const CPDF_Dictionary* pParam, int width, int height) -{ - FX_DWORD id = name.GetID(); - switch (id) { - case FXBSTR_ID('F', 'l', 'a', 't'): - case FXBSTR_ID('F', 'l', 0, 0): - case FXBSTR_ID('L', 'Z', 'W', 'D'): - case FXBSTR_ID('L', 'Z', 'W', 0): { - CFX_DataFilter* pFilter; - if (id == FXBSTR_ID('L', 'Z', 'W', 'D') || id == FXBSTR_ID('L', 'Z', 'W', 0)) { - pFilter = new CPDF_LzwFilter(pParam ? pParam->GetInteger("EarlyChange", 1) : 1); - } else { - pFilter = new CPDF_FlateFilter; - } - if ((pParam ? pParam->GetInteger("Predictor", 1) : 1) > 1) { - CFX_DataFilter* pPredictor = new CPDF_PredictorFilter(pParam->GetInteger(FX_BSTRC("Predictor"), 1), - pParam->GetInteger(FX_BSTRC("Colors"), 1), pParam->GetInteger(FX_BSTRC("BitsPerComponent"), 8), - pParam->GetInteger(FX_BSTRC("Columns"), 1)); - pFilter->SetDestFilter(pPredictor); - } - return pFilter; - } - case FXBSTR_ID('A', 'S', 'C', 'I'): - if (name == "ASCIIHexDecode") { - return new CPDF_AsciiHexFilter; - } - return new CPDF_Ascii85Filter; - case FXBSTR_ID('A', 'H', 'x', 0): - return new CPDF_AsciiHexFilter; - case FXBSTR_ID('A', '8', '5', 0): - return new CPDF_Ascii85Filter; - case FXBSTR_ID('R', 'u', 'n', 'L'): - return new CPDF_RunLenFilter; - case FXBSTR_ID('C', 'C', 'I', 'T'): { - int Encoding = 0; - int bEndOfLine = FALSE; - int bByteAlign = FALSE; - int bBlack = FALSE; - int nRows = 0; - int nColumns = 1728; - if (pParam) { - Encoding = pParam->GetInteger(FX_BSTRC("K")); - bEndOfLine = pParam->GetInteger(FX_BSTRC("EndOfLine")); - bByteAlign = pParam->GetInteger(FX_BSTRC("EncodedByteAlign")); - bBlack = pParam->GetInteger(FX_BSTRC("BlackIs1")); - nColumns = pParam->GetInteger(FX_BSTRC("Columns"), 1728); - nRows = pParam->GetInteger(FX_BSTRC("Rows")); - } - if (nColumns == 0) { - nColumns = width; - } - if (nRows == 0) { - nRows = height; - } - CPDF_FaxFilter* pFilter = new CPDF_FaxFilter(); - pFilter->Initialize(Encoding, bEndOfLine, bByteAlign, bBlack, nRows, nColumns); - return pFilter; - } - case FXBSTR_ID('D', 'C', 'T', 'D'): - return new CPDF_JpegFilter; - default: - return NULL; - } -} -CFX_DataFilter* _FPDF_CreateFilterFromDict(CPDF_Dictionary* pDict) -{ - CPDF_Object* pDecoder = pDict->GetElementValue("Filter"); - if (pDecoder == NULL) { - return NULL; - } - CFX_DataFilter* pFirstFilter = NULL; - int width = pDict->GetInteger(FX_BSTRC("Width")), height = pDict->GetInteger(FX_BSTRC("Height")); - CPDF_Object* pParams = pDict->GetElementValue("DecodeParms"); - if (pDecoder->GetType() == PDFOBJ_ARRAY) { - if (pParams && pParams->GetType() != PDFOBJ_ARRAY) { - pParams = NULL; - } - for (FX_DWORD i = 0; i < ((CPDF_Array*)pDecoder)->GetCount(); i ++) { - CFX_ByteString name = ((CPDF_Array*)pDecoder)->GetString(i); - CPDF_Dictionary* pParam = NULL; - if (pParams) { - pParam = ((CPDF_Array*)pParams)->GetDict(i); - } - CFX_DataFilter* pDestFilter = FPDF_CreateFilter(name, pParam, width, height); - if (pDestFilter) { - if (pFirstFilter == NULL) { - pFirstFilter = pDestFilter; - } else { - pFirstFilter->SetDestFilter(pDestFilter); - } - } - } - } else { - if (pParams && pParams->GetType() != PDFOBJ_DICTIONARY) { - pParams = NULL; - } - pFirstFilter = FPDF_CreateFilter(pDecoder->GetString(), (CPDF_Dictionary*)pParams, width, height); - } - return pFirstFilter; -} -CPDF_StreamFilter* CPDF_Stream::GetStreamFilter(FX_BOOL bRaw) const -{ - CFX_DataFilter* pFirstFilter = NULL; - if (m_pCryptoHandler) { - pFirstFilter = new CPDF_DecryptFilter(m_pCryptoHandler, m_ObjNum, m_GenNum); - } - if (!bRaw) { - CFX_DataFilter* pFilter = _FPDF_CreateFilterFromDict(m_pDict); - if (pFilter) { - if (pFirstFilter == NULL) { - pFirstFilter = pFilter; - } else { - pFirstFilter->SetDestFilter(pFilter); - } - } - } - CPDF_StreamFilter* pStreamFilter = new CPDF_StreamFilter; - pStreamFilter->m_pStream = this; - pStreamFilter->m_pFilter = pFirstFilter; - pStreamFilter->m_pBuffer = NULL; - pStreamFilter->m_SrcOffset = 0; - return pStreamFilter; -} -CPDF_StreamFilter::~CPDF_StreamFilter() -{ - delete m_pFilter; - delete m_pBuffer; -} -#define FPDF_FILTER_BUFFER_IN_SIZE FPDF_FILTER_BUFFER_SIZE -FX_DWORD CPDF_StreamFilter::ReadBlock(uint8_t* buffer, FX_DWORD buf_size) -{ - if (m_pFilter == NULL) { - FX_DWORD read_size = m_pStream->GetRawSize() - m_SrcOffset; - if (read_size == 0) { - return 0; - } - if (read_size > buf_size) { - read_size = buf_size; - } - m_pStream->ReadRawData(m_SrcOffset, buffer, read_size); - m_SrcOffset += read_size; - return read_size; - } - FX_DWORD read_size = 0; - if (m_pBuffer) { - read_size = ReadLeftOver(buffer, buf_size); - if (read_size == buf_size) { - return read_size; - } - buffer += read_size; - buf_size -= read_size; - } - ASSERT(m_pBuffer == NULL); - if (m_pFilter->IsEOF()) { - return read_size; - } - m_pBuffer = new CFX_BinaryBuf; - m_pBuffer->EstimateSize(FPDF_FILTER_BUFFER_SIZE, FPDF_FILTER_BUFFER_SIZE); - m_BufOffset = 0; - while (1) { - int src_size = m_pStream->GetRawSize() - m_SrcOffset; - if (src_size == 0) { - m_pFilter->FilterFinish(*m_pBuffer); - break; - } - if (src_size > FPDF_FILTER_BUFFER_IN_SIZE) { - src_size = FPDF_FILTER_BUFFER_IN_SIZE; - } - if (!m_pStream->ReadRawData(m_SrcOffset, m_SrcBuffer, src_size)) { - return 0; - } - m_SrcOffset += src_size; - m_pFilter->FilterIn(m_SrcBuffer, src_size, *m_pBuffer); - if (m_pBuffer->GetSize() >= (int)buf_size) { - break; - } +CFX_DataFilter::CFX_DataFilter() { + m_bEOF = FALSE; + m_pDestFilter = NULL; + m_SrcPos = 0; +} +CFX_DataFilter::~CFX_DataFilter() { + delete m_pDestFilter; +} +void CFX_DataFilter::SetDestFilter(CFX_DataFilter* pFilter) { + if (m_pDestFilter) { + m_pDestFilter->SetDestFilter(pFilter); + } else { + m_pDestFilter = pFilter; + } +} +void CFX_DataFilter::FilterIn(const uint8_t* src_buf, + FX_DWORD src_size, + CFX_BinaryBuf& dest_buf) { + if (m_bEOF) { + return; + } + m_SrcPos += src_size; + if (m_pDestFilter) { + CFX_BinaryBuf temp_buf; + temp_buf.EstimateSize(FPDF_FILTER_BUFFER_SIZE, FPDF_FILTER_BUFFER_SIZE); + v_FilterIn(src_buf, src_size, temp_buf); + m_pDestFilter->FilterIn(temp_buf.GetBuffer(), temp_buf.GetSize(), dest_buf); + } else { + v_FilterIn(src_buf, src_size, dest_buf); + } +} +void CFX_DataFilter::FilterFinish(CFX_BinaryBuf& dest_buf) { + if (m_pDestFilter) { + CFX_BinaryBuf temp_buf; + v_FilterFinish(temp_buf); + if (temp_buf.GetSize()) { + m_pDestFilter->FilterIn(temp_buf.GetBuffer(), temp_buf.GetSize(), + dest_buf); + } + m_pDestFilter->FilterFinish(dest_buf); + } else { + v_FilterFinish(dest_buf); + } + m_bEOF = TRUE; +} +void CFX_DataFilter::ReportEOF(FX_DWORD left_input) { + if (m_bEOF) { + return; + } + m_bEOF = TRUE; + m_SrcPos -= left_input; +} +CFX_DataFilter* FPDF_CreateFilter(const CFX_ByteStringC& name, + const CPDF_Dictionary* pParam, + int width, + int height) { + FX_DWORD id = name.GetID(); + switch (id) { + case FXBSTR_ID('F', 'l', 'a', 't'): + case FXBSTR_ID('F', 'l', 0, 0): + case FXBSTR_ID('L', 'Z', 'W', 'D'): + case FXBSTR_ID('L', 'Z', 'W', 0): { + CFX_DataFilter* pFilter; + if (id == FXBSTR_ID('L', 'Z', 'W', 'D') || + id == FXBSTR_ID('L', 'Z', 'W', 0)) { + pFilter = new CPDF_LzwFilter( + pParam ? pParam->GetInteger("EarlyChange", 1) : 1); + } else { + pFilter = new CPDF_FlateFilter; + } + if ((pParam ? pParam->GetInteger("Predictor", 1) : 1) > 1) { + CFX_DataFilter* pPredictor = new CPDF_PredictorFilter( + pParam->GetInteger(FX_BSTRC("Predictor"), 1), + pParam->GetInteger(FX_BSTRC("Colors"), 1), + pParam->GetInteger(FX_BSTRC("BitsPerComponent"), 8), + pParam->GetInteger(FX_BSTRC("Columns"), 1)); + pFilter->SetDestFilter(pPredictor); + } + return pFilter; + } + case FXBSTR_ID('A', 'S', 'C', 'I'): + if (name == "ASCIIHexDecode") { + return new CPDF_AsciiHexFilter; + } + return new CPDF_Ascii85Filter; + case FXBSTR_ID('A', 'H', 'x', 0): + return new CPDF_AsciiHexFilter; + case FXBSTR_ID('A', '8', '5', 0): + return new CPDF_Ascii85Filter; + case FXBSTR_ID('R', 'u', 'n', 'L'): + return new CPDF_RunLenFilter; + case FXBSTR_ID('C', 'C', 'I', 'T'): { + int Encoding = 0; + int bEndOfLine = FALSE; + int bByteAlign = FALSE; + int bBlack = FALSE; + int nRows = 0; + int nColumns = 1728; + if (pParam) { + Encoding = pParam->GetInteger(FX_BSTRC("K")); + bEndOfLine = pParam->GetInteger(FX_BSTRC("EndOfLine")); + bByteAlign = pParam->GetInteger(FX_BSTRC("EncodedByteAlign")); + bBlack = pParam->GetInteger(FX_BSTRC("BlackIs1")); + nColumns = pParam->GetInteger(FX_BSTRC("Columns"), 1728); + nRows = pParam->GetInteger(FX_BSTRC("Rows")); + } + if (nColumns == 0) { + nColumns = width; + } + if (nRows == 0) { + nRows = height; + } + CPDF_FaxFilter* pFilter = new CPDF_FaxFilter(); + pFilter->Initialize(Encoding, bEndOfLine, bByteAlign, bBlack, nRows, + nColumns); + return pFilter; + } + case FXBSTR_ID('D', 'C', 'T', 'D'): + return new CPDF_JpegFilter; + default: + return NULL; + } +} +CFX_DataFilter* _FPDF_CreateFilterFromDict(CPDF_Dictionary* pDict) { + CPDF_Object* pDecoder = pDict->GetElementValue("Filter"); + if (pDecoder == NULL) { + return NULL; + } + CFX_DataFilter* pFirstFilter = NULL; + int width = pDict->GetInteger(FX_BSTRC("Width")), + height = pDict->GetInteger(FX_BSTRC("Height")); + CPDF_Object* pParams = pDict->GetElementValue("DecodeParms"); + if (pDecoder->GetType() == PDFOBJ_ARRAY) { + if (pParams && pParams->GetType() != PDFOBJ_ARRAY) { + pParams = NULL; + } + for (FX_DWORD i = 0; i < ((CPDF_Array*)pDecoder)->GetCount(); i++) { + CFX_ByteString name = ((CPDF_Array*)pDecoder)->GetString(i); + CPDF_Dictionary* pParam = NULL; + if (pParams) { + pParam = ((CPDF_Array*)pParams)->GetDict(i); + } + CFX_DataFilter* pDestFilter = + FPDF_CreateFilter(name, pParam, width, height); + if (pDestFilter) { + if (pFirstFilter == NULL) { + pFirstFilter = pDestFilter; + } else { + pFirstFilter->SetDestFilter(pDestFilter); + } + } + } + } else { + if (pParams && pParams->GetType() != PDFOBJ_DICTIONARY) { + pParams = NULL; + } + pFirstFilter = FPDF_CreateFilter(pDecoder->GetString(), + (CPDF_Dictionary*)pParams, width, height); + } + return pFirstFilter; +} +CPDF_StreamFilter* CPDF_Stream::GetStreamFilter(FX_BOOL bRaw) const { + CFX_DataFilter* pFirstFilter = NULL; + if (m_pCryptoHandler) { + pFirstFilter = new CPDF_DecryptFilter(m_pCryptoHandler, m_ObjNum, m_GenNum); + } + if (!bRaw) { + CFX_DataFilter* pFilter = _FPDF_CreateFilterFromDict(m_pDict); + if (pFilter) { + if (pFirstFilter == NULL) { + pFirstFilter = pFilter; + } else { + pFirstFilter->SetDestFilter(pFilter); + } + } + } + CPDF_StreamFilter* pStreamFilter = new CPDF_StreamFilter; + pStreamFilter->m_pStream = this; + pStreamFilter->m_pFilter = pFirstFilter; + pStreamFilter->m_pBuffer = NULL; + pStreamFilter->m_SrcOffset = 0; + return pStreamFilter; +} +CPDF_StreamFilter::~CPDF_StreamFilter() { + delete m_pFilter; + delete m_pBuffer; +} +#define FPDF_FILTER_BUFFER_IN_SIZE FPDF_FILTER_BUFFER_SIZE +FX_DWORD CPDF_StreamFilter::ReadBlock(uint8_t* buffer, FX_DWORD buf_size) { + if (m_pFilter == NULL) { + FX_DWORD read_size = m_pStream->GetRawSize() - m_SrcOffset; + if (read_size == 0) { + return 0; } - return read_size + ReadLeftOver(buffer, buf_size); -} -FX_DWORD CPDF_StreamFilter::ReadLeftOver(uint8_t* buffer, FX_DWORD buf_size) -{ - FX_DWORD read_size = m_pBuffer->GetSize() - m_BufOffset; if (read_size > buf_size) { - read_size = buf_size; - } - FXSYS_memcpy(buffer, m_pBuffer->GetBuffer() + m_BufOffset, read_size); - m_BufOffset += read_size; - if (m_BufOffset == (FX_DWORD)m_pBuffer->GetSize()) { - delete m_pBuffer; - m_pBuffer = NULL; + read_size = buf_size; } + m_pStream->ReadRawData(m_SrcOffset, buffer, read_size); + m_SrcOffset += read_size; return read_size; -} -CPDF_DecryptFilter::CPDF_DecryptFilter(CPDF_CryptoHandler* pCryptoHandler, FX_DWORD objnum, FX_DWORD gennum) -{ - m_pCryptoHandler = pCryptoHandler; - m_pContext = NULL; - m_ObjNum = objnum; - m_GenNum = gennum; -} -CPDF_DecryptFilter::~CPDF_DecryptFilter() -{ - CFX_BinaryBuf buf; - if (m_pContext) { - m_pCryptoHandler->DecryptFinish(m_pContext, buf); - } -} -void CPDF_DecryptFilter::v_FilterIn(const uint8_t* src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf) -{ - if (m_pContext == NULL) { - m_pContext = m_pCryptoHandler->DecryptStart(m_ObjNum, m_GenNum); - } - m_pCryptoHandler->DecryptStream(m_pContext, src_buf, src_size, dest_buf); -} -void CPDF_DecryptFilter::v_FilterFinish(CFX_BinaryBuf& dest_buf) -{ - m_bEOF = TRUE; - if (m_pContext == NULL) { + } + FX_DWORD read_size = 0; + if (m_pBuffer) { + read_size = ReadLeftOver(buffer, buf_size); + if (read_size == buf_size) { + return read_size; + } + buffer += read_size; + buf_size -= read_size; + } + ASSERT(m_pBuffer == NULL); + if (m_pFilter->IsEOF()) { + return read_size; + } + m_pBuffer = new CFX_BinaryBuf; + m_pBuffer->EstimateSize(FPDF_FILTER_BUFFER_SIZE, FPDF_FILTER_BUFFER_SIZE); + m_BufOffset = 0; + while (1) { + int src_size = m_pStream->GetRawSize() - m_SrcOffset; + if (src_size == 0) { + m_pFilter->FilterFinish(*m_pBuffer); + break; + } + if (src_size > FPDF_FILTER_BUFFER_IN_SIZE) { + src_size = FPDF_FILTER_BUFFER_IN_SIZE; + } + if (!m_pStream->ReadRawData(m_SrcOffset, m_SrcBuffer, src_size)) { + return 0; + } + m_SrcOffset += src_size; + m_pFilter->FilterIn(m_SrcBuffer, src_size, *m_pBuffer); + if (m_pBuffer->GetSize() >= (int)buf_size) { + break; + } + } + return read_size + ReadLeftOver(buffer, buf_size); +} +FX_DWORD CPDF_StreamFilter::ReadLeftOver(uint8_t* buffer, FX_DWORD buf_size) { + FX_DWORD read_size = m_pBuffer->GetSize() - m_BufOffset; + if (read_size > buf_size) { + read_size = buf_size; + } + FXSYS_memcpy(buffer, m_pBuffer->GetBuffer() + m_BufOffset, read_size); + m_BufOffset += read_size; + if (m_BufOffset == (FX_DWORD)m_pBuffer->GetSize()) { + delete m_pBuffer; + m_pBuffer = NULL; + } + return read_size; +} +CPDF_DecryptFilter::CPDF_DecryptFilter(CPDF_CryptoHandler* pCryptoHandler, + FX_DWORD objnum, + FX_DWORD gennum) { + m_pCryptoHandler = pCryptoHandler; + m_pContext = NULL; + m_ObjNum = objnum; + m_GenNum = gennum; +} +CPDF_DecryptFilter::~CPDF_DecryptFilter() { + CFX_BinaryBuf buf; + if (m_pContext) { + m_pCryptoHandler->DecryptFinish(m_pContext, buf); + } +} +void CPDF_DecryptFilter::v_FilterIn(const uint8_t* src_buf, + FX_DWORD src_size, + CFX_BinaryBuf& dest_buf) { + if (m_pContext == NULL) { + m_pContext = m_pCryptoHandler->DecryptStart(m_ObjNum, m_GenNum); + } + m_pCryptoHandler->DecryptStream(m_pContext, src_buf, src_size, dest_buf); +} +void CPDF_DecryptFilter::v_FilterFinish(CFX_BinaryBuf& dest_buf) { + m_bEOF = TRUE; + if (m_pContext == NULL) { + return; + } + m_pCryptoHandler->DecryptFinish(m_pContext, dest_buf); + m_pContext = NULL; +} +CPDF_FlateFilter::CPDF_FlateFilter() { + m_pContext = NULL; +} +CPDF_FlateFilter::~CPDF_FlateFilter() { + if (m_pContext) { + FPDFAPI_FlateEnd(m_pContext); + } +} +void CPDF_FlateFilter::v_FilterIn(const uint8_t* src_buf, + FX_DWORD src_size, + CFX_BinaryBuf& dest_buf) { + if (m_pContext == NULL) { + m_pContext = FPDFAPI_FlateInit(my_alloc_func, my_free_func); + } + FPDFAPI_FlateInput(m_pContext, src_buf, src_size); + while (1) { + int ret = + FPDFAPI_FlateOutput(m_pContext, m_DestBuffer, FPDF_FILTER_BUFFER_SIZE); + int out_size = + FPDF_FILTER_BUFFER_SIZE - FPDFAPI_FlateGetAvailOut(m_pContext); + dest_buf.AppendBlock(m_DestBuffer, out_size); + if (ret == Z_BUF_ERROR) { + break; + } + if (ret != Z_OK) { + ReportEOF(FPDFAPI_FlateGetAvailIn(m_pContext)); + break; + } + } +} +CPDF_LzwFilter::CPDF_LzwFilter(FX_BOOL bEarlyChange) { + m_bEarlyChange = bEarlyChange ? 1 : 0; + m_CodeLen = 9; + m_nCodes = 0; + m_nLeftBits = 0; + m_LeftBits = 0; + m_OldCode = (FX_DWORD)-1; +} +void CPDF_LzwFilter::v_FilterIn(const uint8_t* src_buf, + FX_DWORD src_size, + CFX_BinaryBuf& dest_buf) { + for (FX_DWORD i = 0; i < src_size; i++) { + if (m_nLeftBits + 8 < m_CodeLen) { + m_nLeftBits += 8; + m_LeftBits = (m_LeftBits << 8) | src_buf[i]; + continue; + } + FX_DWORD new_bits = m_CodeLen - m_nLeftBits; + FX_DWORD code = (m_LeftBits << new_bits) | (src_buf[i] >> (8 - new_bits)); + m_nLeftBits = 8 - new_bits; + m_LeftBits = src_buf[i] % (1 << m_nLeftBits); + if (code < 256) { + dest_buf.AppendByte((uint8_t)code); + m_LastChar = (uint8_t)code; + if (m_OldCode != -1) { + AddCode(m_OldCode, m_LastChar); + } + m_OldCode = code; + } else if (code == 256) { + m_CodeLen = 9; + m_nCodes = 0; + m_OldCode = (FX_DWORD)-1; + } else if (code == 257) { + ReportEOF(src_size - i - 1); + return; + } else { + if (m_OldCode == -1) { + ReportEOF(src_size - i - 1); return; - } - m_pCryptoHandler->DecryptFinish(m_pContext, dest_buf); - m_pContext = NULL; -} -CPDF_FlateFilter::CPDF_FlateFilter() -{ - m_pContext = NULL; -} -CPDF_FlateFilter::~CPDF_FlateFilter() -{ - if (m_pContext) { - FPDFAPI_FlateEnd(m_pContext); - } -} -void CPDF_FlateFilter::v_FilterIn(const uint8_t* src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf) -{ - if (m_pContext == NULL) { - m_pContext = FPDFAPI_FlateInit(my_alloc_func, my_free_func); - } - FPDFAPI_FlateInput(m_pContext, src_buf, src_size); - while (1) { - int ret = FPDFAPI_FlateOutput(m_pContext, m_DestBuffer, FPDF_FILTER_BUFFER_SIZE); - int out_size = FPDF_FILTER_BUFFER_SIZE - FPDFAPI_FlateGetAvailOut(m_pContext); - dest_buf.AppendBlock(m_DestBuffer, out_size); - if (ret == Z_BUF_ERROR) { - break; - } - if (ret != Z_OK) { - ReportEOF(FPDFAPI_FlateGetAvailIn(m_pContext)); - break; - } - } -} -CPDF_LzwFilter::CPDF_LzwFilter(FX_BOOL bEarlyChange) -{ - m_bEarlyChange = bEarlyChange ? 1 : 0; - m_CodeLen = 9; - m_nCodes = 0; - m_nLeftBits = 0; - m_LeftBits = 0; - m_OldCode = (FX_DWORD) - 1; -} -void CPDF_LzwFilter::v_FilterIn(const uint8_t* src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf) -{ - for (FX_DWORD i = 0; i < src_size; i ++) { - if (m_nLeftBits + 8 < m_CodeLen) { - m_nLeftBits += 8; - m_LeftBits = (m_LeftBits << 8) | src_buf[i]; - continue; - } - FX_DWORD new_bits = m_CodeLen - m_nLeftBits; - FX_DWORD code = (m_LeftBits << new_bits) | (src_buf[i] >> (8 - new_bits)); - m_nLeftBits = 8 - new_bits; - m_LeftBits = src_buf[i] % (1 << m_nLeftBits); - if (code < 256) { - dest_buf.AppendByte((uint8_t)code); - m_LastChar = (uint8_t)code; - if (m_OldCode != -1) { - AddCode(m_OldCode, m_LastChar); - } - m_OldCode = code; - } else if (code == 256) { - m_CodeLen = 9; - m_nCodes = 0; - m_OldCode = (FX_DWORD) - 1; - } else if (code == 257) { - ReportEOF(src_size - i - 1); - return; - } else { - if (m_OldCode == -1) { - ReportEOF(src_size - i - 1); - return; - } - m_StackLen = 0; - if (code >= m_nCodes + 258) { - if (m_StackLen < sizeof(m_DecodeStack)) { - m_DecodeStack[m_StackLen++] = m_LastChar; - } - DecodeString(m_OldCode); - } else { - DecodeString(code); - } - dest_buf.AppendBlock(NULL, m_StackLen); - uint8_t* pOutput = dest_buf.GetBuffer() + dest_buf.GetSize() - m_StackLen; - for (FX_DWORD cc = 0; cc < m_StackLen; cc ++) { - pOutput[cc] = m_DecodeStack[m_StackLen - cc - 1]; - } - m_LastChar = m_DecodeStack[m_StackLen - 1]; - if (m_OldCode < 256) { - AddCode(m_OldCode, m_LastChar); - } else if (m_OldCode - 258 >= m_nCodes) { - ReportEOF(src_size - i - 1); - return; - } else { - AddCode(m_OldCode, m_LastChar); - } - m_OldCode = code; - } - } -} -void CPDF_LzwFilter::AddCode(FX_DWORD prefix_code, uint8_t append_char) -{ - if (m_nCodes + m_bEarlyChange == 4094) { + } + m_StackLen = 0; + if (code >= m_nCodes + 258) { + if (m_StackLen < sizeof(m_DecodeStack)) { + m_DecodeStack[m_StackLen++] = m_LastChar; + } + DecodeString(m_OldCode); + } else { + DecodeString(code); + } + dest_buf.AppendBlock(NULL, m_StackLen); + uint8_t* pOutput = dest_buf.GetBuffer() + dest_buf.GetSize() - m_StackLen; + for (FX_DWORD cc = 0; cc < m_StackLen; cc++) { + pOutput[cc] = m_DecodeStack[m_StackLen - cc - 1]; + } + m_LastChar = m_DecodeStack[m_StackLen - 1]; + if (m_OldCode < 256) { + AddCode(m_OldCode, m_LastChar); + } else if (m_OldCode - 258 >= m_nCodes) { + ReportEOF(src_size - i - 1); return; - } - m_CodeArray[m_nCodes ++] = (prefix_code << 16) | append_char; - if (m_nCodes + m_bEarlyChange == 512 - 258) { - m_CodeLen = 10; - } else if (m_nCodes + m_bEarlyChange == 1024 - 258) { - m_CodeLen = 11; - } else if (m_nCodes + m_bEarlyChange == 2048 - 258) { - m_CodeLen = 12; - } -} -void CPDF_LzwFilter::DecodeString(FX_DWORD code) -{ - while (1) { - int index = code - 258; - if (index < 0 || index >= (int)m_nCodes) { - break; - } - FX_DWORD data = m_CodeArray[index]; - if (m_StackLen >= sizeof(m_DecodeStack)) { - return; - } - m_DecodeStack[m_StackLen++] = (uint8_t)data; - code = data >> 16; - } + } else { + AddCode(m_OldCode, m_LastChar); + } + m_OldCode = code; + } + } +} +void CPDF_LzwFilter::AddCode(FX_DWORD prefix_code, uint8_t append_char) { + if (m_nCodes + m_bEarlyChange == 4094) { + return; + } + m_CodeArray[m_nCodes++] = (prefix_code << 16) | append_char; + if (m_nCodes + m_bEarlyChange == 512 - 258) { + m_CodeLen = 10; + } else if (m_nCodes + m_bEarlyChange == 1024 - 258) { + m_CodeLen = 11; + } else if (m_nCodes + m_bEarlyChange == 2048 - 258) { + m_CodeLen = 12; + } +} +void CPDF_LzwFilter::DecodeString(FX_DWORD code) { + while (1) { + int index = code - 258; + if (index < 0 || index >= (int)m_nCodes) { + break; + } + FX_DWORD data = m_CodeArray[index]; if (m_StackLen >= sizeof(m_DecodeStack)) { - return; - } - m_DecodeStack[m_StackLen++] = (uint8_t)code; -} -CPDF_PredictorFilter::CPDF_PredictorFilter(int predictor, int colors, int bpc, int cols) -{ - m_bTiff = predictor < 10; - m_pRefLine = NULL; - m_pCurLine = NULL; - m_iLine = 0; - m_LineInSize = 0; - m_Bpp = (colors * bpc + 7) / 8; - m_Pitch = (colors * bpc * cols + 7) / 8; + return; + } + m_DecodeStack[m_StackLen++] = (uint8_t)data; + code = data >> 16; + } + if (m_StackLen >= sizeof(m_DecodeStack)) { + return; + } + m_DecodeStack[m_StackLen++] = (uint8_t)code; +} +CPDF_PredictorFilter::CPDF_PredictorFilter(int predictor, + int colors, + int bpc, + int cols) { + m_bTiff = predictor < 10; + m_pRefLine = NULL; + m_pCurLine = NULL; + m_iLine = 0; + m_LineInSize = 0; + m_Bpp = (colors * bpc + 7) / 8; + m_Pitch = (colors * bpc * cols + 7) / 8; + if (!m_bTiff) { + m_Pitch++; + } +} +CPDF_PredictorFilter::~CPDF_PredictorFilter() { + if (m_pCurLine) { + FX_Free(m_pCurLine); + } + if (m_pRefLine) { + FX_Free(m_pRefLine); + } +} +static 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); + int pc = FXSYS_abs(p - c); + if (pa <= pb && pa <= pc) { + return (uint8_t)a; + } + if (pb <= pc) { + return (uint8_t)b; + } + return (uint8_t)c; +} +static void PNG_PredictorLine(uint8_t* cur_buf, + uint8_t* ref_buf, + int pitch, + int Bpp) { + uint8_t tag = cur_buf[0]; + if (tag == 0) { + return; + } + cur_buf++; + if (ref_buf) { + ref_buf++; + } + for (int byte = 0; byte < pitch; byte++) { + uint8_t raw_byte = cur_buf[byte]; + switch (tag) { + case 1: { + uint8_t left = 0; + if (byte >= Bpp) { + left = cur_buf[byte - Bpp]; + } + cur_buf[byte] = raw_byte + left; + break; + } + case 2: { + uint8_t up = 0; + if (ref_buf) { + up = ref_buf[byte]; + } + cur_buf[byte] = raw_byte + up; + break; + } + case 3: { + uint8_t left = 0; + if (byte >= Bpp) { + left = cur_buf[byte - Bpp]; + } + uint8_t up = 0; + if (ref_buf) { + up = ref_buf[byte]; + } + cur_buf[byte] = raw_byte + (up + left) / 2; + break; + } + case 4: { + uint8_t left = 0; + if (byte >= Bpp) { + left = cur_buf[byte - Bpp]; + } + uint8_t up = 0; + if (ref_buf) { + up = ref_buf[byte]; + } + uint8_t upper_left = 0; + if (byte >= Bpp && ref_buf) { + upper_left = ref_buf[byte - Bpp]; + } + cur_buf[byte] = raw_byte + PaethPredictor(left, up, upper_left); + break; + } + } + } +} +void CPDF_PredictorFilter::v_FilterIn(const uint8_t* src_buf, + FX_DWORD src_size, + CFX_BinaryBuf& dest_buf) { + if (m_pCurLine == NULL) { + m_pCurLine = FX_Alloc(uint8_t, m_Pitch); if (!m_bTiff) { - m_Pitch ++; - } -} -CPDF_PredictorFilter::~CPDF_PredictorFilter() -{ - if (m_pCurLine) { - FX_Free(m_pCurLine); - } - if (m_pRefLine) { - FX_Free(m_pRefLine); - } -} -static 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); - int pc = FXSYS_abs(p - c); - if (pa <= pb && pa <= pc) { - return (uint8_t)a; - } - if (pb <= pc) { - return (uint8_t)b; - } - return (uint8_t)c; -} -static void PNG_PredictorLine(uint8_t* cur_buf, uint8_t* ref_buf, int pitch, int Bpp) -{ - uint8_t tag = cur_buf[0]; - if (tag == 0) { - return; - } - cur_buf ++; - if (ref_buf) { - ref_buf ++; - } - for (int byte = 0; byte < pitch; byte ++) { - uint8_t raw_byte = cur_buf[byte]; - switch (tag) { - case 1: { - uint8_t left = 0; - if (byte >= Bpp) { - left = cur_buf[byte - Bpp]; - } - cur_buf[byte] = raw_byte + left; - break; - } - case 2: { - uint8_t up = 0; - if (ref_buf) { - up = ref_buf[byte]; - } - cur_buf[byte] = raw_byte + up; - break; - } - case 3: { - uint8_t left = 0; - if (byte >= Bpp) { - left = cur_buf[byte - Bpp]; - } - uint8_t up = 0; - if (ref_buf) { - up = ref_buf[byte]; - } - cur_buf[byte] = raw_byte + (up + left) / 2; - break; - } - case 4: { - uint8_t left = 0; - if (byte >= Bpp) { - left = cur_buf[byte - Bpp]; - } - uint8_t up = 0; - if (ref_buf) { - up = ref_buf[byte]; - } - uint8_t upper_left = 0; - if (byte >= Bpp && ref_buf) { - upper_left = ref_buf[byte - Bpp]; - } - cur_buf[byte] = raw_byte + PaethPredictor(left, up, upper_left); - break; - } - } - } -} -void CPDF_PredictorFilter::v_FilterIn(const uint8_t* src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf) -{ - if (m_pCurLine == NULL) { - m_pCurLine = FX_Alloc(uint8_t, m_Pitch); - if (!m_bTiff) { - m_pRefLine = FX_Alloc(uint8_t, m_Pitch); - } + m_pRefLine = FX_Alloc(uint8_t, m_Pitch); + } + } + while (1) { + FX_DWORD read_size = m_Pitch - m_LineInSize; + if (read_size > src_size) { + read_size = src_size; + } + FXSYS_memcpy(m_pCurLine + m_LineInSize, src_buf, read_size); + m_LineInSize += read_size; + if (m_LineInSize < m_Pitch) { + break; + } + src_buf += read_size; + src_size -= read_size; + if (m_bTiff) { + for (FX_DWORD byte = m_Bpp; byte < m_Pitch; byte++) { + m_pCurLine[byte] += m_pCurLine[byte - m_Bpp]; + } + dest_buf.AppendBlock(m_pCurLine, m_Pitch); + } else { + PNG_PredictorLine(m_pCurLine, m_iLine ? m_pRefLine : NULL, m_Pitch - 1, + m_Bpp); + dest_buf.AppendBlock(m_pCurLine + 1, m_Pitch - 1); + m_iLine++; + uint8_t* temp = m_pCurLine; + m_pCurLine = m_pRefLine; + m_pRefLine = temp; } - while (1) { - FX_DWORD read_size = m_Pitch - m_LineInSize; - if (read_size > src_size) { - read_size = src_size; - } - FXSYS_memcpy(m_pCurLine + m_LineInSize, src_buf, read_size); - m_LineInSize += read_size; - if (m_LineInSize < m_Pitch) { - break; - } - src_buf += read_size; - src_size -= read_size; - if (m_bTiff) { - for (FX_DWORD byte = m_Bpp; byte < m_Pitch; byte ++) { - m_pCurLine[byte] += m_pCurLine[byte - m_Bpp]; + m_LineInSize = 0; + } +} +CPDF_Ascii85Filter::CPDF_Ascii85Filter() { + m_State = 0; + m_CharCount = 0; +} +void CPDF_Ascii85Filter::v_FilterIn(const uint8_t* src_buf, + FX_DWORD src_size, + CFX_BinaryBuf& dest_buf) { + for (FX_DWORD i = 0; i < src_size; i++) { + uint8_t byte = src_buf[i]; + if (PDF_CharType[byte] == 'W') { + continue; + } + switch (m_State) { + case 0: + if (byte >= '!' && byte <= 'u') { + int digit = byte - '!'; + m_CurDWord = digit; + m_CharCount = 1; + m_State = 1; + } else if (byte == 'z') { + int zero = 0; + dest_buf.AppendBlock(&zero, 4); + } else if (byte == '~') { + m_State = 2; + } + break; + case 1: { + if (byte >= '!' && byte <= 'u') { + int digit = byte - '!'; + m_CurDWord = m_CurDWord * 85 + digit; + m_CharCount++; + if (m_CharCount == 5) { + for (int i = 0; i < 4; i++) { + dest_buf.AppendByte((uint8_t)(m_CurDWord >> (3 - i) * 8)); } - dest_buf.AppendBlock(m_pCurLine, m_Pitch); - } else { - PNG_PredictorLine(m_pCurLine, m_iLine ? m_pRefLine : NULL, m_Pitch - 1, m_Bpp); - dest_buf.AppendBlock(m_pCurLine + 1, m_Pitch - 1); - m_iLine ++; - uint8_t* temp = m_pCurLine; - m_pCurLine = m_pRefLine; - m_pRefLine = temp; - } - m_LineInSize = 0; - } -} -CPDF_Ascii85Filter::CPDF_Ascii85Filter() -{ - m_State = 0; - m_CharCount = 0; -} -void CPDF_Ascii85Filter::v_FilterIn(const uint8_t* src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf) -{ - for (FX_DWORD i = 0; i < src_size; i ++) { - uint8_t byte = src_buf[i]; - if (PDF_CharType[byte] == 'W') { - continue; - } - switch (m_State) { - case 0: - if (byte >= '!' && byte <= 'u') { - int digit = byte - '!'; - m_CurDWord = digit; - m_CharCount = 1; - m_State = 1; - } else if (byte == 'z') { - int zero = 0; - dest_buf.AppendBlock(&zero, 4); - } else if (byte == '~') { - m_State = 2; - } - break; - case 1: { - if (byte >= '!' && byte <= 'u') { - int digit = byte - '!'; - m_CurDWord = m_CurDWord * 85 + digit; - m_CharCount ++; - if (m_CharCount == 5) { - for (int i = 0; i < 4; i ++) { - dest_buf.AppendByte((uint8_t)(m_CurDWord >> (3 - i) * 8)); - } - m_State = 0; - } - } else if (byte == '~') { - if (m_CharCount > 1) { - int i; - for (i = m_CharCount; i < 5; i ++) { - m_CurDWord = m_CurDWord * 85 + 84; - } - for (i = 0; i < m_CharCount - 1; i ++) { - dest_buf.AppendByte((uint8_t)(m_CurDWord >> (3 - i) * 8)); - } - } - m_State = 2; - } - break; - } - case 2: - if (byte == '>') { - ReportEOF(src_size - i - 1); - return; - } - break; - } - } -} -CPDF_AsciiHexFilter::CPDF_AsciiHexFilter() -{ - m_State = 0; -} -void CPDF_AsciiHexFilter::v_FilterIn(const uint8_t* src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf) -{ - for (FX_DWORD i = 0; i < src_size; i ++) { - uint8_t byte = src_buf[i]; - if (PDF_CharType[byte] == 'W') { - continue; - } - int digit; - if (byte >= '0' && byte <= '9') { - digit = byte - '0'; - } else if (byte >= 'a' && byte <= 'f') { - digit = byte - 'a' + 10; - } else if (byte >= 'A' && byte <= 'F') { - digit = byte - 'A' + 10; - } else { - if (m_State) { - dest_buf.AppendByte(m_FirstDigit * 16); + m_State = 0; + } + } else if (byte == '~') { + if (m_CharCount > 1) { + int i; + for (i = m_CharCount; i < 5; i++) { + m_CurDWord = m_CurDWord * 85 + 84; } - ReportEOF(src_size - i - 1); - return; - } - if (m_State == 0) { - m_FirstDigit = digit; - m_State ++; - } else { - dest_buf.AppendByte(m_FirstDigit * 16 + digit); - m_State --; - } - } -} -CPDF_RunLenFilter::CPDF_RunLenFilter() -{ - m_State = 0; - m_Count = 0; -} -void CPDF_RunLenFilter::v_FilterIn(const uint8_t* src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf) -{ - for (FX_DWORD i = 0; i < src_size; i ++) { - uint8_t byte = src_buf[i]; - switch (m_State) { - case 0: - if (byte < 128) { - m_State = 1; - m_Count = byte + 1; - } else if (byte == 128) { - ReportEOF(src_size - i - 1); - return; - } else { - m_State = 2; - m_Count = 257 - byte; - } - break; - case 1: - dest_buf.AppendByte(byte); - m_Count --; - if (m_Count == 0) { - m_State = 0; - } - break; - case 2: { - dest_buf.AppendBlock(NULL, m_Count); - FXSYS_memset(dest_buf.GetBuffer() + dest_buf.GetSize() - m_Count, byte, m_Count); - m_State = 0; - break; - } - } - } -} -CPDF_JpegFilter::CPDF_JpegFilter() -{ - m_pContext = NULL; - m_bGotHeader = FALSE; - m_pScanline = NULL; - m_iLine = 0; -} -CPDF_JpegFilter::~CPDF_JpegFilter() -{ - if (m_pScanline) { - FX_Free(m_pScanline); - } - if (m_pContext) { - CPDF_ModuleMgr::Get()->GetJpegModule()->Finish(m_pContext); - } -} -void CPDF_JpegFilter::v_FilterIn(const uint8_t* src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf) -{ - if (m_pContext == NULL) { - m_pContext = CPDF_ModuleMgr::Get()->GetJpegModule()->Start(); - } - const uint8_t* jpeg_src_buf; - FX_DWORD jpeg_src_size; - CFX_BinaryBuf temp_buf; - if (m_InputBuf.GetSize()) { - temp_buf.EstimateSize(m_InputBuf.GetSize() + src_size); - temp_buf.AppendBlock(m_InputBuf.GetBuffer(), m_InputBuf.GetSize()); - m_InputBuf.Clear(); - temp_buf.AppendBlock(src_buf, src_size); - jpeg_src_buf = temp_buf.GetBuffer(); - jpeg_src_size = temp_buf.GetSize(); + for (i = 0; i < m_CharCount - 1; i++) { + dest_buf.AppendByte((uint8_t)(m_CurDWord >> (3 - i) * 8)); + } + } + m_State = 2; + } + break; + } + case 2: + if (byte == '>') { + ReportEOF(src_size - i - 1); + return; + } + break; + } + } +} +CPDF_AsciiHexFilter::CPDF_AsciiHexFilter() { + m_State = 0; +} +void CPDF_AsciiHexFilter::v_FilterIn(const uint8_t* src_buf, + FX_DWORD src_size, + CFX_BinaryBuf& dest_buf) { + for (FX_DWORD i = 0; i < src_size; i++) { + uint8_t byte = src_buf[i]; + if (PDF_CharType[byte] == 'W') { + continue; + } + int digit; + if (byte >= '0' && byte <= '9') { + digit = byte - '0'; + } else if (byte >= 'a' && byte <= 'f') { + digit = byte - 'a' + 10; + } else if (byte >= 'A' && byte <= 'F') { + digit = byte - 'A' + 10; } else { - jpeg_src_buf = src_buf; - jpeg_src_size = src_size; - } - CPDF_ModuleMgr::Get()->GetJpegModule()->Input(m_pContext, jpeg_src_buf, jpeg_src_size); - if (!m_bGotHeader) { - int ret = CPDF_ModuleMgr::Get()->GetJpegModule()->ReadHeader(m_pContext, &m_Width, &m_Height, &m_nComps); - int left_size = CPDF_ModuleMgr::Get()->GetJpegModule()->GetAvailInput(m_pContext); - if (ret == 1) { - ReportEOF(left_size); - return; - } - if (ret == 2) { - m_InputBuf.AppendBlock(jpeg_src_buf + jpeg_src_size - left_size, left_size); - return; - } - CPDF_ModuleMgr::Get()->GetJpegModule()->StartScanline(m_pContext, 1); - m_bGotHeader = TRUE; - m_Pitch = m_Width * m_nComps; - } - if (m_pScanline == NULL) { - m_pScanline = FX_Alloc(uint8_t, m_Pitch + 4); - } - while (1) { - if (!CPDF_ModuleMgr::Get()->GetJpegModule()->ReadScanline(m_pContext, m_pScanline)) { - int left_size = CPDF_ModuleMgr::Get()->GetJpegModule()->GetAvailInput(m_pContext); - m_InputBuf.AppendBlock(jpeg_src_buf + jpeg_src_size - left_size, left_size); - break; - } - dest_buf.AppendBlock(m_pScanline, m_Pitch); - m_iLine ++; - if (m_iLine == m_Height) { - ReportEOF(CPDF_ModuleMgr::Get()->GetJpegModule()->GetAvailInput(m_pContext)); - return; - } - } -} -CPDF_FaxFilter::CPDF_FaxFilter() -{ - m_Encoding = 0; - m_bEndOfLine = FALSE; - m_bByteAlign = FALSE; - m_bBlack = FALSE; - m_nRows = 0; - m_nColumns = 0; - m_Pitch = 0; - m_pScanlineBuf = NULL; - m_pRefBuf = NULL; - m_iRow = 0; - m_InputBitPos = 0; -} -CPDF_FaxFilter::~CPDF_FaxFilter() -{ - if (m_pScanlineBuf) { - FX_Free(m_pScanlineBuf); - } - if (m_pRefBuf) { - FX_Free(m_pRefBuf); - } -} -FX_BOOL CPDF_FaxFilter::Initialize(int Encoding, int bEndOfLine, int bByteAlign, int bBlack, int nRows, int nColumns) -{ - m_Encoding = Encoding; - m_bEndOfLine = bEndOfLine; - m_bByteAlign = bByteAlign; - m_bBlack = bBlack; - m_nRows = nRows; - m_nColumns = nColumns; - m_Pitch = (m_nColumns + 7) / 8; - m_pScanlineBuf = FX_Alloc(uint8_t, m_Pitch); - m_pRefBuf = FX_Alloc(uint8_t, m_Pitch); - FXSYS_memset(m_pScanlineBuf, 0xff, m_Pitch); - FXSYS_memset(m_pRefBuf, 0xff, m_Pitch); - m_iRow = 0; - m_InputBitPos = 0; - return TRUE; -} -void CPDF_FaxFilter::v_FilterIn(const uint8_t* src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf) -{ - const uint8_t* fax_src_buf; - FX_DWORD fax_src_size; - CFX_BinaryBuf temp_buf; - int bitpos; - if (m_InputBuf.GetSize()) { - temp_buf.EstimateSize(m_InputBuf.GetSize() + src_size); - temp_buf.AppendBlock(m_InputBuf.GetBuffer(), m_InputBuf.GetSize()); - m_InputBuf.Clear(); - temp_buf.AppendBlock(src_buf, src_size); - fax_src_buf = temp_buf.GetBuffer(); - fax_src_size = temp_buf.GetSize(); - bitpos = m_InputBitPos; + if (m_State) { + dest_buf.AppendByte(m_FirstDigit * 16); + } + ReportEOF(src_size - i - 1); + return; + } + if (m_State == 0) { + m_FirstDigit = digit; + m_State++; } else { - fax_src_buf = src_buf; - fax_src_size = src_size; - bitpos = 0; - } - ProcessData(fax_src_buf, fax_src_size, bitpos, FALSE, dest_buf); - int left_bits = fax_src_size * 8 - bitpos; - m_InputBuf.AppendBlock(fax_src_buf + bitpos / 8, (left_bits + 7) / 8); - m_InputBitPos = bitpos % 8; -} -void CPDF_FaxFilter::v_FilterFinish(CFX_BinaryBuf& dest_buf) -{ - ProcessData(m_InputBuf.GetBuffer(), m_InputBuf.GetSize(), m_InputBitPos, TRUE, dest_buf); + dest_buf.AppendByte(m_FirstDigit * 16 + digit); + m_State--; + } + } +} +CPDF_RunLenFilter::CPDF_RunLenFilter() { + m_State = 0; + m_Count = 0; +} +void CPDF_RunLenFilter::v_FilterIn(const uint8_t* src_buf, + FX_DWORD src_size, + CFX_BinaryBuf& dest_buf) { + for (FX_DWORD i = 0; i < src_size; i++) { + uint8_t byte = src_buf[i]; + switch (m_State) { + case 0: + if (byte < 128) { + m_State = 1; + m_Count = byte + 1; + } else if (byte == 128) { + ReportEOF(src_size - i - 1); + return; + } else { + m_State = 2; + m_Count = 257 - byte; + } + break; + case 1: + dest_buf.AppendByte(byte); + m_Count--; + if (m_Count == 0) { + m_State = 0; + } + break; + case 2: { + dest_buf.AppendBlock(NULL, m_Count); + FXSYS_memset(dest_buf.GetBuffer() + dest_buf.GetSize() - m_Count, byte, + m_Count); + m_State = 0; + break; + } + } + } +} +CPDF_JpegFilter::CPDF_JpegFilter() { + m_pContext = NULL; + m_bGotHeader = FALSE; + m_pScanline = NULL; + m_iLine = 0; +} +CPDF_JpegFilter::~CPDF_JpegFilter() { + if (m_pScanline) { + FX_Free(m_pScanline); + } + if (m_pContext) { + CPDF_ModuleMgr::Get()->GetJpegModule()->Finish(m_pContext); + } +} +void CPDF_JpegFilter::v_FilterIn(const uint8_t* src_buf, + FX_DWORD src_size, + CFX_BinaryBuf& dest_buf) { + if (m_pContext == NULL) { + m_pContext = CPDF_ModuleMgr::Get()->GetJpegModule()->Start(); + } + const uint8_t* jpeg_src_buf; + FX_DWORD jpeg_src_size; + CFX_BinaryBuf temp_buf; + if (m_InputBuf.GetSize()) { + temp_buf.EstimateSize(m_InputBuf.GetSize() + src_size); + temp_buf.AppendBlock(m_InputBuf.GetBuffer(), m_InputBuf.GetSize()); + m_InputBuf.Clear(); + temp_buf.AppendBlock(src_buf, src_size); + jpeg_src_buf = temp_buf.GetBuffer(); + jpeg_src_size = temp_buf.GetSize(); + } else { + jpeg_src_buf = src_buf; + jpeg_src_size = src_size; + } + CPDF_ModuleMgr::Get()->GetJpegModule()->Input(m_pContext, jpeg_src_buf, + jpeg_src_size); + if (!m_bGotHeader) { + int ret = CPDF_ModuleMgr::Get()->GetJpegModule()->ReadHeader( + m_pContext, &m_Width, &m_Height, &m_nComps); + int left_size = + CPDF_ModuleMgr::Get()->GetJpegModule()->GetAvailInput(m_pContext); + if (ret == 1) { + ReportEOF(left_size); + return; + } + if (ret == 2) { + m_InputBuf.AppendBlock(jpeg_src_buf + jpeg_src_size - left_size, + left_size); + return; + } + CPDF_ModuleMgr::Get()->GetJpegModule()->StartScanline(m_pContext, 1); + m_bGotHeader = TRUE; + m_Pitch = m_Width * m_nComps; + } + if (m_pScanline == NULL) { + m_pScanline = FX_Alloc(uint8_t, m_Pitch + 4); + } + while (1) { + if (!CPDF_ModuleMgr::Get()->GetJpegModule()->ReadScanline(m_pContext, + m_pScanline)) { + int left_size = + CPDF_ModuleMgr::Get()->GetJpegModule()->GetAvailInput(m_pContext); + m_InputBuf.AppendBlock(jpeg_src_buf + jpeg_src_size - left_size, + left_size); + break; + } + dest_buf.AppendBlock(m_pScanline, m_Pitch); + m_iLine++; + if (m_iLine == m_Height) { + ReportEOF( + CPDF_ModuleMgr::Get()->GetJpegModule()->GetAvailInput(m_pContext)); + return; + } + } +} +CPDF_FaxFilter::CPDF_FaxFilter() { + m_Encoding = 0; + m_bEndOfLine = FALSE; + m_bByteAlign = FALSE; + m_bBlack = FALSE; + m_nRows = 0; + m_nColumns = 0; + m_Pitch = 0; + m_pScanlineBuf = NULL; + m_pRefBuf = NULL; + m_iRow = 0; + m_InputBitPos = 0; +} +CPDF_FaxFilter::~CPDF_FaxFilter() { + if (m_pScanlineBuf) { + FX_Free(m_pScanlineBuf); + } + if (m_pRefBuf) { + FX_Free(m_pRefBuf); + } +} +FX_BOOL CPDF_FaxFilter::Initialize(int Encoding, + int bEndOfLine, + int bByteAlign, + int bBlack, + int nRows, + int nColumns) { + m_Encoding = Encoding; + m_bEndOfLine = bEndOfLine; + m_bByteAlign = bByteAlign; + m_bBlack = bBlack; + m_nRows = nRows; + m_nColumns = nColumns; + m_Pitch = (m_nColumns + 7) / 8; + m_pScanlineBuf = FX_Alloc(uint8_t, m_Pitch); + m_pRefBuf = FX_Alloc(uint8_t, m_Pitch); + FXSYS_memset(m_pScanlineBuf, 0xff, m_Pitch); + FXSYS_memset(m_pRefBuf, 0xff, m_Pitch); + m_iRow = 0; + m_InputBitPos = 0; + return TRUE; +} +void CPDF_FaxFilter::v_FilterIn(const uint8_t* src_buf, + FX_DWORD src_size, + CFX_BinaryBuf& dest_buf) { + const uint8_t* fax_src_buf; + FX_DWORD fax_src_size; + CFX_BinaryBuf temp_buf; + int bitpos; + if (m_InputBuf.GetSize()) { + temp_buf.EstimateSize(m_InputBuf.GetSize() + src_size); + temp_buf.AppendBlock(m_InputBuf.GetBuffer(), m_InputBuf.GetSize()); + m_InputBuf.Clear(); + temp_buf.AppendBlock(src_buf, src_size); + fax_src_buf = temp_buf.GetBuffer(); + fax_src_size = temp_buf.GetSize(); + bitpos = m_InputBitPos; + } else { + fax_src_buf = src_buf; + fax_src_size = src_size; + bitpos = 0; + } + ProcessData(fax_src_buf, fax_src_size, bitpos, FALSE, dest_buf); + int left_bits = fax_src_size * 8 - bitpos; + m_InputBuf.AppendBlock(fax_src_buf + bitpos / 8, (left_bits + 7) / 8); + m_InputBitPos = bitpos % 8; +} +void CPDF_FaxFilter::v_FilterFinish(CFX_BinaryBuf& dest_buf) { + ProcessData(m_InputBuf.GetBuffer(), m_InputBuf.GetSize(), m_InputBitPos, TRUE, + dest_buf); } FX_BOOL _FaxSkipEOL(const uint8_t* src_buf, int bitsize, int& bitpos); -FX_BOOL _FaxG4GetRow(const uint8_t* src_buf, int bitsize, int& bitpos, uint8_t* dest_buf, const uint8_t* ref_buf, int columns); -FX_BOOL _FaxGet1DLine(const uint8_t* src_buf, int bitsize, int& bitpos, uint8_t* dest_buf, int columns); -void CPDF_FaxFilter::ProcessData(const uint8_t* src_buf, FX_DWORD src_size, int& bitpos, FX_BOOL bFinish, - CFX_BinaryBuf& dest_buf) -{ - int bitsize = src_size * 8; - while (1) { - if ((bitsize < bitpos + 256) && !bFinish) { - return; - } - int start_bitpos = bitpos; - FXSYS_memset(m_pScanlineBuf, 0xff, m_Pitch); - if (!ReadLine(src_buf, bitsize, bitpos)) { - bitpos = start_bitpos; - return; - } - if (m_Encoding) { - FXSYS_memcpy(m_pRefBuf, m_pScanlineBuf, m_Pitch); - } - if (m_bBlack) { - for (int i = 0; i < m_Pitch; i ++) { - m_pScanlineBuf[i] = ~m_pScanlineBuf[i]; - } - } - dest_buf.AppendBlock(m_pScanlineBuf, m_Pitch); - m_iRow ++; - if (m_iRow == m_nRows) { - ReportEOF(src_size - (bitpos + 7) / 8); - return; - } - } -} -FX_BOOL CPDF_FaxFilter::ReadLine(const uint8_t* src_buf, int bitsize, int& bitpos) -{ - if (!_FaxSkipEOL(src_buf, bitsize, bitpos)) { - return FALSE; - } - FX_BOOL ret; - if (m_Encoding < 0) { - ret = _FaxG4GetRow(src_buf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf, m_nColumns); - } else if (m_Encoding == 0) { - ret = _FaxGet1DLine(src_buf, bitsize, bitpos, m_pScanlineBuf, m_nColumns); +FX_BOOL _FaxG4GetRow(const uint8_t* src_buf, + int bitsize, + int& bitpos, + uint8_t* dest_buf, + const uint8_t* ref_buf, + int columns); +FX_BOOL _FaxGet1DLine(const uint8_t* src_buf, + int bitsize, + int& bitpos, + uint8_t* dest_buf, + int columns); +void CPDF_FaxFilter::ProcessData(const uint8_t* src_buf, + FX_DWORD src_size, + int& bitpos, + FX_BOOL bFinish, + CFX_BinaryBuf& dest_buf) { + int bitsize = src_size * 8; + while (1) { + if ((bitsize < bitpos + 256) && !bFinish) { + return; + } + int start_bitpos = bitpos; + FXSYS_memset(m_pScanlineBuf, 0xff, m_Pitch); + if (!ReadLine(src_buf, bitsize, bitpos)) { + bitpos = start_bitpos; + return; + } + if (m_Encoding) { + FXSYS_memcpy(m_pRefBuf, m_pScanlineBuf, m_Pitch); + } + if (m_bBlack) { + for (int i = 0; i < m_Pitch; i++) { + m_pScanlineBuf[i] = ~m_pScanlineBuf[i]; + } + } + dest_buf.AppendBlock(m_pScanlineBuf, m_Pitch); + m_iRow++; + if (m_iRow == m_nRows) { + ReportEOF(src_size - (bitpos + 7) / 8); + return; + } + } +} +FX_BOOL CPDF_FaxFilter::ReadLine(const uint8_t* src_buf, + int bitsize, + int& bitpos) { + if (!_FaxSkipEOL(src_buf, bitsize, bitpos)) { + return FALSE; + } + FX_BOOL ret; + if (m_Encoding < 0) { + ret = _FaxG4GetRow(src_buf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf, + m_nColumns); + } else if (m_Encoding == 0) { + ret = _FaxGet1DLine(src_buf, bitsize, bitpos, m_pScanlineBuf, m_nColumns); + } else { + if (bitpos == bitsize) { + return FALSE; + } + FX_BOOL bNext1D = src_buf[bitpos / 8] & (1 << (7 - bitpos % 8)); + bitpos++; + if (bNext1D) { + ret = _FaxGet1DLine(src_buf, bitsize, bitpos, m_pScanlineBuf, m_nColumns); } else { - if (bitpos == bitsize) { - return FALSE; - } - FX_BOOL bNext1D = src_buf[bitpos / 8] & (1 << (7 - bitpos % 8)); - bitpos ++; - if (bNext1D) { - ret = _FaxGet1DLine(src_buf, bitsize, bitpos, m_pScanlineBuf, m_nColumns); - } else { - ret = _FaxG4GetRow(src_buf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf, m_nColumns); - } - } - if (!ret) { - return FALSE; - } - if (m_bEndOfLine) - if (!_FaxSkipEOL(src_buf, bitsize, bitpos)) { - return FALSE; - } - if (m_bByteAlign) { - bitpos = (bitpos + 7) / 8 * 8; + ret = _FaxG4GetRow(src_buf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf, + m_nColumns); + } + } + if (!ret) { + return FALSE; + } + if (m_bEndOfLine) + if (!_FaxSkipEOL(src_buf, bitsize, bitpos)) { + return FALSE; } - return TRUE; + if (m_bByteAlign) { + bitpos = (bitpos + 7) / 8 * 8; + } + return TRUE; } diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp index c7d1dece25..932793218d 100644 --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp +++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp @@ -7,1282 +7,1245 @@ #include "../../../include/fpdfapi/fpdf_parser.h" #include "../../../include/fxcrt/fx_string.h" -//static +// static int CPDF_Object::s_nCurRefDepth = 0; -void CPDF_Object::Release() -{ - if (m_ObjNum) { - return; - } - Destroy(); -} -void CPDF_Object::Destroy() -{ - switch (m_Type) { - case PDFOBJ_STRING: - delete (CPDF_String*)this; - break; - case PDFOBJ_NAME: - delete (CPDF_Name*)this; - break; - case PDFOBJ_ARRAY: - delete (CPDF_Array*)this; - break; - case PDFOBJ_DICTIONARY: - delete (CPDF_Dictionary*)this; - break; - case PDFOBJ_STREAM: - delete (CPDF_Stream*)this; - break; - default: - delete this; - } -} -CFX_ByteString CPDF_Object::GetString() const -{ - switch (m_Type) { - case PDFOBJ_BOOLEAN: - return ((CPDF_Boolean*)this)->m_bValue ? "true" : "false"; - case PDFOBJ_NUMBER: - return ((CPDF_Number*)this)->GetString(); - case PDFOBJ_STRING: - return ((CPDF_String*)this)->m_String; - case PDFOBJ_NAME: - return ((CPDF_Name*)this)->m_Name; - case PDFOBJ_REFERENCE: { - CPDF_Reference* pRef = (CPDF_Reference*)(void*)this; - if (pRef->m_pObjList == NULL) { - break; - } - CPDF_Object* pObj = pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum); - if (pObj == NULL) { - return CFX_ByteString(); - } - return pObj->GetString(); - } - } - return CFX_ByteString(); -} -CFX_ByteStringC CPDF_Object::GetConstString() const -{ - switch (m_Type) { - case PDFOBJ_STRING: - return CFX_ByteStringC((const uint8_t*)((CPDF_String*)this)->m_String, ((CPDF_String*)this)->m_String.GetLength()); - case PDFOBJ_NAME: - return CFX_ByteStringC((const uint8_t*)((CPDF_Name*)this)->m_Name, ((CPDF_Name*)this)->m_Name.GetLength()); - case PDFOBJ_REFERENCE: { - CPDF_Reference* pRef = (CPDF_Reference*)(void*)this; - if (pRef->m_pObjList == NULL) { - break; - } - CPDF_Object* pObj = pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum); - if (pObj == NULL) { - return CFX_ByteStringC(); - } - return pObj->GetConstString(); - } - } - return CFX_ByteStringC(); -} -FX_FLOAT CPDF_Object::GetNumber() const -{ - switch (m_Type) { - case PDFOBJ_NUMBER: - return ((CPDF_Number*)this)->GetNumber(); - case PDFOBJ_REFERENCE: { - CPDF_Reference* pRef = (CPDF_Reference*)(void*)this; - if (pRef->m_pObjList == NULL) { - break; - } - CPDF_Object* pObj = pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum); - if (pObj == NULL) { - return 0; - } - return pObj->GetNumber(); - } +void CPDF_Object::Release() { + if (m_ObjNum) { + return; + } + Destroy(); +} +void CPDF_Object::Destroy() { + switch (m_Type) { + case PDFOBJ_STRING: + delete (CPDF_String*)this; + break; + case PDFOBJ_NAME: + delete (CPDF_Name*)this; + break; + case PDFOBJ_ARRAY: + delete (CPDF_Array*)this; + break; + case PDFOBJ_DICTIONARY: + delete (CPDF_Dictionary*)this; + break; + case PDFOBJ_STREAM: + delete (CPDF_Stream*)this; + break; + default: + delete this; + } +} +CFX_ByteString CPDF_Object::GetString() const { + switch (m_Type) { + case PDFOBJ_BOOLEAN: + return ((CPDF_Boolean*)this)->m_bValue ? "true" : "false"; + case PDFOBJ_NUMBER: + return ((CPDF_Number*)this)->GetString(); + case PDFOBJ_STRING: + return ((CPDF_String*)this)->m_String; + case PDFOBJ_NAME: + return ((CPDF_Name*)this)->m_Name; + case PDFOBJ_REFERENCE: { + CPDF_Reference* pRef = (CPDF_Reference*)(void*)this; + if (pRef->m_pObjList == NULL) { + break; + } + CPDF_Object* pObj = + pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum); + if (pObj == NULL) { + return CFX_ByteString(); + } + return pObj->GetString(); + } + } + return CFX_ByteString(); +} +CFX_ByteStringC CPDF_Object::GetConstString() const { + switch (m_Type) { + case PDFOBJ_STRING: + return CFX_ByteStringC((const uint8_t*)((CPDF_String*)this)->m_String, + ((CPDF_String*)this)->m_String.GetLength()); + case PDFOBJ_NAME: + return CFX_ByteStringC((const uint8_t*)((CPDF_Name*)this)->m_Name, + ((CPDF_Name*)this)->m_Name.GetLength()); + case PDFOBJ_REFERENCE: { + CPDF_Reference* pRef = (CPDF_Reference*)(void*)this; + if (pRef->m_pObjList == NULL) { + break; + } + CPDF_Object* pObj = + pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum); + if (pObj == NULL) { + return CFX_ByteStringC(); + } + return pObj->GetConstString(); + } + } + return CFX_ByteStringC(); +} +FX_FLOAT CPDF_Object::GetNumber() const { + switch (m_Type) { + case PDFOBJ_NUMBER: + return ((CPDF_Number*)this)->GetNumber(); + case PDFOBJ_REFERENCE: { + CPDF_Reference* pRef = (CPDF_Reference*)(void*)this; + if (pRef->m_pObjList == NULL) { + break; + } + CPDF_Object* pObj = + pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum); + if (pObj == NULL) { + return 0; + } + return pObj->GetNumber(); } - return 0; + } + return 0; } -FX_FLOAT CPDF_Object::GetNumber16() const -{ - return GetNumber(); +FX_FLOAT CPDF_Object::GetNumber16() const { + return GetNumber(); } -int CPDF_Object::GetInteger() const -{ - CFX_AutoRestorer<int> restorer(&s_nCurRefDepth); - if (++s_nCurRefDepth > OBJECT_REF_MAX_DEPTH) { - return 0; - } - switch (m_Type) { - case PDFOBJ_BOOLEAN: - return ((CPDF_Boolean*)this)->m_bValue; - case PDFOBJ_NUMBER: - return ((CPDF_Number*)this)->GetInteger(); - case PDFOBJ_REFERENCE: { - CPDF_Reference* pRef = (CPDF_Reference*)(void*)this; - PARSE_CONTEXT context; - FXSYS_memset(&context, 0, sizeof(PARSE_CONTEXT)); - if (pRef->m_pObjList == NULL) { - return 0; - } - CPDF_Object* pObj = pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum, &context); - if (pObj == NULL) { - return 0; - } - return pObj->GetInteger(); - } - } +int CPDF_Object::GetInteger() const { + CFX_AutoRestorer<int> restorer(&s_nCurRefDepth); + if (++s_nCurRefDepth > OBJECT_REF_MAX_DEPTH) { return 0; -} -CPDF_Dictionary* CPDF_Object::GetDict() const -{ - switch (m_Type) { - case PDFOBJ_DICTIONARY: - return (CPDF_Dictionary*)this; - case PDFOBJ_STREAM: - return ((CPDF_Stream*)this)->GetDict(); - case PDFOBJ_REFERENCE: { - CPDF_Reference* pRef = (CPDF_Reference*)this; - if (pRef->m_pObjList == NULL) { - break; - } - CPDF_Object* pObj = pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum); - if (pObj == NULL) { - return NULL; - } - return pObj->GetDict(); - } + } + switch (m_Type) { + case PDFOBJ_BOOLEAN: + return ((CPDF_Boolean*)this)->m_bValue; + case PDFOBJ_NUMBER: + return ((CPDF_Number*)this)->GetInteger(); + case PDFOBJ_REFERENCE: { + CPDF_Reference* pRef = (CPDF_Reference*)(void*)this; + PARSE_CONTEXT context; + FXSYS_memset(&context, 0, sizeof(PARSE_CONTEXT)); + if (pRef->m_pObjList == NULL) { + return 0; + } + CPDF_Object* pObj = + pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum, &context); + if (pObj == NULL) { + return 0; + } + return pObj->GetInteger(); + } + } + return 0; +} +CPDF_Dictionary* CPDF_Object::GetDict() const { + switch (m_Type) { + case PDFOBJ_DICTIONARY: + return (CPDF_Dictionary*)this; + case PDFOBJ_STREAM: + return ((CPDF_Stream*)this)->GetDict(); + case PDFOBJ_REFERENCE: { + CPDF_Reference* pRef = (CPDF_Reference*)this; + if (pRef->m_pObjList == NULL) { + break; + } + CPDF_Object* pObj = + pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum); + if (pObj == NULL) { + return NULL; + } + return pObj->GetDict(); } - return NULL; + } + return NULL; } -CPDF_Array* CPDF_Object::GetArray() const -{ - if (m_Type == PDFOBJ_ARRAY) - return (CPDF_Array*)this; +CPDF_Array* CPDF_Object::GetArray() const { + if (m_Type == PDFOBJ_ARRAY) + return (CPDF_Array*)this; - return NULL; -} -void CPDF_Object::SetString(const CFX_ByteString& str) -{ - ASSERT(this != NULL); - switch (m_Type) { - case PDFOBJ_BOOLEAN: - ((CPDF_Boolean*)this)->m_bValue = str == FX_BSTRC("true") ? 1 : 0; - return; - case PDFOBJ_NUMBER: - ((CPDF_Number*)this)->SetString(str); - return; - case PDFOBJ_STRING: - ((CPDF_String*)this)->m_String = str; - return; - case PDFOBJ_NAME: - ((CPDF_Name*)this)->m_Name = str; - return; - } - ASSERT(FALSE); -} -int CPDF_Object::GetDirectType() const -{ - if (m_Type != PDFOBJ_REFERENCE) { - return m_Type; - } - CPDF_Reference* pRef = (CPDF_Reference*)this; - return pRef->m_pObjList->GetIndirectType(pRef->m_RefObjNum); -} -FX_BOOL CPDF_Object::IsIdentical(CPDF_Object* pOther) const -{ - if (this == pOther) { - return TRUE; - } - if (pOther == NULL) { - return FALSE; - } - if (pOther->m_Type != m_Type) { - if (m_Type == PDFOBJ_REFERENCE && GetDirect()) { - return GetDirect()->IsIdentical(pOther); - } - if (pOther->m_Type == PDFOBJ_REFERENCE) { - return IsIdentical(pOther->GetDirect()); - } - return FALSE; - } - switch (m_Type) { - case PDFOBJ_BOOLEAN: - return (((CPDF_Boolean*)this)->Identical((CPDF_Boolean*)pOther)); - case PDFOBJ_NUMBER: - return (((CPDF_Number*)this)->Identical((CPDF_Number*)pOther)); - case PDFOBJ_STRING: - return (((CPDF_String*)this)->Identical((CPDF_String*)pOther)); - case PDFOBJ_NAME: - return (((CPDF_Name*)this)->Identical((CPDF_Name*)pOther)); - case PDFOBJ_ARRAY: - return (((CPDF_Array*)this)->Identical((CPDF_Array*)pOther)); - case PDFOBJ_DICTIONARY: - return (((CPDF_Dictionary*)this)->Identical((CPDF_Dictionary*)pOther)); - case PDFOBJ_NULL: - return TRUE; - case PDFOBJ_STREAM: - return (((CPDF_Stream*)this)->Identical((CPDF_Stream*)pOther)); - case PDFOBJ_REFERENCE: - return (((CPDF_Reference*)this)->Identical((CPDF_Reference*)pOther)); - } + return NULL; +} +void CPDF_Object::SetString(const CFX_ByteString& str) { + ASSERT(this != NULL); + switch (m_Type) { + case PDFOBJ_BOOLEAN: + ((CPDF_Boolean*)this)->m_bValue = str == FX_BSTRC("true") ? 1 : 0; + return; + case PDFOBJ_NUMBER: + ((CPDF_Number*)this)->SetString(str); + return; + case PDFOBJ_STRING: + ((CPDF_String*)this)->m_String = str; + return; + case PDFOBJ_NAME: + ((CPDF_Name*)this)->m_Name = str; + return; + } + ASSERT(FALSE); +} +int CPDF_Object::GetDirectType() const { + if (m_Type != PDFOBJ_REFERENCE) { + return m_Type; + } + CPDF_Reference* pRef = (CPDF_Reference*)this; + return pRef->m_pObjList->GetIndirectType(pRef->m_RefObjNum); +} +FX_BOOL CPDF_Object::IsIdentical(CPDF_Object* pOther) const { + if (this == pOther) { + return TRUE; + } + if (pOther == NULL) { return FALSE; -} -CPDF_Object* CPDF_Object::GetDirect() const -{ - if (m_Type != PDFOBJ_REFERENCE) { - return (CPDF_Object*)this; + } + if (pOther->m_Type != m_Type) { + if (m_Type == PDFOBJ_REFERENCE && GetDirect()) { + return GetDirect()->IsIdentical(pOther); } - CPDF_Reference* pRef = (CPDF_Reference*)(void*)this; - if (pRef->m_pObjList == NULL) { - return NULL; - } - return pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum); -} -CPDF_Object* CPDF_Object::Clone(FX_BOOL bDirect) const -{ - CFX_MapPtrToPtr visited; - return CloneInternal(bDirect, &visited); -} -CPDF_Object* CPDF_Object::CloneInternal(FX_BOOL bDirect, CFX_MapPtrToPtr* visited) const -{ - switch (m_Type) { - case PDFOBJ_BOOLEAN: - return new CPDF_Boolean(((CPDF_Boolean*)this)->m_bValue); - case PDFOBJ_NUMBER: - return new CPDF_Number(((CPDF_Number*)this)->m_bInteger, &((CPDF_Number*)this)->m_Integer); - case PDFOBJ_STRING: - return new CPDF_String(((CPDF_String*)this)->m_String, ((CPDF_String*)this)->IsHex()); - case PDFOBJ_NAME: - return new CPDF_Name(((CPDF_Name*)this)->m_Name); - case PDFOBJ_ARRAY: { - CPDF_Array* pCopy = new CPDF_Array(); - CPDF_Array* pThis = (CPDF_Array*)this; - int n = pThis->GetCount(); - for (int i = 0; i < n; i ++) { - CPDF_Object* value = (CPDF_Object*)pThis->m_Objects.GetAt(i); - pCopy->m_Objects.Add(value->CloneInternal(bDirect, visited)); - } - return pCopy; - } - case PDFOBJ_DICTIONARY: { - CPDF_Dictionary* pCopy = new CPDF_Dictionary(); - CPDF_Dictionary* pThis = (CPDF_Dictionary*)this; - FX_POSITION pos = pThis->m_Map.GetStartPosition(); - while (pos) { - CFX_ByteString key; - CPDF_Object* value; - pThis->m_Map.GetNextAssoc(pos, key, (void*&)value); - pCopy->m_Map.SetAt(key, value->CloneInternal(bDirect, visited)); - } - return pCopy; - } - case PDFOBJ_NULL: { - return new CPDF_Null; - } - case PDFOBJ_STREAM: { - CPDF_Stream* pThis = (CPDF_Stream*)this; - CPDF_StreamAcc acc; - acc.LoadAllData(pThis, TRUE); - FX_DWORD streamSize = acc.GetSize(); - CPDF_Dictionary* pDict = pThis->GetDict(); - if (pDict) - pDict = (CPDF_Dictionary*)((CPDF_Object*)pDict)->CloneInternal(bDirect, visited); - return new CPDF_Stream(acc.DetachData(), streamSize, pDict); - } - case PDFOBJ_REFERENCE: { - CPDF_Reference* pRef = (CPDF_Reference*)this; - FX_DWORD obj_num = pRef->m_RefObjNum; - if (bDirect && !visited->GetValueAt((void*)(uintptr_t)obj_num)) { - visited->SetAt((void*)(uintptr_t)obj_num, (void*)1); - if (!pRef->GetDirect()) - return nullptr; - - return pRef->GetDirect()->CloneInternal(TRUE, visited); - } - return new CPDF_Reference(pRef->m_pObjList, obj_num); - } + if (pOther->m_Type == PDFOBJ_REFERENCE) { + return IsIdentical(pOther->GetDirect()); } + return FALSE; + } + switch (m_Type) { + case PDFOBJ_BOOLEAN: + return (((CPDF_Boolean*)this)->Identical((CPDF_Boolean*)pOther)); + case PDFOBJ_NUMBER: + return (((CPDF_Number*)this)->Identical((CPDF_Number*)pOther)); + case PDFOBJ_STRING: + return (((CPDF_String*)this)->Identical((CPDF_String*)pOther)); + case PDFOBJ_NAME: + return (((CPDF_Name*)this)->Identical((CPDF_Name*)pOther)); + case PDFOBJ_ARRAY: + return (((CPDF_Array*)this)->Identical((CPDF_Array*)pOther)); + case PDFOBJ_DICTIONARY: + return (((CPDF_Dictionary*)this)->Identical((CPDF_Dictionary*)pOther)); + case PDFOBJ_NULL: + return TRUE; + case PDFOBJ_STREAM: + return (((CPDF_Stream*)this)->Identical((CPDF_Stream*)pOther)); + case PDFOBJ_REFERENCE: + return (((CPDF_Reference*)this)->Identical((CPDF_Reference*)pOther)); + } + return FALSE; +} +CPDF_Object* CPDF_Object::GetDirect() const { + if (m_Type != PDFOBJ_REFERENCE) { + return (CPDF_Object*)this; + } + CPDF_Reference* pRef = (CPDF_Reference*)(void*)this; + if (pRef->m_pObjList == NULL) { return NULL; -} -CPDF_Object* CPDF_Object::CloneRef(CPDF_IndirectObjects* pDoc) const -{ - if (m_ObjNum) { - return new CPDF_Reference(pDoc, m_ObjNum); - } - return Clone(); -} -CFX_WideString CPDF_Object::GetUnicodeText(CFX_CharMap* pCharMap) const -{ - if (m_Type == PDFOBJ_STRING) { - return PDF_DecodeText(((CPDF_String*)this)->m_String, pCharMap); - } - if (m_Type == PDFOBJ_STREAM) { - CPDF_StreamAcc stream; - stream.LoadAllData((CPDF_Stream*)this, FALSE); - CFX_WideString result = PDF_DecodeText(stream.GetData(), stream.GetSize(), pCharMap); - return result; - } - if (m_Type == PDFOBJ_NAME) { - return PDF_DecodeText(((CPDF_Name*)this)->m_Name, pCharMap); - } - return CFX_WideString(); -} -void CPDF_Object::SetUnicodeText(const FX_WCHAR* pUnicodes, int len) -{ - if (m_Type == PDFOBJ_STRING) { - ((CPDF_String*)this)->m_String = PDF_EncodeText(pUnicodes, len); - } else if (m_Type == PDFOBJ_STREAM) { - CFX_ByteString result = PDF_EncodeText(pUnicodes, len); - ((CPDF_Stream*)this)->SetData((uint8_t*)result.c_str(), result.GetLength(), FALSE, FALSE); - } + } + return pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum); +} +CPDF_Object* CPDF_Object::Clone(FX_BOOL bDirect) const { + CFX_MapPtrToPtr visited; + return CloneInternal(bDirect, &visited); +} +CPDF_Object* CPDF_Object::CloneInternal(FX_BOOL bDirect, + CFX_MapPtrToPtr* visited) const { + switch (m_Type) { + case PDFOBJ_BOOLEAN: + return new CPDF_Boolean(((CPDF_Boolean*)this)->m_bValue); + case PDFOBJ_NUMBER: + return new CPDF_Number(((CPDF_Number*)this)->m_bInteger, + &((CPDF_Number*)this)->m_Integer); + case PDFOBJ_STRING: + return new CPDF_String(((CPDF_String*)this)->m_String, + ((CPDF_String*)this)->IsHex()); + case PDFOBJ_NAME: + return new CPDF_Name(((CPDF_Name*)this)->m_Name); + case PDFOBJ_ARRAY: { + CPDF_Array* pCopy = new CPDF_Array(); + CPDF_Array* pThis = (CPDF_Array*)this; + int n = pThis->GetCount(); + for (int i = 0; i < n; i++) { + CPDF_Object* value = (CPDF_Object*)pThis->m_Objects.GetAt(i); + pCopy->m_Objects.Add(value->CloneInternal(bDirect, visited)); + } + return pCopy; + } + case PDFOBJ_DICTIONARY: { + CPDF_Dictionary* pCopy = new CPDF_Dictionary(); + CPDF_Dictionary* pThis = (CPDF_Dictionary*)this; + FX_POSITION pos = pThis->m_Map.GetStartPosition(); + while (pos) { + CFX_ByteString key; + CPDF_Object* value; + pThis->m_Map.GetNextAssoc(pos, key, (void*&)value); + pCopy->m_Map.SetAt(key, value->CloneInternal(bDirect, visited)); + } + return pCopy; + } + case PDFOBJ_NULL: { + return new CPDF_Null; + } + case PDFOBJ_STREAM: { + CPDF_Stream* pThis = (CPDF_Stream*)this; + CPDF_StreamAcc acc; + acc.LoadAllData(pThis, TRUE); + FX_DWORD streamSize = acc.GetSize(); + CPDF_Dictionary* pDict = pThis->GetDict(); + if (pDict) + pDict = (CPDF_Dictionary*)((CPDF_Object*)pDict) + ->CloneInternal(bDirect, visited); + return new CPDF_Stream(acc.DetachData(), streamSize, pDict); + } + case PDFOBJ_REFERENCE: { + CPDF_Reference* pRef = (CPDF_Reference*)this; + FX_DWORD obj_num = pRef->m_RefObjNum; + if (bDirect && !visited->GetValueAt((void*)(uintptr_t)obj_num)) { + visited->SetAt((void*)(uintptr_t)obj_num, (void*)1); + if (!pRef->GetDirect()) + return nullptr; + + return pRef->GetDirect()->CloneInternal(TRUE, visited); + } + return new CPDF_Reference(pRef->m_pObjList, obj_num); + } + } + return NULL; +} +CPDF_Object* CPDF_Object::CloneRef(CPDF_IndirectObjects* pDoc) const { + if (m_ObjNum) { + return new CPDF_Reference(pDoc, m_ObjNum); + } + return Clone(); +} +CFX_WideString CPDF_Object::GetUnicodeText(CFX_CharMap* pCharMap) const { + if (m_Type == PDFOBJ_STRING) { + return PDF_DecodeText(((CPDF_String*)this)->m_String, pCharMap); + } + if (m_Type == PDFOBJ_STREAM) { + CPDF_StreamAcc stream; + stream.LoadAllData((CPDF_Stream*)this, FALSE); + CFX_WideString result = + PDF_DecodeText(stream.GetData(), stream.GetSize(), pCharMap); + return result; + } + if (m_Type == PDFOBJ_NAME) { + return PDF_DecodeText(((CPDF_Name*)this)->m_Name, pCharMap); + } + return CFX_WideString(); +} +void CPDF_Object::SetUnicodeText(const FX_WCHAR* pUnicodes, int len) { + if (m_Type == PDFOBJ_STRING) { + ((CPDF_String*)this)->m_String = PDF_EncodeText(pUnicodes, len); + } else if (m_Type == PDFOBJ_STREAM) { + CFX_ByteString result = PDF_EncodeText(pUnicodes, len); + ((CPDF_Stream*)this) + ->SetData((uint8_t*)result.c_str(), result.GetLength(), FALSE, FALSE); + } } CPDF_Number::CPDF_Number(int value) - : CPDF_Object(PDFOBJ_NUMBER), m_bInteger(TRUE), m_Integer(value) { -} + : CPDF_Object(PDFOBJ_NUMBER), m_bInteger(TRUE), m_Integer(value) {} CPDF_Number::CPDF_Number(FX_FLOAT value) - : CPDF_Object(PDFOBJ_NUMBER), m_bInteger(FALSE), m_Float(value) { -} + : CPDF_Object(PDFOBJ_NUMBER), m_bInteger(FALSE), m_Float(value) {} CPDF_Number::CPDF_Number(FX_BOOL bInteger, void* pData) - : CPDF_Object(PDFOBJ_NUMBER), m_bInteger(bInteger), m_Integer(*(int*)pData) { -} + : CPDF_Object(PDFOBJ_NUMBER), + m_bInteger(bInteger), + m_Integer(*(int*)pData) {} -CPDF_Number::CPDF_Number(const CFX_ByteStringC& str) : CPDF_Object(PDFOBJ_NUMBER) { - FX_atonum(str, m_bInteger, &m_Integer); +CPDF_Number::CPDF_Number(const CFX_ByteStringC& str) + : CPDF_Object(PDFOBJ_NUMBER) { + FX_atonum(str, m_bInteger, &m_Integer); } -void CPDF_Number::SetString(const CFX_ByteStringC& str) -{ - FX_atonum(str, m_bInteger, &m_Integer); -} -FX_BOOL CPDF_Number::Identical(CPDF_Number* pOther) const -{ - return m_bInteger == pOther->m_bInteger && m_Integer == pOther->m_Integer; -} -CFX_ByteString CPDF_Number::GetString() const -{ - return m_bInteger ? CFX_ByteString::FormatInteger(m_Integer, FXFORMAT_SIGNED) : CFX_ByteString::FormatFloat(m_Float); -} -void CPDF_Number::SetNumber(FX_FLOAT value) -{ - m_bInteger = FALSE; - m_Float = value; -} -CPDF_String::CPDF_String(const CFX_WideString& str) : CPDF_Object(PDFOBJ_STRING), m_bHex(FALSE) { - m_String = PDF_EncodeText(str); -} -CPDF_Array::~CPDF_Array() -{ - int size = m_Objects.GetSize(); - CPDF_Object** pList = (CPDF_Object**)m_Objects.GetData(); - for (int i = 0; i < size; i ++) { - if (pList[i]) - pList[i]->Release(); - } -} -CFX_FloatRect CPDF_Array::GetRect() -{ - CFX_FloatRect rect; - if (m_Type != PDFOBJ_ARRAY || m_Objects.GetSize() != 4) { - return rect; - } - rect.left = GetNumber(0); - rect.bottom = GetNumber(1); - rect.right = GetNumber(2); - rect.top = GetNumber(3); +void CPDF_Number::SetString(const CFX_ByteStringC& str) { + FX_atonum(str, m_bInteger, &m_Integer); +} +FX_BOOL CPDF_Number::Identical(CPDF_Number* pOther) const { + return m_bInteger == pOther->m_bInteger && m_Integer == pOther->m_Integer; +} +CFX_ByteString CPDF_Number::GetString() const { + return m_bInteger ? CFX_ByteString::FormatInteger(m_Integer, FXFORMAT_SIGNED) + : CFX_ByteString::FormatFloat(m_Float); +} +void CPDF_Number::SetNumber(FX_FLOAT value) { + m_bInteger = FALSE; + m_Float = value; +} +CPDF_String::CPDF_String(const CFX_WideString& str) + : CPDF_Object(PDFOBJ_STRING), m_bHex(FALSE) { + m_String = PDF_EncodeText(str); +} +CPDF_Array::~CPDF_Array() { + int size = m_Objects.GetSize(); + CPDF_Object** pList = (CPDF_Object**)m_Objects.GetData(); + for (int i = 0; i < size; i++) { + if (pList[i]) + pList[i]->Release(); + } +} +CFX_FloatRect CPDF_Array::GetRect() { + CFX_FloatRect rect; + if (m_Type != PDFOBJ_ARRAY || m_Objects.GetSize() != 4) { return rect; -} -CFX_AffineMatrix CPDF_Array::GetMatrix() -{ - CFX_AffineMatrix matrix; - if (m_Type != PDFOBJ_ARRAY || m_Objects.GetSize() != 6) { - return matrix; - } - matrix.Set(GetNumber(0), GetNumber(1), GetNumber(2), GetNumber(3), GetNumber(4), GetNumber(5)); + } + rect.left = GetNumber(0); + rect.bottom = GetNumber(1); + rect.right = GetNumber(2); + rect.top = GetNumber(3); + return rect; +} +CFX_AffineMatrix CPDF_Array::GetMatrix() { + CFX_AffineMatrix matrix; + if (m_Type != PDFOBJ_ARRAY || m_Objects.GetSize() != 6) { return matrix; + } + matrix.Set(GetNumber(0), GetNumber(1), GetNumber(2), GetNumber(3), + GetNumber(4), GetNumber(5)); + return matrix; } -CPDF_Object* CPDF_Array::GetElement(FX_DWORD i) const -{ - if (i >= (FX_DWORD)m_Objects.GetSize()) { - return NULL; - } - return (CPDF_Object*)m_Objects.GetAt(i); -} -CPDF_Object* CPDF_Array::GetElementValue(FX_DWORD i) const -{ - if (i >= (FX_DWORD)m_Objects.GetSize()) { - return NULL; - } - return ((CPDF_Object*)m_Objects.GetAt(i))->GetDirect(); -} -CFX_ByteString CPDF_Array::GetString(FX_DWORD i) const -{ - if (i < (FX_DWORD)m_Objects.GetSize()) { - CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i); - return p->GetString(); - } - return CFX_ByteString(); -} -CFX_ByteStringC CPDF_Array::GetConstString(FX_DWORD i) const -{ - if (i < (FX_DWORD)m_Objects.GetSize()) { - CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i); - return p->GetConstString(); - } - return CFX_ByteStringC(); -} -int CPDF_Array::GetInteger(FX_DWORD i) const -{ - if (i >= (FX_DWORD)m_Objects.GetSize()) { - return 0; - } - CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i); - return p->GetInteger(); -} -FX_FLOAT CPDF_Array::GetNumber(FX_DWORD i) const -{ - if (i >= (FX_DWORD)m_Objects.GetSize()) { - return 0; - } - CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i); - return p->GetNumber(); -} -CPDF_Dictionary* CPDF_Array::GetDict(FX_DWORD i) const -{ - CPDF_Object* p = GetElementValue(i); - if (!p) { - return NULL; - } - if (p->GetType() == PDFOBJ_DICTIONARY) { - return (CPDF_Dictionary*)p; - } - if (p->GetType() == PDFOBJ_STREAM) { - return ((CPDF_Stream*)p)->GetDict(); - } +CPDF_Object* CPDF_Array::GetElement(FX_DWORD i) const { + if (i >= (FX_DWORD)m_Objects.GetSize()) { return NULL; + } + return (CPDF_Object*)m_Objects.GetAt(i); } -CPDF_Stream* CPDF_Array::GetStream(FX_DWORD i) const -{ - CPDF_Object* p = GetElementValue(i); - if (p == NULL || p->GetType() != PDFOBJ_STREAM) { - return NULL; - } - return (CPDF_Stream*)p; -} -CPDF_Array* CPDF_Array::GetArray(FX_DWORD i) const -{ - CPDF_Object* p = GetElementValue(i); - if (p == NULL || p->GetType() != PDFOBJ_ARRAY) { - return NULL; - } - return (CPDF_Array*)p; +CPDF_Object* CPDF_Array::GetElementValue(FX_DWORD i) const { + if (i >= (FX_DWORD)m_Objects.GetSize()) { + return NULL; + } + return ((CPDF_Object*)m_Objects.GetAt(i))->GetDirect(); } -void CPDF_Array::RemoveAt(FX_DWORD i) -{ - ASSERT(m_Type == PDFOBJ_ARRAY); - if (i >= (FX_DWORD)m_Objects.GetSize()) { - return; - } +CFX_ByteString CPDF_Array::GetString(FX_DWORD i) const { + if (i < (FX_DWORD)m_Objects.GetSize()) { CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i); - if (p) - p->Release(); - m_Objects.RemoveAt(i); -} -void CPDF_Array::SetAt(FX_DWORD i, CPDF_Object* pObj, CPDF_IndirectObjects* pObjs) -{ - ASSERT(m_Type == PDFOBJ_ARRAY); - ASSERT(i < (FX_DWORD)m_Objects.GetSize()); - if (i >= (FX_DWORD)m_Objects.GetSize()) { - return; - } - CPDF_Object* pOld = (CPDF_Object*)m_Objects.GetAt(i); - if (pOld) - pOld->Release(); - if (pObj->GetObjNum()) { - ASSERT(pObjs != NULL); - pObj = new CPDF_Reference(pObjs, pObj->GetObjNum()); - } - m_Objects.SetAt(i, pObj); -} -void CPDF_Array::InsertAt(FX_DWORD index, CPDF_Object* pObj, CPDF_IndirectObjects* pObjs) -{ - ASSERT(pObj != NULL); - if (pObj->GetObjNum()) { - ASSERT(pObjs != NULL); - pObj = new CPDF_Reference(pObjs, pObj->GetObjNum()); - } - m_Objects.InsertAt(index, pObj); -} -void CPDF_Array::Add(CPDF_Object* pObj, CPDF_IndirectObjects* pObjs) -{ - ASSERT(pObj != NULL); - if (pObj->GetObjNum()) { - ASSERT(pObjs != NULL); - pObj = new CPDF_Reference(pObjs, pObj->GetObjNum()); - } - m_Objects.Add(pObj); -} -void CPDF_Array::AddName(const CFX_ByteString& str) -{ - ASSERT(m_Type == PDFOBJ_ARRAY); - Add(new CPDF_Name(str)); -} -void CPDF_Array::AddString(const CFX_ByteString& str) -{ - ASSERT(m_Type == PDFOBJ_ARRAY); - Add(new CPDF_String(str)); -} -void CPDF_Array::AddInteger(int i) -{ - ASSERT(m_Type == PDFOBJ_ARRAY); - Add(new CPDF_Number(i)); -} -void CPDF_Array::AddNumber(FX_FLOAT f) -{ - ASSERT(m_Type == PDFOBJ_ARRAY); - CPDF_Number* pNumber = new CPDF_Number; - pNumber->SetNumber(f); - Add(pNumber); -} -void CPDF_Array::AddReference(CPDF_IndirectObjects* pDoc, FX_DWORD objnum) -{ - ASSERT(m_Type == PDFOBJ_ARRAY); - Add(new CPDF_Reference(pDoc, objnum)); -} -FX_BOOL CPDF_Array::Identical(CPDF_Array* pOther) const -{ - if (m_Objects.GetSize() != pOther->m_Objects.GetSize()) { - return FALSE; - } - for (int i = 0; i < m_Objects.GetSize(); i ++) - if (!((CPDF_Object*)m_Objects[i])->IsIdentical((CPDF_Object*)pOther->m_Objects[i])) { - return FALSE; - } - return TRUE; -} -CPDF_Dictionary::~CPDF_Dictionary() -{ - FX_POSITION pos = m_Map.GetStartPosition(); - while (pos) { - void* value = m_Map.GetNextValue(pos); - if (value) - ((CPDF_Object*)value)->Release(); - } -} -FX_POSITION CPDF_Dictionary::GetStartPos() const -{ - return m_Map.GetStartPosition(); -} -CPDF_Object* CPDF_Dictionary::GetNextElement(FX_POSITION& pos, CFX_ByteString& key) const -{ - if (pos == NULL) { - return NULL; - } - CPDF_Object* p; - m_Map.GetNextAssoc(pos, key, (void*&)p); - return p; + return p->GetString(); + } + return CFX_ByteString(); } -CPDF_Object* CPDF_Dictionary::GetElement(const CFX_ByteStringC& key) const -{ - CPDF_Object* p = NULL; - m_Map.Lookup(key, (void*&)p); - return p; +CFX_ByteStringC CPDF_Array::GetConstString(FX_DWORD i) const { + if (i < (FX_DWORD)m_Objects.GetSize()) { + CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i); + return p->GetConstString(); + } + return CFX_ByteStringC(); } -CPDF_Object* CPDF_Dictionary::GetElementValue(const CFX_ByteStringC& key) const -{ - CPDF_Object* p = NULL; - m_Map.Lookup(key, (void*&)p); - return p ? p->GetDirect() : NULL; -} -CFX_ByteString CPDF_Dictionary::GetString(const CFX_ByteStringC& key) const -{ - CPDF_Object* p = NULL; - m_Map.Lookup(key, (void*&)p); - if (p) { - return p->GetString(); - } - return CFX_ByteString(); -} -CFX_ByteStringC CPDF_Dictionary::GetConstString(const CFX_ByteStringC& key) const -{ - CPDF_Object* p = NULL; - m_Map.Lookup(key, (void*&)p); - if (p) { - return p->GetConstString(); - } - return CFX_ByteStringC(); -} -CFX_WideString CPDF_Dictionary::GetUnicodeText(const CFX_ByteStringC& key, CFX_CharMap* pCharMap) const -{ - CPDF_Object* p = NULL; - m_Map.Lookup(key, (void*&)p); - if (p) { - if(p->GetType() == PDFOBJ_REFERENCE) { - p = ((CPDF_Reference*)p)->GetDirect(); - if (p) { - return p->GetUnicodeText(pCharMap); - } - } else { - return p->GetUnicodeText(pCharMap); - } - } - return CFX_WideString(); -} -CFX_ByteString CPDF_Dictionary::GetString(const CFX_ByteStringC& key, const CFX_ByteStringC& def) const -{ - CPDF_Object* p = NULL; - m_Map.Lookup(key, (void*&)p); - if (p) { - return p->GetString(); - } - return CFX_ByteString(def); -} -CFX_ByteStringC CPDF_Dictionary::GetConstString(const CFX_ByteStringC& key, const CFX_ByteStringC& def) const -{ - CPDF_Object* p = NULL; - m_Map.Lookup(key, (void*&)p); - if (p) { - return p->GetConstString(); - } - return CFX_ByteStringC(def); -} -int CPDF_Dictionary::GetInteger(const CFX_ByteStringC& key) const -{ - CPDF_Object* p = NULL; - m_Map.Lookup(key, (void*&)p); - if (p) { - return p->GetInteger(); - } +int CPDF_Array::GetInteger(FX_DWORD i) const { + if (i >= (FX_DWORD)m_Objects.GetSize()) { return 0; + } + CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i); + return p->GetInteger(); } -int CPDF_Dictionary::GetInteger(const CFX_ByteStringC& key, int def) const -{ - CPDF_Object* p = NULL; - m_Map.Lookup(key, (void*&)p); - if (p) { - return p->GetInteger(); - } - return def; -} -FX_FLOAT CPDF_Dictionary::GetNumber(const CFX_ByteStringC& key) const -{ - CPDF_Object* p = NULL; - m_Map.Lookup(key, (void*&)p); - if (p) { - return p->GetNumber(); - } +FX_FLOAT CPDF_Array::GetNumber(FX_DWORD i) const { + if (i >= (FX_DWORD)m_Objects.GetSize()) { return 0; + } + CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i); + return p->GetNumber(); } -FX_BOOL CPDF_Dictionary::GetBoolean(const CFX_ByteStringC& key, FX_BOOL bDefault) const -{ - CPDF_Object* p = NULL; - m_Map.Lookup(key, (void*&)p); - if (p && p->GetType() == PDFOBJ_BOOLEAN) { - return p->GetInteger(); - } - return bDefault; -} -CPDF_Dictionary* CPDF_Dictionary::GetDict(const CFX_ByteStringC& key) const -{ - CPDF_Object* p = GetElementValue(key); - if (!p) { - return nullptr; - } - if (p->GetType() == PDFOBJ_DICTIONARY) { - return (CPDF_Dictionary*)p; - } - if (p->GetType() == PDFOBJ_STREAM) { - return ((CPDF_Stream*)p)->GetDict(); - } - return nullptr; +CPDF_Dictionary* CPDF_Array::GetDict(FX_DWORD i) const { + CPDF_Object* p = GetElementValue(i); + if (!p) { + return NULL; + } + if (p->GetType() == PDFOBJ_DICTIONARY) { + return (CPDF_Dictionary*)p; + } + if (p->GetType() == PDFOBJ_STREAM) { + return ((CPDF_Stream*)p)->GetDict(); + } + return NULL; +} +CPDF_Stream* CPDF_Array::GetStream(FX_DWORD i) const { + CPDF_Object* p = GetElementValue(i); + if (p == NULL || p->GetType() != PDFOBJ_STREAM) { + return NULL; + } + return (CPDF_Stream*)p; } -CPDF_Array* CPDF_Dictionary::GetArray(const CFX_ByteStringC& key) const -{ - CPDF_Object* p = GetElementValue(key); - if (p == NULL || p->GetType() != PDFOBJ_ARRAY) { - return NULL; - } - return (CPDF_Array*)p; +CPDF_Array* CPDF_Array::GetArray(FX_DWORD i) const { + CPDF_Object* p = GetElementValue(i); + if (p == NULL || p->GetType() != PDFOBJ_ARRAY) { + return NULL; + } + return (CPDF_Array*)p; +} +void CPDF_Array::RemoveAt(FX_DWORD i) { + ASSERT(m_Type == PDFOBJ_ARRAY); + if (i >= (FX_DWORD)m_Objects.GetSize()) { + return; + } + CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i); + if (p) + p->Release(); + m_Objects.RemoveAt(i); +} +void CPDF_Array::SetAt(FX_DWORD i, + CPDF_Object* pObj, + CPDF_IndirectObjects* pObjs) { + ASSERT(m_Type == PDFOBJ_ARRAY); + ASSERT(i < (FX_DWORD)m_Objects.GetSize()); + if (i >= (FX_DWORD)m_Objects.GetSize()) { + return; + } + CPDF_Object* pOld = (CPDF_Object*)m_Objects.GetAt(i); + if (pOld) + pOld->Release(); + if (pObj->GetObjNum()) { + ASSERT(pObjs != NULL); + pObj = new CPDF_Reference(pObjs, pObj->GetObjNum()); + } + m_Objects.SetAt(i, pObj); +} +void CPDF_Array::InsertAt(FX_DWORD index, + CPDF_Object* pObj, + CPDF_IndirectObjects* pObjs) { + ASSERT(pObj != NULL); + if (pObj->GetObjNum()) { + ASSERT(pObjs != NULL); + pObj = new CPDF_Reference(pObjs, pObj->GetObjNum()); + } + m_Objects.InsertAt(index, pObj); +} +void CPDF_Array::Add(CPDF_Object* pObj, CPDF_IndirectObjects* pObjs) { + ASSERT(pObj != NULL); + if (pObj->GetObjNum()) { + ASSERT(pObjs != NULL); + pObj = new CPDF_Reference(pObjs, pObj->GetObjNum()); + } + m_Objects.Add(pObj); +} +void CPDF_Array::AddName(const CFX_ByteString& str) { + ASSERT(m_Type == PDFOBJ_ARRAY); + Add(new CPDF_Name(str)); +} +void CPDF_Array::AddString(const CFX_ByteString& str) { + ASSERT(m_Type == PDFOBJ_ARRAY); + Add(new CPDF_String(str)); +} +void CPDF_Array::AddInteger(int i) { + ASSERT(m_Type == PDFOBJ_ARRAY); + Add(new CPDF_Number(i)); +} +void CPDF_Array::AddNumber(FX_FLOAT f) { + ASSERT(m_Type == PDFOBJ_ARRAY); + CPDF_Number* pNumber = new CPDF_Number; + pNumber->SetNumber(f); + Add(pNumber); +} +void CPDF_Array::AddReference(CPDF_IndirectObjects* pDoc, FX_DWORD objnum) { + ASSERT(m_Type == PDFOBJ_ARRAY); + Add(new CPDF_Reference(pDoc, objnum)); +} +FX_BOOL CPDF_Array::Identical(CPDF_Array* pOther) const { + if (m_Objects.GetSize() != pOther->m_Objects.GetSize()) { + return FALSE; + } + for (int i = 0; i < m_Objects.GetSize(); i++) + if (!((CPDF_Object*)m_Objects[i]) + ->IsIdentical((CPDF_Object*)pOther->m_Objects[i])) { + return FALSE; + } + return TRUE; +} +CPDF_Dictionary::~CPDF_Dictionary() { + FX_POSITION pos = m_Map.GetStartPosition(); + while (pos) { + void* value = m_Map.GetNextValue(pos); + if (value) + ((CPDF_Object*)value)->Release(); + } +} +FX_POSITION CPDF_Dictionary::GetStartPos() const { + return m_Map.GetStartPosition(); +} +CPDF_Object* CPDF_Dictionary::GetNextElement(FX_POSITION& pos, + CFX_ByteString& key) const { + if (pos == NULL) { + return NULL; + } + CPDF_Object* p; + m_Map.GetNextAssoc(pos, key, (void*&)p); + return p; +} +CPDF_Object* CPDF_Dictionary::GetElement(const CFX_ByteStringC& key) const { + CPDF_Object* p = NULL; + m_Map.Lookup(key, (void*&)p); + return p; +} +CPDF_Object* CPDF_Dictionary::GetElementValue( + const CFX_ByteStringC& key) const { + CPDF_Object* p = NULL; + m_Map.Lookup(key, (void*&)p); + return p ? p->GetDirect() : NULL; +} +CFX_ByteString CPDF_Dictionary::GetString(const CFX_ByteStringC& key) const { + CPDF_Object* p = NULL; + m_Map.Lookup(key, (void*&)p); + if (p) { + return p->GetString(); + } + return CFX_ByteString(); +} +CFX_ByteStringC CPDF_Dictionary::GetConstString( + const CFX_ByteStringC& key) const { + CPDF_Object* p = NULL; + m_Map.Lookup(key, (void*&)p); + if (p) { + return p->GetConstString(); + } + return CFX_ByteStringC(); +} +CFX_WideString CPDF_Dictionary::GetUnicodeText(const CFX_ByteStringC& key, + CFX_CharMap* pCharMap) const { + CPDF_Object* p = NULL; + m_Map.Lookup(key, (void*&)p); + if (p) { + if (p->GetType() == PDFOBJ_REFERENCE) { + p = ((CPDF_Reference*)p)->GetDirect(); + if (p) { + return p->GetUnicodeText(pCharMap); + } + } else { + return p->GetUnicodeText(pCharMap); + } + } + return CFX_WideString(); +} +CFX_ByteString CPDF_Dictionary::GetString(const CFX_ByteStringC& key, + const CFX_ByteStringC& def) const { + CPDF_Object* p = NULL; + m_Map.Lookup(key, (void*&)p); + if (p) { + return p->GetString(); + } + return CFX_ByteString(def); +} +CFX_ByteStringC CPDF_Dictionary::GetConstString( + const CFX_ByteStringC& key, + const CFX_ByteStringC& def) const { + CPDF_Object* p = NULL; + m_Map.Lookup(key, (void*&)p); + if (p) { + return p->GetConstString(); + } + return CFX_ByteStringC(def); +} +int CPDF_Dictionary::GetInteger(const CFX_ByteStringC& key) const { + CPDF_Object* p = NULL; + m_Map.Lookup(key, (void*&)p); + if (p) { + return p->GetInteger(); + } + return 0; } -CPDF_Stream* CPDF_Dictionary::GetStream(const CFX_ByteStringC& key) const -{ - CPDF_Object* p = GetElementValue(key); - if (p == NULL || p->GetType() != PDFOBJ_STREAM) { - return NULL; - } - return (CPDF_Stream*)p; -} -CFX_FloatRect CPDF_Dictionary::GetRect(const CFX_ByteStringC& key) const -{ - CFX_FloatRect rect; - CPDF_Array* pArray = GetArray(key); - if (pArray) { - rect = pArray->GetRect(); - } - return rect; +int CPDF_Dictionary::GetInteger(const CFX_ByteStringC& key, int def) const { + CPDF_Object* p = NULL; + m_Map.Lookup(key, (void*&)p); + if (p) { + return p->GetInteger(); + } + return def; } -CFX_AffineMatrix CPDF_Dictionary::GetMatrix(const CFX_ByteStringC& key) const -{ - CFX_AffineMatrix matrix; - CPDF_Array* pArray = GetArray(key); - if (pArray) { - matrix = pArray->GetMatrix(); - } - return matrix; +FX_FLOAT CPDF_Dictionary::GetNumber(const CFX_ByteStringC& key) const { + CPDF_Object* p = NULL; + m_Map.Lookup(key, (void*&)p); + if (p) { + return p->GetNumber(); + } + return 0; +} +FX_BOOL CPDF_Dictionary::GetBoolean(const CFX_ByteStringC& key, + FX_BOOL bDefault) const { + CPDF_Object* p = NULL; + m_Map.Lookup(key, (void*&)p); + if (p && p->GetType() == PDFOBJ_BOOLEAN) { + return p->GetInteger(); + } + return bDefault; } -FX_BOOL CPDF_Dictionary::KeyExist(const CFX_ByteStringC& key) const -{ - void* value; - return m_Map.Lookup(key, value); -} -void CPDF_Dictionary::SetAt(const CFX_ByteStringC& key, CPDF_Object* pObj, CPDF_IndirectObjects* pObjs) -{ - ASSERT(m_Type == PDFOBJ_DICTIONARY); - CPDF_Object* p = NULL; - m_Map.Lookup(key, (void*&)p); - if (p == pObj) { - return; - } - if (p) - p->Release(); - if (pObj) { - if (pObj->GetObjNum()) { - ASSERT(pObjs != NULL); - pObj = new CPDF_Reference(pObjs, pObj->GetObjNum()); - } - m_Map.SetAt(key, pObj); - } else { - m_Map.RemoveKey(key); - } +CPDF_Dictionary* CPDF_Dictionary::GetDict(const CFX_ByteStringC& key) const { + CPDF_Object* p = GetElementValue(key); + if (!p) { + return nullptr; + } + if (p->GetType() == PDFOBJ_DICTIONARY) { + return (CPDF_Dictionary*)p; + } + if (p->GetType() == PDFOBJ_STREAM) { + return ((CPDF_Stream*)p)->GetDict(); + } + return nullptr; +} +CPDF_Array* CPDF_Dictionary::GetArray(const CFX_ByteStringC& key) const { + CPDF_Object* p = GetElementValue(key); + if (p == NULL || p->GetType() != PDFOBJ_ARRAY) { + return NULL; + } + return (CPDF_Array*)p; } -void CPDF_Dictionary::AddValue(const CFX_ByteStringC& key, CPDF_Object* pObj) -{ - ASSERT(m_Type == PDFOBJ_DICTIONARY); - m_Map.AddValue(key, pObj); -} -void CPDF_Dictionary::RemoveAt(const CFX_ByteStringC& key) -{ - ASSERT(m_Type == PDFOBJ_DICTIONARY); - CPDF_Object* p = NULL; - m_Map.Lookup(key, (void*&)p); - if (p == NULL) { - return; - } +CPDF_Stream* CPDF_Dictionary::GetStream(const CFX_ByteStringC& key) const { + CPDF_Object* p = GetElementValue(key); + if (p == NULL || p->GetType() != PDFOBJ_STREAM) { + return NULL; + } + return (CPDF_Stream*)p; +} +CFX_FloatRect CPDF_Dictionary::GetRect(const CFX_ByteStringC& key) const { + CFX_FloatRect rect; + CPDF_Array* pArray = GetArray(key); + if (pArray) { + rect = pArray->GetRect(); + } + return rect; +} +CFX_AffineMatrix CPDF_Dictionary::GetMatrix(const CFX_ByteStringC& key) const { + CFX_AffineMatrix matrix; + CPDF_Array* pArray = GetArray(key); + if (pArray) { + matrix = pArray->GetMatrix(); + } + return matrix; +} +FX_BOOL CPDF_Dictionary::KeyExist(const CFX_ByteStringC& key) const { + void* value; + return m_Map.Lookup(key, value); +} +void CPDF_Dictionary::SetAt(const CFX_ByteStringC& key, + CPDF_Object* pObj, + CPDF_IndirectObjects* pObjs) { + ASSERT(m_Type == PDFOBJ_DICTIONARY); + CPDF_Object* p = NULL; + m_Map.Lookup(key, (void*&)p); + if (p == pObj) { + return; + } + if (p) p->Release(); - m_Map.RemoveKey(key); -} -void CPDF_Dictionary::ReplaceKey(const CFX_ByteStringC& oldkey, const CFX_ByteStringC& newkey) -{ - ASSERT(m_Type == PDFOBJ_DICTIONARY); - CPDF_Object* p = NULL; - m_Map.Lookup(oldkey, (void*&)p); - if (p == NULL) { - return; - } - m_Map.RemoveKey(oldkey); - m_Map.SetAt(newkey, p); -} -FX_BOOL CPDF_Dictionary::Identical(CPDF_Dictionary* pOther) const -{ - if (pOther == NULL) { - return FALSE; - } - if (m_Map.GetCount() != pOther->m_Map.GetCount()) { - return FALSE; - } - FX_POSITION pos = m_Map.GetStartPosition(); - while (pos) { - CFX_ByteString key; - void* value; - m_Map.GetNextAssoc(pos, key, value); - if (!value) - return FALSE; - if (!((CPDF_Object*)value)->IsIdentical(pOther->GetElement(key))) { - return FALSE; - } + if (pObj) { + if (pObj->GetObjNum()) { + ASSERT(pObjs != NULL); + pObj = new CPDF_Reference(pObjs, pObj->GetObjNum()); } - return TRUE; -} -void CPDF_Dictionary::SetAtInteger(const CFX_ByteStringC& key, int i) -{ - SetAt(key, new CPDF_Number(i)); -} -void CPDF_Dictionary::SetAtName(const CFX_ByteStringC& key, const CFX_ByteString& name) -{ - SetAt(key, new CPDF_Name(name)); -} -void CPDF_Dictionary::SetAtString(const CFX_ByteStringC& key, const CFX_ByteString& str) -{ - SetAt(key, new CPDF_String(str)); -} -void CPDF_Dictionary::SetAtReference(const CFX_ByteStringC& key, CPDF_IndirectObjects* pDoc, FX_DWORD objnum) -{ - SetAt(key, new CPDF_Reference(pDoc, objnum)); -} -void CPDF_Dictionary::AddReference(const CFX_ByteStringC& key, CPDF_IndirectObjects* pDoc, FX_DWORD objnum) -{ - AddValue(key, new CPDF_Reference(pDoc, objnum)); -} -void CPDF_Dictionary::SetAtNumber(const CFX_ByteStringC& key, FX_FLOAT f) -{ - CPDF_Number* pNumber = new CPDF_Number; - pNumber->SetNumber(f); - SetAt(key, pNumber); -} -void CPDF_Dictionary::SetAtBoolean(const CFX_ByteStringC& key, FX_BOOL bValue) -{ - SetAt(key, new CPDF_Boolean(bValue)); -} -void CPDF_Dictionary::SetAtRect(const CFX_ByteStringC& key, const CFX_FloatRect& rect) -{ - CPDF_Array* pArray = new CPDF_Array; - pArray->AddNumber(rect.left); - pArray->AddNumber(rect.bottom); - pArray->AddNumber(rect.right); - pArray->AddNumber(rect.top); - SetAt(key, pArray); -} -void CPDF_Dictionary::SetAtMatrix(const CFX_ByteStringC& key, const CFX_AffineMatrix& matrix) -{ - CPDF_Array* pArray = new CPDF_Array; - pArray->AddNumber16(matrix.a); - pArray->AddNumber16(matrix.b); - pArray->AddNumber16(matrix.c); - pArray->AddNumber16(matrix.d); - pArray->AddNumber(matrix.e); - pArray->AddNumber(matrix.f); - SetAt(key, pArray); + m_Map.SetAt(key, pObj); + } else { + m_Map.RemoveKey(key); + } +} +void CPDF_Dictionary::AddValue(const CFX_ByteStringC& key, CPDF_Object* pObj) { + ASSERT(m_Type == PDFOBJ_DICTIONARY); + m_Map.AddValue(key, pObj); +} +void CPDF_Dictionary::RemoveAt(const CFX_ByteStringC& key) { + ASSERT(m_Type == PDFOBJ_DICTIONARY); + CPDF_Object* p = NULL; + m_Map.Lookup(key, (void*&)p); + if (p == NULL) { + return; + } + p->Release(); + m_Map.RemoveKey(key); +} +void CPDF_Dictionary::ReplaceKey(const CFX_ByteStringC& oldkey, + const CFX_ByteStringC& newkey) { + ASSERT(m_Type == PDFOBJ_DICTIONARY); + CPDF_Object* p = NULL; + m_Map.Lookup(oldkey, (void*&)p); + if (p == NULL) { + return; + } + m_Map.RemoveKey(oldkey); + m_Map.SetAt(newkey, p); +} +FX_BOOL CPDF_Dictionary::Identical(CPDF_Dictionary* pOther) const { + if (pOther == NULL) { + return FALSE; + } + if (m_Map.GetCount() != pOther->m_Map.GetCount()) { + return FALSE; + } + FX_POSITION pos = m_Map.GetStartPosition(); + while (pos) { + CFX_ByteString key; + void* value; + m_Map.GetNextAssoc(pos, key, value); + if (!value) + return FALSE; + if (!((CPDF_Object*)value)->IsIdentical(pOther->GetElement(key))) { + return FALSE; + } + } + return TRUE; +} +void CPDF_Dictionary::SetAtInteger(const CFX_ByteStringC& key, int i) { + SetAt(key, new CPDF_Number(i)); +} +void CPDF_Dictionary::SetAtName(const CFX_ByteStringC& key, + const CFX_ByteString& name) { + SetAt(key, new CPDF_Name(name)); +} +void CPDF_Dictionary::SetAtString(const CFX_ByteStringC& key, + const CFX_ByteString& str) { + SetAt(key, new CPDF_String(str)); +} +void CPDF_Dictionary::SetAtReference(const CFX_ByteStringC& key, + CPDF_IndirectObjects* pDoc, + FX_DWORD objnum) { + SetAt(key, new CPDF_Reference(pDoc, objnum)); +} +void CPDF_Dictionary::AddReference(const CFX_ByteStringC& key, + CPDF_IndirectObjects* pDoc, + FX_DWORD objnum) { + AddValue(key, new CPDF_Reference(pDoc, objnum)); +} +void CPDF_Dictionary::SetAtNumber(const CFX_ByteStringC& key, FX_FLOAT f) { + CPDF_Number* pNumber = new CPDF_Number; + pNumber->SetNumber(f); + SetAt(key, pNumber); +} +void CPDF_Dictionary::SetAtBoolean(const CFX_ByteStringC& key, FX_BOOL bValue) { + SetAt(key, new CPDF_Boolean(bValue)); +} +void CPDF_Dictionary::SetAtRect(const CFX_ByteStringC& key, + const CFX_FloatRect& rect) { + CPDF_Array* pArray = new CPDF_Array; + pArray->AddNumber(rect.left); + pArray->AddNumber(rect.bottom); + pArray->AddNumber(rect.right); + pArray->AddNumber(rect.top); + SetAt(key, pArray); +} +void CPDF_Dictionary::SetAtMatrix(const CFX_ByteStringC& key, + const CFX_AffineMatrix& matrix) { + CPDF_Array* pArray = new CPDF_Array; + pArray->AddNumber16(matrix.a); + pArray->AddNumber16(matrix.b); + pArray->AddNumber16(matrix.c); + pArray->AddNumber16(matrix.d); + pArray->AddNumber(matrix.e); + pArray->AddNumber(matrix.f); + SetAt(key, pArray); } CPDF_Stream::CPDF_Stream(uint8_t* pData, FX_DWORD size, CPDF_Dictionary* pDict) : CPDF_Object(PDFOBJ_STREAM) { - m_pDict = pDict; - m_dwSize = size; - m_GenNum = (FX_DWORD) - 1; - m_pDataBuf = pData; - m_pCryptoHandler = NULL; -} -CPDF_Stream::~CPDF_Stream() -{ - if (m_GenNum == (FX_DWORD) - 1 && m_pDataBuf != NULL) { - FX_Free(m_pDataBuf); - } + m_pDict = pDict; + m_dwSize = size; + m_GenNum = (FX_DWORD)-1; + m_pDataBuf = pData; + m_pCryptoHandler = NULL; +} +CPDF_Stream::~CPDF_Stream() { + if (m_GenNum == (FX_DWORD)-1 && m_pDataBuf != NULL) { + FX_Free(m_pDataBuf); + } + if (m_pDict) { + m_pDict->Release(); + } +} +void CPDF_Stream::InitStream(CPDF_Dictionary* pDict) { + if (pDict) { if (m_pDict) { - m_pDict->Release(); + m_pDict->Release(); } + m_pDict = pDict; + } + if (m_GenNum == (FX_DWORD)-1) { + if (m_pDataBuf) { + FX_Free(m_pDataBuf); + } + } + m_GenNum = 0; + m_pFile = NULL; + m_pCryptoHandler = NULL; + m_FileOffset = 0; +} +void CPDF_Stream::InitStream(uint8_t* pData, + FX_DWORD size, + CPDF_Dictionary* pDict) { + InitStream(pDict); + m_GenNum = (FX_DWORD)-1; + m_pDataBuf = FX_Alloc(uint8_t, size); + if (pData) { + FXSYS_memcpy(m_pDataBuf, pData, size); + } + m_dwSize = size; + if (m_pDict) { + m_pDict->SetAtInteger(FX_BSTRC("Length"), size); + } } -void CPDF_Stream::InitStream(CPDF_Dictionary* pDict) -{ - if (pDict) { - if (m_pDict) { - m_pDict->Release(); - } - m_pDict = pDict; - } - if (m_GenNum == (FX_DWORD) - 1) { - if (m_pDataBuf) { - FX_Free(m_pDataBuf); - } +void CPDF_Stream::SetData(const uint8_t* pData, + FX_DWORD size, + FX_BOOL bCompressed, + FX_BOOL bKeepBuf) { + if (m_GenNum == (FX_DWORD)-1) { + if (m_pDataBuf) { + FX_Free(m_pDataBuf); } - m_GenNum = 0; - m_pFile = NULL; + } else { + m_GenNum = (FX_DWORD)-1; m_pCryptoHandler = NULL; - m_FileOffset = 0; -} -void CPDF_Stream::InitStream(uint8_t* pData, FX_DWORD size, CPDF_Dictionary* pDict) -{ - InitStream(pDict); - m_GenNum = (FX_DWORD) - 1; + } + if (bKeepBuf) { + m_pDataBuf = (uint8_t*)pData; + } else { m_pDataBuf = FX_Alloc(uint8_t, size); if (pData) { - FXSYS_memcpy(m_pDataBuf, pData, size); - } - m_dwSize = size; - if (m_pDict) { - m_pDict->SetAtInteger(FX_BSTRC("Length"), size); - } -} -void CPDF_Stream::SetData(const uint8_t* pData, FX_DWORD size, FX_BOOL bCompressed, FX_BOOL bKeepBuf) -{ - if (m_GenNum == (FX_DWORD) - 1) { - if (m_pDataBuf) { - FX_Free(m_pDataBuf); - } - } else { - m_GenNum = (FX_DWORD) - 1; - m_pCryptoHandler = NULL; - } - if (bKeepBuf) { - m_pDataBuf = (uint8_t*)pData; - } else { - m_pDataBuf = FX_Alloc(uint8_t, size); - if (pData) { - FXSYS_memcpy(m_pDataBuf, pData, size); - } - } - m_dwSize = size; - if (m_pDict == NULL) { - m_pDict = new CPDF_Dictionary; - } - m_pDict->SetAtInteger(FX_BSTRC("Length"), size); - if (!bCompressed) { - m_pDict->RemoveAt(FX_BSTRC("Filter")); - m_pDict->RemoveAt(FX_BSTRC("DecodeParms")); - } -} -FX_BOOL CPDF_Stream::ReadRawData(FX_FILESIZE offset, uint8_t* buf, FX_DWORD size) const -{ - if ((m_GenNum != (FX_DWORD) - 1) && m_pFile) { - return m_pFile->ReadBlock(buf, m_FileOffset + offset, size); - } - if (m_pDataBuf) { - FXSYS_memcpy(buf, m_pDataBuf + offset, size); - } - return TRUE; -} -void CPDF_Stream::InitStream(IFX_FileRead *pFile, CPDF_Dictionary* pDict) -{ - InitStream(pDict); - m_pFile = pFile; - m_dwSize = (FX_DWORD)pFile->GetSize(); - if (m_pDict) { - m_pDict->SetAtInteger(FX_BSTRC("Length"), m_dwSize); - } -} -FX_BOOL CPDF_Stream::Identical(CPDF_Stream* pOther) const -{ - if (!m_pDict) - return pOther->m_pDict ? FALSE : TRUE; + FXSYS_memcpy(m_pDataBuf, pData, size); + } + } + m_dwSize = size; + if (m_pDict == NULL) { + m_pDict = new CPDF_Dictionary; + } + m_pDict->SetAtInteger(FX_BSTRC("Length"), size); + if (!bCompressed) { + m_pDict->RemoveAt(FX_BSTRC("Filter")); + m_pDict->RemoveAt(FX_BSTRC("DecodeParms")); + } +} +FX_BOOL CPDF_Stream::ReadRawData(FX_FILESIZE offset, + uint8_t* buf, + FX_DWORD size) const { + if ((m_GenNum != (FX_DWORD)-1) && m_pFile) { + return m_pFile->ReadBlock(buf, m_FileOffset + offset, size); + } + if (m_pDataBuf) { + FXSYS_memcpy(buf, m_pDataBuf + offset, size); + } + return TRUE; +} +void CPDF_Stream::InitStream(IFX_FileRead* pFile, CPDF_Dictionary* pDict) { + InitStream(pDict); + m_pFile = pFile; + m_dwSize = (FX_DWORD)pFile->GetSize(); + if (m_pDict) { + m_pDict->SetAtInteger(FX_BSTRC("Length"), m_dwSize); + } +} +FX_BOOL CPDF_Stream::Identical(CPDF_Stream* pOther) const { + if (!m_pDict) + return pOther->m_pDict ? FALSE : TRUE; - if (!m_pDict->Identical(pOther->m_pDict)) { + if (!m_pDict->Identical(pOther->m_pDict)) { + return FALSE; + } + if (m_dwSize != pOther->m_dwSize) { + return FALSE; + } + if (m_GenNum != (FX_DWORD)-1 && pOther->m_GenNum != (FX_DWORD)-1) { + if (m_pFile == pOther->m_pFile && m_pFile == NULL) { + return TRUE; + } + if (!m_pFile || !pOther->m_pFile) { + return FALSE; + } + uint8_t srcBuf[1024]; + uint8_t destBuf[1024]; + FX_DWORD size = m_dwSize; + FX_DWORD srcOffset = m_FileOffset; + FX_DWORD destOffset = pOther->m_FileOffset; + if (m_pFile == pOther->m_pFile && srcOffset == destOffset) { + return TRUE; + } + while (size > 0) { + FX_DWORD actualSize = size > 1024 ? 1024 : size; + m_pFile->ReadBlock(srcBuf, srcOffset, actualSize); + pOther->m_pFile->ReadBlock(destBuf, destOffset, actualSize); + if (FXSYS_memcmp(srcBuf, destBuf, actualSize) != 0) { return FALSE; + } + size -= actualSize; + srcOffset += actualSize; + destOffset += actualSize; } - if (m_dwSize != pOther->m_dwSize) { + return TRUE; + } + if (m_GenNum != (FX_DWORD)-1 || pOther->m_GenNum != (FX_DWORD)-1) { + IFX_FileRead* pFile = NULL; + uint8_t* pBuf = NULL; + FX_DWORD offset = 0; + if (pOther->m_GenNum != (FX_DWORD)-1) { + pFile = pOther->m_pFile; + pBuf = m_pDataBuf; + offset = pOther->m_FileOffset; + } else if (m_GenNum != (FX_DWORD)-1) { + pFile = m_pFile; + pBuf = pOther->m_pDataBuf; + offset = m_FileOffset; + } + if (NULL == pBuf) { + return FALSE; + } + uint8_t srcBuf[1024]; + FX_DWORD size = m_dwSize; + while (size > 0) { + FX_DWORD actualSize = std::min(size, 1024U); + pFile->ReadBlock(srcBuf, offset, actualSize); + if (FXSYS_memcmp(srcBuf, pBuf, actualSize) != 0) { return FALSE; + } + pBuf += actualSize; + size -= actualSize; + offset += actualSize; } - if (m_GenNum != (FX_DWORD) - 1 && pOther->m_GenNum != (FX_DWORD) - 1) { - if (m_pFile == pOther->m_pFile && m_pFile == NULL) { - return TRUE; - } - if (!m_pFile || !pOther->m_pFile) { - return FALSE; - } - uint8_t srcBuf[1024]; - uint8_t destBuf[1024]; - FX_DWORD size = m_dwSize; - FX_DWORD srcOffset = m_FileOffset; - FX_DWORD destOffset = pOther->m_FileOffset; - if (m_pFile == pOther->m_pFile && srcOffset == destOffset) { - return TRUE; - } - while (size > 0) { - FX_DWORD actualSize = size > 1024 ? 1024 : size; - m_pFile->ReadBlock(srcBuf, srcOffset, actualSize); - pOther->m_pFile->ReadBlock(destBuf, destOffset, actualSize); - if (FXSYS_memcmp(srcBuf, destBuf, actualSize) != 0) { - return FALSE; - } - size -= actualSize; - srcOffset += actualSize; - destOffset += actualSize; - } - return TRUE; - } - if (m_GenNum != (FX_DWORD) - 1 || pOther->m_GenNum != (FX_DWORD) - 1) { - IFX_FileRead* pFile = NULL; - uint8_t* pBuf = NULL; - FX_DWORD offset = 0; - if (pOther->m_GenNum != (FX_DWORD) - 1) { - pFile = pOther->m_pFile; - pBuf = m_pDataBuf; - offset = pOther->m_FileOffset; - } else if (m_GenNum != (FX_DWORD) - 1) { - pFile = m_pFile; - pBuf = pOther->m_pDataBuf; - offset = m_FileOffset; - } - if (NULL == pBuf) { - return FALSE; - } - uint8_t srcBuf[1024]; - FX_DWORD size = m_dwSize; - while (size > 0) { - FX_DWORD actualSize = std::min(size, 1024U); - pFile->ReadBlock(srcBuf, offset, actualSize); - if (FXSYS_memcmp(srcBuf, pBuf, actualSize) != 0) { - return FALSE; - } - pBuf += actualSize; - size -= actualSize; - offset += actualSize; - } - return TRUE; - } - return FXSYS_memcmp(m_pDataBuf, pOther->m_pDataBuf, m_dwSize) == 0; -} -CPDF_Stream* CPDF_Stream::Clone(FX_BOOL bDirect, FPDF_LPFCloneStreamCallback lpfCallback, void* pUserData) const -{ - CPDF_Dictionary *pCloneDict = (CPDF_Dictionary*)m_pDict->Clone(bDirect); - IFX_FileStream *pFS = NULL; - if (lpfCallback) { - pFS = lpfCallback((CPDF_Stream*)this, pUserData); - } - if (!pFS) { - CPDF_StreamAcc acc; - acc.LoadAllData(this, TRUE); - FX_DWORD streamSize = acc.GetSize(); - return new CPDF_Stream(acc.DetachData(), streamSize, pCloneDict); - } - CPDF_Stream* pObj = new CPDF_Stream(NULL, 0, NULL); - CPDF_StreamFilter *pSF = GetStreamFilter(TRUE); - if (pSF) { - uint8_t* pBuf = FX_Alloc(uint8_t, 4096); - FX_DWORD dwRead; - do { - dwRead = pSF->ReadBlock(pBuf, 4096); - if (dwRead) { - pFS->WriteBlock(pBuf, dwRead); - } - } while (dwRead == 4096); - pFS->Flush(); - FX_Free(pBuf); - delete pSF; - } - pObj->InitStream((IFX_FileRead*)pFS, pCloneDict); - return pObj; -} -extern FX_BOOL PDF_DataDecode(const uint8_t* src_buf, FX_DWORD src_size, const CPDF_Dictionary* pDict, - uint8_t*& dest_buf, FX_DWORD& dest_size, CFX_ByteString& ImageEncoding, - CPDF_Dictionary*& pImageParms, FX_DWORD estimated_size, FX_BOOL bImageAcc); -CPDF_StreamAcc::CPDF_StreamAcc() -{ - m_bNewBuf = FALSE; + return TRUE; + } + return FXSYS_memcmp(m_pDataBuf, pOther->m_pDataBuf, m_dwSize) == 0; +} +CPDF_Stream* CPDF_Stream::Clone(FX_BOOL bDirect, + FPDF_LPFCloneStreamCallback lpfCallback, + void* pUserData) const { + CPDF_Dictionary* pCloneDict = (CPDF_Dictionary*)m_pDict->Clone(bDirect); + IFX_FileStream* pFS = NULL; + if (lpfCallback) { + pFS = lpfCallback((CPDF_Stream*)this, pUserData); + } + if (!pFS) { + CPDF_StreamAcc acc; + acc.LoadAllData(this, TRUE); + FX_DWORD streamSize = acc.GetSize(); + return new CPDF_Stream(acc.DetachData(), streamSize, pCloneDict); + } + CPDF_Stream* pObj = new CPDF_Stream(NULL, 0, NULL); + CPDF_StreamFilter* pSF = GetStreamFilter(TRUE); + if (pSF) { + uint8_t* pBuf = FX_Alloc(uint8_t, 4096); + FX_DWORD dwRead; + do { + dwRead = pSF->ReadBlock(pBuf, 4096); + if (dwRead) { + pFS->WriteBlock(pBuf, dwRead); + } + } while (dwRead == 4096); + pFS->Flush(); + FX_Free(pBuf); + delete pSF; + } + pObj->InitStream((IFX_FileRead*)pFS, pCloneDict); + return pObj; +} +extern FX_BOOL PDF_DataDecode(const uint8_t* src_buf, + FX_DWORD src_size, + const CPDF_Dictionary* pDict, + uint8_t*& dest_buf, + FX_DWORD& dest_size, + CFX_ByteString& ImageEncoding, + CPDF_Dictionary*& pImageParms, + FX_DWORD estimated_size, + FX_BOOL bImageAcc); +CPDF_StreamAcc::CPDF_StreamAcc() { + m_bNewBuf = FALSE; + m_pData = NULL; + m_dwSize = 0; + m_pImageParam = NULL; + m_pStream = NULL; + m_pSrcData = NULL; +} +void CPDF_StreamAcc::LoadAllData(const CPDF_Stream* pStream, + FX_BOOL bRawAccess, + FX_DWORD estimated_size, + FX_BOOL bImageAcc) { + if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM) { + return; + } + m_pStream = pStream; + if (pStream->IsMemoryBased() && + (!pStream->GetDict()->KeyExist(FX_BSTRC("Filter")) || bRawAccess)) { + m_dwSize = pStream->m_dwSize; + m_pData = (uint8_t*)pStream->m_pDataBuf; + return; + } + uint8_t* pSrcData; + FX_DWORD dwSrcSize = pStream->m_dwSize; + if (dwSrcSize == 0) { + return; + } + if (!pStream->IsMemoryBased()) { + pSrcData = m_pSrcData = FX_Alloc(uint8_t, dwSrcSize); + if (!pStream->ReadRawData(0, pSrcData, dwSrcSize)) { + return; + } + } else { + pSrcData = pStream->m_pDataBuf; + } + uint8_t* pDecryptedData; + FX_DWORD dwDecryptedSize; + if (pStream->m_pCryptoHandler) { + CFX_BinaryBuf dest_buf; + dest_buf.EstimateSize(pStream->m_pCryptoHandler->DecryptGetSize(dwSrcSize)); + void* context = pStream->m_pCryptoHandler->DecryptStart( + pStream->GetObjNum(), pStream->m_GenNum); + pStream->m_pCryptoHandler->DecryptStream(context, pSrcData, dwSrcSize, + dest_buf); + pStream->m_pCryptoHandler->DecryptFinish(context, dest_buf); + pDecryptedData = dest_buf.GetBuffer(); + dwDecryptedSize = dest_buf.GetSize(); + dest_buf.DetachBuffer(); + } else { + pDecryptedData = pSrcData; + dwDecryptedSize = dwSrcSize; + } + if (!pStream->GetDict()->KeyExist(FX_BSTRC("Filter")) || bRawAccess) { + m_pData = pDecryptedData; + m_dwSize = dwDecryptedSize; + } else { + FX_BOOL bRet = PDF_DataDecode( + pDecryptedData, dwDecryptedSize, m_pStream->GetDict(), m_pData, + m_dwSize, m_ImageDecoder, m_pImageParam, estimated_size, bImageAcc); + if (!bRet) { + m_pData = pDecryptedData; + m_dwSize = dwDecryptedSize; + } + } + if (pSrcData != pStream->m_pDataBuf && pSrcData != m_pData) { + FX_Free(pSrcData); + } + if (pDecryptedData != pSrcData && pDecryptedData != m_pData) { + FX_Free(pDecryptedData); + } + m_pSrcData = NULL; + m_bNewBuf = m_pData != pStream->m_pDataBuf; +} +CPDF_StreamAcc::~CPDF_StreamAcc() { + if (m_bNewBuf && m_pData) { + FX_Free(m_pData); + } + if (m_pSrcData) { + FX_Free(m_pSrcData); + } +} +const uint8_t* CPDF_StreamAcc::GetData() const { + if (m_bNewBuf) { + return m_pData; + } + if (!m_pStream) { + return NULL; + } + return m_pStream->m_pDataBuf; +} +FX_DWORD CPDF_StreamAcc::GetSize() const { + if (m_bNewBuf) { + return m_dwSize; + } + if (!m_pStream) { + return 0; + } + return m_pStream->m_dwSize; +} +uint8_t* CPDF_StreamAcc::DetachData() { + if (m_bNewBuf) { + uint8_t* p = m_pData; m_pData = NULL; m_dwSize = 0; - m_pImageParam = NULL; - m_pStream = NULL; - m_pSrcData = NULL; -} -void CPDF_StreamAcc::LoadAllData(const CPDF_Stream* pStream, FX_BOOL bRawAccess, FX_DWORD estimated_size, - FX_BOOL bImageAcc) -{ - if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM) { - return; - } - m_pStream = pStream; - if (pStream->IsMemoryBased() && - (!pStream->GetDict()->KeyExist(FX_BSTRC("Filter")) || bRawAccess)) { - m_dwSize = pStream->m_dwSize; - m_pData = (uint8_t*)pStream->m_pDataBuf; - return; - } - uint8_t* pSrcData; - FX_DWORD dwSrcSize = pStream->m_dwSize; - if (dwSrcSize == 0) { - return; - } - if (!pStream->IsMemoryBased()) { - pSrcData = m_pSrcData = FX_Alloc(uint8_t, dwSrcSize); - if (!pStream->ReadRawData(0, pSrcData, dwSrcSize)) { - return; - } - } else { - pSrcData = pStream->m_pDataBuf; - } - uint8_t* pDecryptedData; - FX_DWORD dwDecryptedSize; - if (pStream->m_pCryptoHandler) { - CFX_BinaryBuf dest_buf; - dest_buf.EstimateSize(pStream->m_pCryptoHandler->DecryptGetSize(dwSrcSize)); - void* context = pStream->m_pCryptoHandler->DecryptStart(pStream->GetObjNum(), pStream->m_GenNum); - pStream->m_pCryptoHandler->DecryptStream(context, pSrcData, dwSrcSize, dest_buf); - pStream->m_pCryptoHandler->DecryptFinish(context, dest_buf); - pDecryptedData = dest_buf.GetBuffer(); - dwDecryptedSize = dest_buf.GetSize(); - dest_buf.DetachBuffer(); - } else { - pDecryptedData = pSrcData; - dwDecryptedSize = dwSrcSize; - } - if (!pStream->GetDict()->KeyExist(FX_BSTRC("Filter")) || bRawAccess) { - m_pData = pDecryptedData; - m_dwSize = dwDecryptedSize; - } else { - FX_BOOL bRet = PDF_DataDecode(pDecryptedData, dwDecryptedSize, m_pStream->GetDict(), - m_pData, m_dwSize, m_ImageDecoder, m_pImageParam, estimated_size, bImageAcc); - if (!bRet) { - m_pData = pDecryptedData; - m_dwSize = dwDecryptedSize; - } - } - if (pSrcData != pStream->m_pDataBuf && pSrcData != m_pData) { - FX_Free(pSrcData); - } - if (pDecryptedData != pSrcData && pDecryptedData != m_pData) { - FX_Free(pDecryptedData); - } - m_pSrcData = NULL; - m_bNewBuf = m_pData != pStream->m_pDataBuf; -} -CPDF_StreamAcc::~CPDF_StreamAcc() -{ - if (m_bNewBuf && m_pData) { - FX_Free(m_pData); - } - if (m_pSrcData) { - FX_Free(m_pSrcData); - } -} -const uint8_t* CPDF_StreamAcc::GetData() const -{ - if (m_bNewBuf) { - return m_pData; - } - if (!m_pStream) { - return NULL; - } - return m_pStream->m_pDataBuf; -} -FX_DWORD CPDF_StreamAcc::GetSize() const -{ - if (m_bNewBuf) { - return m_dwSize; - } - if (!m_pStream) { - return 0; - } - return m_pStream->m_dwSize; -} -uint8_t* CPDF_StreamAcc::DetachData() -{ - if (m_bNewBuf) { - uint8_t* p = m_pData; - m_pData = NULL; - m_dwSize = 0; - return p; - } - uint8_t* p = FX_Alloc(uint8_t, m_dwSize); - FXSYS_memcpy(p, m_pData, m_dwSize); return p; -} -void CPDF_Reference::SetRef(CPDF_IndirectObjects* pDoc, FX_DWORD objnum) -{ - m_pObjList = pDoc; - m_RefObjNum = objnum; -} -CPDF_IndirectObjects::CPDF_IndirectObjects(CPDF_Parser* pParser) -{ - m_pParser = pParser; - m_IndirectObjs.InitHashTable(1013); - if (pParser) { - m_LastObjNum = m_pParser->GetLastObjNum(); - } else { - m_LastObjNum = 0; - } -} -CPDF_IndirectObjects::~CPDF_IndirectObjects() -{ - FX_POSITION pos = m_IndirectObjs.GetStartPosition(); - while (pos) { - void* key; - void* value; - m_IndirectObjs.GetNextAssoc(pos, key, value); - ((CPDF_Object*)value)->Destroy(); - } -} -CPDF_Object* CPDF_IndirectObjects::GetIndirectObject(FX_DWORD objnum, struct PARSE_CONTEXT* pContext) -{ - if (objnum == 0) { - return NULL; - } + } + uint8_t* p = FX_Alloc(uint8_t, m_dwSize); + FXSYS_memcpy(p, m_pData, m_dwSize); + return p; +} +void CPDF_Reference::SetRef(CPDF_IndirectObjects* pDoc, FX_DWORD objnum) { + m_pObjList = pDoc; + m_RefObjNum = objnum; +} +CPDF_IndirectObjects::CPDF_IndirectObjects(CPDF_Parser* pParser) { + m_pParser = pParser; + m_IndirectObjs.InitHashTable(1013); + if (pParser) { + m_LastObjNum = m_pParser->GetLastObjNum(); + } else { + m_LastObjNum = 0; + } +} +CPDF_IndirectObjects::~CPDF_IndirectObjects() { + FX_POSITION pos = m_IndirectObjs.GetStartPosition(); + while (pos) { + void* key; void* value; - { - if (m_IndirectObjs.Lookup((void*)(uintptr_t)objnum, value)) { - if (((CPDF_Object*)value)->GetObjNum() == -1) { - return NULL; - } - return (CPDF_Object*)value; - } - } - CPDF_Object* pObj = NULL; - if (m_pParser) { - pObj = m_pParser->ParseIndirectObject(this, objnum, pContext); - } - if (pObj == NULL) { - return NULL; - } - pObj->m_ObjNum = objnum; - if (m_LastObjNum < objnum) { - m_LastObjNum = objnum; - } - if (m_IndirectObjs.Lookup((void*)(uintptr_t)objnum, value)) { - if (value) { - ((CPDF_Object *)value)->Destroy(); - } - } - m_IndirectObjs.SetAt((void*)(uintptr_t)objnum, pObj); - return pObj; -} -int CPDF_IndirectObjects::GetIndirectType(FX_DWORD objnum) -{ - void* value; - if (m_IndirectObjs.Lookup((void*)(uintptr_t)objnum, value)) { - return ((CPDF_Object*)value)->GetType(); - } - if (m_pParser) { - PARSE_CONTEXT context; - FXSYS_memset(&context, 0, sizeof(PARSE_CONTEXT)); - context.m_Flags = PDFPARSE_TYPEONLY; - return (int)(uintptr_t)m_pParser->ParseIndirectObject(this, objnum, &context); - } - return 0; -} -FX_DWORD CPDF_IndirectObjects::AddIndirectObject(CPDF_Object* pObj) -{ - if (pObj->m_ObjNum) { - return pObj->m_ObjNum; - } - m_LastObjNum ++; - m_IndirectObjs.SetAt((void*)(uintptr_t)m_LastObjNum, pObj); - pObj->m_ObjNum = m_LastObjNum; - return m_LastObjNum; -} -void CPDF_IndirectObjects::ReleaseIndirectObject(FX_DWORD objnum) -{ - void* value; - if (!m_IndirectObjs.Lookup((void*)(uintptr_t)objnum, value)) { - return; - } - if (((CPDF_Object*)value)->GetObjNum() == -1) { - return; - } + m_IndirectObjs.GetNextAssoc(pos, key, value); ((CPDF_Object*)value)->Destroy(); - m_IndirectObjs.RemoveKey((void*)(uintptr_t)objnum); + } } -void CPDF_IndirectObjects::InsertIndirectObject(FX_DWORD objnum, CPDF_Object* pObj) -{ - if (objnum == 0 || pObj == NULL) { - return; - } - void* value = NULL; +CPDF_Object* CPDF_IndirectObjects::GetIndirectObject( + FX_DWORD objnum, + struct PARSE_CONTEXT* pContext) { + if (objnum == 0) { + return NULL; + } + void* value; + { if (m_IndirectObjs.Lookup((void*)(uintptr_t)objnum, value)) { - if (value) { - if (pObj->GetGenNum() <= ((CPDF_Object*)value)->GetGenNum()) { - return; - } - ((CPDF_Object*)value)->Destroy(); - } - } - pObj->m_ObjNum = objnum; - m_IndirectObjs.SetAt((void*)(uintptr_t)objnum, pObj); - if (m_LastObjNum < objnum) { - m_LastObjNum = objnum; - } -} -FX_DWORD CPDF_IndirectObjects::GetLastObjNum() const -{ - return m_LastObjNum; + if (((CPDF_Object*)value)->GetObjNum() == -1) { + return NULL; + } + return (CPDF_Object*)value; + } + } + CPDF_Object* pObj = NULL; + if (m_pParser) { + pObj = m_pParser->ParseIndirectObject(this, objnum, pContext); + } + if (pObj == NULL) { + return NULL; + } + pObj->m_ObjNum = objnum; + if (m_LastObjNum < objnum) { + m_LastObjNum = objnum; + } + if (m_IndirectObjs.Lookup((void*)(uintptr_t)objnum, value)) { + if (value) { + ((CPDF_Object*)value)->Destroy(); + } + } + m_IndirectObjs.SetAt((void*)(uintptr_t)objnum, pObj); + return pObj; +} +int CPDF_IndirectObjects::GetIndirectType(FX_DWORD objnum) { + void* value; + if (m_IndirectObjs.Lookup((void*)(uintptr_t)objnum, value)) { + return ((CPDF_Object*)value)->GetType(); + } + if (m_pParser) { + PARSE_CONTEXT context; + FXSYS_memset(&context, 0, sizeof(PARSE_CONTEXT)); + context.m_Flags = PDFPARSE_TYPEONLY; + return (int)(uintptr_t)m_pParser->ParseIndirectObject(this, objnum, + &context); + } + return 0; +} +FX_DWORD CPDF_IndirectObjects::AddIndirectObject(CPDF_Object* pObj) { + if (pObj->m_ObjNum) { + return pObj->m_ObjNum; + } + m_LastObjNum++; + m_IndirectObjs.SetAt((void*)(uintptr_t)m_LastObjNum, pObj); + pObj->m_ObjNum = m_LastObjNum; + return m_LastObjNum; +} +void CPDF_IndirectObjects::ReleaseIndirectObject(FX_DWORD objnum) { + void* value; + if (!m_IndirectObjs.Lookup((void*)(uintptr_t)objnum, value)) { + return; + } + if (((CPDF_Object*)value)->GetObjNum() == -1) { + return; + } + ((CPDF_Object*)value)->Destroy(); + m_IndirectObjs.RemoveKey((void*)(uintptr_t)objnum); +} +void CPDF_IndirectObjects::InsertIndirectObject(FX_DWORD objnum, + CPDF_Object* pObj) { + if (objnum == 0 || pObj == NULL) { + return; + } + void* value = NULL; + if (m_IndirectObjs.Lookup((void*)(uintptr_t)objnum, value)) { + if (value) { + if (pObj->GetGenNum() <= ((CPDF_Object*)value)->GetGenNum()) { + return; + } + ((CPDF_Object*)value)->Destroy(); + } + } + pObj->m_ObjNum = objnum; + m_IndirectObjs.SetAt((void*)(uintptr_t)objnum, pObj); + if (m_LastObjNum < objnum) { + m_LastObjNum = objnum; + } +} +FX_DWORD CPDF_IndirectObjects::GetLastObjNum() const { + return m_LastObjNum; } diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp index 854be75ad4..d0d449308d 100644 --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp +++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp @@ -13,4591 +13,4647 @@ #include "../../../include/fxcrt/fx_safe_types.h" #include "../fpdf_page/pageint.h" -FX_BOOL IsSignatureDict(const CPDF_Dictionary* pDict) -{ - CPDF_Object* pType = pDict->GetElementValue(FX_BSTRC("Type")); +FX_BOOL IsSignatureDict(const CPDF_Dictionary* pDict) { + CPDF_Object* pType = pDict->GetElementValue(FX_BSTRC("Type")); + if (!pType) { + pType = pDict->GetElementValue(FX_BSTRC("FT")); if (!pType) { - pType = pDict->GetElementValue(FX_BSTRC("FT")); - if (!pType) { - return FALSE; - } - } - if (pType->GetString() == FX_BSTRC("Sig")) { - return TRUE; + return FALSE; } - return FALSE; + } + if (pType->GetString() == FX_BSTRC("Sig")) { + return TRUE; + } + return FALSE; } -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; +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; - m_pTrailer = NULL; - m_pEncryptDict = NULL; - m_pSecurityHandler = NULL; - m_pLinearized = NULL; - m_dwFirstPageNo = 0; - m_dwXrefStartObjNum = 0; - m_bOwnFileRead = TRUE; - m_FileVersion = 0; - m_bForceUseSecurityHandler = FALSE; +CPDF_Parser::CPDF_Parser() { + m_pDocument = NULL; + m_pTrailer = NULL; + m_pEncryptDict = NULL; + m_pSecurityHandler = NULL; + m_pLinearized = NULL; + m_dwFirstPageNo = 0; + m_dwXrefStartObjNum = 0; + m_bOwnFileRead = TRUE; + m_FileVersion = 0; + m_bForceUseSecurityHandler = FALSE; } -CPDF_Parser::~CPDF_Parser() -{ - CloseParser(FALSE); +CPDF_Parser::~CPDF_Parser() { + CloseParser(FALSE); } -FX_DWORD CPDF_Parser::GetLastObjNum() -{ - FX_DWORD dwSize = m_CrossRef.GetSize(); - return dwSize ? dwSize - 1 : 0; +FX_DWORD CPDF_Parser::GetLastObjNum() { + FX_DWORD dwSize = m_CrossRef.GetSize(); + return dwSize ? dwSize - 1 : 0; } -void CPDF_Parser::SetEncryptDictionary(CPDF_Dictionary* pDict) -{ - m_pEncryptDict = pDict; +void CPDF_Parser::SetEncryptDictionary(CPDF_Dictionary* pDict) { + m_pEncryptDict = pDict; } -void CPDF_Parser::CloseParser(FX_BOOL bReParse) -{ - m_bVersionUpdated = FALSE; - if (!bReParse) { - delete m_pDocument; - m_pDocument = NULL; - } - if (m_pTrailer) { - m_pTrailer->Release(); - m_pTrailer = NULL; - } - ReleaseEncryptHandler(); - SetEncryptDictionary(NULL); - if (m_bOwnFileRead && m_Syntax.m_pFileAccess) { - m_Syntax.m_pFileAccess->Release(); - m_Syntax.m_pFileAccess = NULL; - } - FX_POSITION pos = m_ObjectStreamMap.GetStartPosition(); - while (pos) { - void* objnum; - CPDF_StreamAcc* pStream; - m_ObjectStreamMap.GetNextAssoc(pos, objnum, (void*&)pStream); - delete pStream; - } - m_ObjectStreamMap.RemoveAll(); - m_SortedOffset.RemoveAll(); - m_CrossRef.RemoveAll(); - m_V5Type.RemoveAll(); - m_ObjVersion.RemoveAll(); - int32_t iLen = m_Trailers.GetSize(); - for (int32_t i = 0; i < iLen; ++i) { - if (CPDF_Dictionary* trailer = m_Trailers.GetAt(i)) - trailer->Release(); - } - m_Trailers.RemoveAll(); - if (m_pLinearized) { - m_pLinearized->Release(); - m_pLinearized = NULL; - } +void CPDF_Parser::CloseParser(FX_BOOL bReParse) { + m_bVersionUpdated = FALSE; + if (!bReParse) { + delete m_pDocument; + m_pDocument = NULL; + } + if (m_pTrailer) { + m_pTrailer->Release(); + m_pTrailer = NULL; + } + ReleaseEncryptHandler(); + SetEncryptDictionary(NULL); + if (m_bOwnFileRead && m_Syntax.m_pFileAccess) { + m_Syntax.m_pFileAccess->Release(); + m_Syntax.m_pFileAccess = NULL; + } + FX_POSITION pos = m_ObjectStreamMap.GetStartPosition(); + while (pos) { + void* objnum; + CPDF_StreamAcc* pStream; + m_ObjectStreamMap.GetNextAssoc(pos, objnum, (void*&)pStream); + delete pStream; + } + m_ObjectStreamMap.RemoveAll(); + m_SortedOffset.RemoveAll(); + m_CrossRef.RemoveAll(); + m_V5Type.RemoveAll(); + m_ObjVersion.RemoveAll(); + int32_t iLen = m_Trailers.GetSize(); + for (int32_t i = 0; i < iLen; ++i) { + if (CPDF_Dictionary* trailer = m_Trailers.GetAt(i)) + trailer->Release(); + } + m_Trailers.RemoveAll(); + if (m_pLinearized) { + m_pLinearized->Release(); + 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; +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; } -FX_DWORD CPDF_Parser::StartParse(const FX_CHAR* filename, FX_BOOL bReParse) -{ - IFX_FileRead* pFileAccess = FX_CreateFileRead(filename); - if (!pFileAccess) { - return PDFPARSE_ERROR_FILE; - } - return StartParse(pFileAccess, bReParse); +FX_DWORD CPDF_Parser::StartParse(const FX_CHAR* filename, FX_BOOL bReParse) { + IFX_FileRead* pFileAccess = FX_CreateFileRead(filename); + if (!pFileAccess) { + return PDFPARSE_ERROR_FILE; + } + return StartParse(pFileAccess, bReParse); } -FX_DWORD CPDF_Parser::StartParse(const FX_WCHAR* filename, FX_BOOL bReParse) -{ - IFX_FileRead* pFileAccess = FX_CreateFileRead(filename); - if (!pFileAccess) { - return PDFPARSE_ERROR_FILE; - } - return StartParse(pFileAccess, bReParse); +FX_DWORD CPDF_Parser::StartParse(const FX_WCHAR* filename, FX_BOOL bReParse) { + IFX_FileRead* pFileAccess = FX_CreateFileRead(filename); + if (!pFileAccess) { + return PDFPARSE_ERROR_FILE; + } + return StartParse(pFileAccess, bReParse); } CPDF_SecurityHandler* FPDF_CreateStandardSecurityHandler(); CPDF_SecurityHandler* FPDF_CreatePubKeyHandler(void*); -FX_DWORD CPDF_Parser::StartParse(IFX_FileRead* pFileAccess, FX_BOOL bReParse, FX_BOOL bOwnFileRead) -{ - CloseParser(bReParse); - m_bXRefStream = FALSE; - m_LastXRefOffset = 0; - m_bOwnFileRead = bOwnFileRead; - int32_t offset = GetHeaderOffset(pFileAccess); - if (offset == -1) { - if (bOwnFileRead && pFileAccess) { - pFileAccess->Release(); - } - return PDFPARSE_ERROR_FORMAT; - } - m_Syntax.InitParser(pFileAccess, offset); - uint8_t ch; - if (!m_Syntax.GetCharAt(5, ch)) { - return PDFPARSE_ERROR_FORMAT; - } - if (ch >= '0' && ch <= '9') { - m_FileVersion = (ch - '0') * 10; - } - if (!m_Syntax.GetCharAt(7, ch)) { - return PDFPARSE_ERROR_FORMAT; +FX_DWORD CPDF_Parser::StartParse(IFX_FileRead* pFileAccess, + FX_BOOL bReParse, + FX_BOOL bOwnFileRead) { + CloseParser(bReParse); + m_bXRefStream = FALSE; + m_LastXRefOffset = 0; + m_bOwnFileRead = bOwnFileRead; + int32_t offset = GetHeaderOffset(pFileAccess); + if (offset == -1) { + if (bOwnFileRead && pFileAccess) { + pFileAccess->Release(); + } + return PDFPARSE_ERROR_FORMAT; + } + m_Syntax.InitParser(pFileAccess, offset); + uint8_t ch; + if (!m_Syntax.GetCharAt(5, ch)) { + return PDFPARSE_ERROR_FORMAT; + } + if (ch >= '0' && ch <= '9') { + m_FileVersion = (ch - '0') * 10; + } + if (!m_Syntax.GetCharAt(7, ch)) { + return PDFPARSE_ERROR_FORMAT; + } + if (ch >= '0' && ch <= '9') { + m_FileVersion += ch - '0'; + } + if (m_Syntax.m_FileLen < m_Syntax.m_HeaderOffset + 9) { + return PDFPARSE_ERROR_FORMAT; + } + m_Syntax.RestorePos(m_Syntax.m_FileLen - m_Syntax.m_HeaderOffset - 9); + if (!bReParse) { + m_pDocument = new CPDF_Document(this); + } + FX_BOOL bXRefRebuilt = FALSE; + if (m_Syntax.SearchWord(FX_BSTRC("startxref"), TRUE, FALSE, 4096)) { + FX_FILESIZE startxref_offset = m_Syntax.SavePos(); + void* pResult = FXSYS_bsearch(&startxref_offset, m_SortedOffset.GetData(), + m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), + _CompareFileSize); + if (pResult == NULL) { + m_SortedOffset.Add(startxref_offset); } - if (ch >= '0' && ch <= '9') { - m_FileVersion += ch - '0'; + m_Syntax.GetKeyword(); + FX_BOOL bNumber; + CFX_ByteString xrefpos_str = m_Syntax.GetNextWord(bNumber); + if (!bNumber) { + return PDFPARSE_ERROR_FORMAT; } - if (m_Syntax.m_FileLen < m_Syntax.m_HeaderOffset + 9) { + m_LastXRefOffset = (FX_FILESIZE)FXSYS_atoi64(xrefpos_str); + if (!LoadAllCrossRefV4(m_LastXRefOffset) && + !LoadAllCrossRefV5(m_LastXRefOffset)) { + if (!RebuildCrossRef()) { return PDFPARSE_ERROR_FORMAT; + } + bXRefRebuilt = TRUE; + m_LastXRefOffset = 0; + } + } else { + if (!RebuildCrossRef()) { + return PDFPARSE_ERROR_FORMAT; + } + bXRefRebuilt = TRUE; + } + FX_DWORD dwRet = SetEncryptHandler(); + if (dwRet != PDFPARSE_ERROR_SUCCESS) { + return dwRet; + } + m_pDocument->LoadDoc(); + if (m_pDocument->GetRoot() == NULL || m_pDocument->GetPageCount() == 0) { + if (bXRefRebuilt) { + return PDFPARSE_ERROR_FORMAT; } - m_Syntax.RestorePos(m_Syntax.m_FileLen - m_Syntax.m_HeaderOffset - 9); - if (!bReParse) { - m_pDocument = new CPDF_Document(this); - } - FX_BOOL bXRefRebuilt = FALSE; - if (m_Syntax.SearchWord(FX_BSTRC("startxref"), TRUE, FALSE, 4096)) { - FX_FILESIZE startxref_offset = m_Syntax.SavePos(); - void* pResult = FXSYS_bsearch(&startxref_offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); - if (pResult == NULL) { - m_SortedOffset.Add(startxref_offset); - } - m_Syntax.GetKeyword(); - FX_BOOL bNumber; - CFX_ByteString xrefpos_str = m_Syntax.GetNextWord(bNumber); - if (!bNumber) { - return PDFPARSE_ERROR_FORMAT; - } - m_LastXRefOffset = (FX_FILESIZE)FXSYS_atoi64(xrefpos_str); - if (!LoadAllCrossRefV4(m_LastXRefOffset) && !LoadAllCrossRefV5(m_LastXRefOffset)) { - if (!RebuildCrossRef()) { - return PDFPARSE_ERROR_FORMAT; - } - bXRefRebuilt = TRUE; - m_LastXRefOffset = 0; - } - } else { - if (!RebuildCrossRef()) { - return PDFPARSE_ERROR_FORMAT; - } - bXRefRebuilt = TRUE; + ReleaseEncryptHandler(); + if (!RebuildCrossRef()) { + return PDFPARSE_ERROR_FORMAT; } - FX_DWORD dwRet = SetEncryptHandler(); + dwRet = SetEncryptHandler(); if (dwRet != PDFPARSE_ERROR_SUCCESS) { - return dwRet; + return dwRet; } m_pDocument->LoadDoc(); - if (m_pDocument->GetRoot() == NULL || m_pDocument->GetPageCount() == 0) { - if (bXRefRebuilt) { - return PDFPARSE_ERROR_FORMAT; - } - ReleaseEncryptHandler(); - if (!RebuildCrossRef()) { - return PDFPARSE_ERROR_FORMAT; - } - dwRet = SetEncryptHandler(); - if (dwRet != PDFPARSE_ERROR_SUCCESS) { - return dwRet; - } - m_pDocument->LoadDoc(); - if (m_pDocument->GetRoot() == NULL) { - return PDFPARSE_ERROR_FORMAT; - } - } - FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); - FX_DWORD RootObjNum = GetRootObjNum(); + if (m_pDocument->GetRoot() == NULL) { + return PDFPARSE_ERROR_FORMAT; + } + } + FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(), + sizeof(FX_FILESIZE), _CompareFileSize); + FX_DWORD RootObjNum = GetRootObjNum(); + if (RootObjNum == 0) { + ReleaseEncryptHandler(); + RebuildCrossRef(); + RootObjNum = GetRootObjNum(); if (RootObjNum == 0) { - ReleaseEncryptHandler(); - RebuildCrossRef(); - RootObjNum = GetRootObjNum(); - if (RootObjNum == 0) { - return PDFPARSE_ERROR_FORMAT; - } - dwRet = SetEncryptHandler(); - if (dwRet != PDFPARSE_ERROR_SUCCESS) { - return dwRet; - } - } - if (m_pSecurityHandler && !m_pSecurityHandler->IsMetadataEncrypted()) { - CPDF_Reference* pMetadata = (CPDF_Reference*)m_pDocument->GetRoot()->GetElement(FX_BSTRC("Metadata")); - if (pMetadata && pMetadata->GetType() == PDFOBJ_REFERENCE) { - m_Syntax.m_MetadataObjnum = pMetadata->GetRefObjNum(); - } + return PDFPARSE_ERROR_FORMAT; } - return PDFPARSE_ERROR_SUCCESS; + dwRet = SetEncryptHandler(); + if (dwRet != PDFPARSE_ERROR_SUCCESS) { + return dwRet; + } + } + if (m_pSecurityHandler && !m_pSecurityHandler->IsMetadataEncrypted()) { + CPDF_Reference* pMetadata = + (CPDF_Reference*)m_pDocument->GetRoot()->GetElement( + FX_BSTRC("Metadata")); + if (pMetadata && pMetadata->GetType() == PDFOBJ_REFERENCE) { + m_Syntax.m_MetadataObjnum = pMetadata->GetRefObjNum(); + } + } + return PDFPARSE_ERROR_SUCCESS; } -FX_DWORD CPDF_Parser::SetEncryptHandler() -{ - ReleaseEncryptHandler(); - SetEncryptDictionary(NULL); - if (m_pTrailer == NULL) { - return PDFPARSE_ERROR_FORMAT; - } - CPDF_Object* pEncryptObj = m_pTrailer->GetElement(FX_BSTRC("Encrypt")); - if (pEncryptObj) { - if (pEncryptObj->GetType() == PDFOBJ_DICTIONARY) { - SetEncryptDictionary((CPDF_Dictionary*)pEncryptObj); - } else if (pEncryptObj->GetType() == PDFOBJ_REFERENCE) { - pEncryptObj = m_pDocument->GetIndirectObject(((CPDF_Reference*)pEncryptObj)->GetRefObjNum()); - if (pEncryptObj) { - SetEncryptDictionary(pEncryptObj->GetDict()); - } - } - } - if (m_bForceUseSecurityHandler) { - FX_DWORD err = PDFPARSE_ERROR_HANDLER; - if (m_pSecurityHandler == NULL) { - return PDFPARSE_ERROR_HANDLER; - } - if (!m_pSecurityHandler->OnInit(this, m_pEncryptDict)) { - return err; - } - CPDF_CryptoHandler* pCryptoHandler = m_pSecurityHandler->CreateCryptoHandler(); - if (!pCryptoHandler->Init(m_pEncryptDict, m_pSecurityHandler)) { - delete pCryptoHandler; - pCryptoHandler = NULL; - return PDFPARSE_ERROR_HANDLER; - } - m_Syntax.SetEncrypt(pCryptoHandler); - } else if (m_pEncryptDict) { - CFX_ByteString filter = m_pEncryptDict->GetString(FX_BSTRC("Filter")); - CPDF_SecurityHandler* pSecurityHandler = NULL; - FX_DWORD err = PDFPARSE_ERROR_HANDLER; - if (filter == FX_BSTRC("Standard")) { - pSecurityHandler = FPDF_CreateStandardSecurityHandler(); - err = PDFPARSE_ERROR_PASSWORD; - } - if (pSecurityHandler == NULL) { - return PDFPARSE_ERROR_HANDLER; - } - if (!pSecurityHandler->OnInit(this, m_pEncryptDict)) { - delete pSecurityHandler; - pSecurityHandler = NULL; - return err; - } - m_pSecurityHandler = pSecurityHandler; - CPDF_CryptoHandler* pCryptoHandler = pSecurityHandler->CreateCryptoHandler(); - if (!pCryptoHandler->Init(m_pEncryptDict, m_pSecurityHandler)) { - delete pCryptoHandler; - pCryptoHandler = NULL; - return PDFPARSE_ERROR_HANDLER; - } - m_Syntax.SetEncrypt(pCryptoHandler); +FX_DWORD CPDF_Parser::SetEncryptHandler() { + ReleaseEncryptHandler(); + SetEncryptDictionary(NULL); + if (m_pTrailer == NULL) { + return PDFPARSE_ERROR_FORMAT; + } + CPDF_Object* pEncryptObj = m_pTrailer->GetElement(FX_BSTRC("Encrypt")); + if (pEncryptObj) { + if (pEncryptObj->GetType() == PDFOBJ_DICTIONARY) { + SetEncryptDictionary((CPDF_Dictionary*)pEncryptObj); + } else if (pEncryptObj->GetType() == PDFOBJ_REFERENCE) { + pEncryptObj = m_pDocument->GetIndirectObject( + ((CPDF_Reference*)pEncryptObj)->GetRefObjNum()); + if (pEncryptObj) { + SetEncryptDictionary(pEncryptObj->GetDict()); + } + } + } + if (m_bForceUseSecurityHandler) { + FX_DWORD err = PDFPARSE_ERROR_HANDLER; + if (m_pSecurityHandler == NULL) { + return PDFPARSE_ERROR_HANDLER; + } + if (!m_pSecurityHandler->OnInit(this, m_pEncryptDict)) { + return err; + } + CPDF_CryptoHandler* pCryptoHandler = + m_pSecurityHandler->CreateCryptoHandler(); + if (!pCryptoHandler->Init(m_pEncryptDict, m_pSecurityHandler)) { + delete pCryptoHandler; + pCryptoHandler = NULL; + return PDFPARSE_ERROR_HANDLER; + } + m_Syntax.SetEncrypt(pCryptoHandler); + } else if (m_pEncryptDict) { + CFX_ByteString filter = m_pEncryptDict->GetString(FX_BSTRC("Filter")); + CPDF_SecurityHandler* pSecurityHandler = NULL; + FX_DWORD err = PDFPARSE_ERROR_HANDLER; + if (filter == FX_BSTRC("Standard")) { + pSecurityHandler = FPDF_CreateStandardSecurityHandler(); + err = PDFPARSE_ERROR_PASSWORD; + } + if (pSecurityHandler == NULL) { + return PDFPARSE_ERROR_HANDLER; + } + if (!pSecurityHandler->OnInit(this, m_pEncryptDict)) { + delete pSecurityHandler; + pSecurityHandler = NULL; + return err; } - return PDFPARSE_ERROR_SUCCESS; + m_pSecurityHandler = pSecurityHandler; + CPDF_CryptoHandler* pCryptoHandler = + pSecurityHandler->CreateCryptoHandler(); + if (!pCryptoHandler->Init(m_pEncryptDict, m_pSecurityHandler)) { + delete pCryptoHandler; + pCryptoHandler = NULL; + return PDFPARSE_ERROR_HANDLER; + } + m_Syntax.SetEncrypt(pCryptoHandler); + } + return PDFPARSE_ERROR_SUCCESS; } -void CPDF_Parser::ReleaseEncryptHandler() -{ - delete m_Syntax.m_pCryptoHandler; - m_Syntax.m_pCryptoHandler = NULL; - if (!m_bForceUseSecurityHandler) { - delete m_pSecurityHandler; - m_pSecurityHandler = NULL; - } +void CPDF_Parser::ReleaseEncryptHandler() { + delete m_Syntax.m_pCryptoHandler; + m_Syntax.m_pCryptoHandler = NULL; + if (!m_bForceUseSecurityHandler) { + delete m_pSecurityHandler; + m_pSecurityHandler = NULL; + } } -FX_FILESIZE CPDF_Parser::GetObjectOffset(FX_DWORD objnum) -{ - if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) { - return 0; - } - if (m_V5Type[objnum] == 1) { - return m_CrossRef[objnum]; - } - if (m_V5Type[objnum] == 2) { - return m_CrossRef[(int32_t)m_CrossRef[objnum]]; - } +FX_FILESIZE CPDF_Parser::GetObjectOffset(FX_DWORD objnum) { + if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) { return 0; + } + if (m_V5Type[objnum] == 1) { + return m_CrossRef[objnum]; + } + if (m_V5Type[objnum] == 2) { + return m_CrossRef[(int32_t)m_CrossRef[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(); - } +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; +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; - } - m_pTrailer = LoadTrailerV4(); - if (m_pTrailer == NULL) { - return FALSE; - } - int32_t xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size")); - if (xrefsize <= 0 || xrefsize > (1 << 20)) { - return FALSE; - } - m_CrossRef.SetSize(xrefsize); - m_V5Type.SetSize(xrefsize); - CFX_FileSizeArray CrossRefList, XRefStreamList; - CrossRefList.Add(xrefpos); - XRefStreamList.Add(GetDirectInteger(m_pTrailer, FX_BSTRC("XRefStm"))); - if (!CheckDirectType(m_pTrailer, FX_BSTRC("Prev"), PDFOBJ_NUMBER)) { - return FALSE; - } - FX_FILESIZE newxrefpos = GetDirectInteger(m_pTrailer, FX_BSTRC("Prev")); +FX_BOOL CPDF_Parser::LoadAllCrossRefV4(FX_FILESIZE xrefpos) { + if (!LoadCrossRefV4(xrefpos, 0, TRUE, FALSE)) { + return FALSE; + } + m_pTrailer = LoadTrailerV4(); + if (m_pTrailer == NULL) { + return FALSE; + } + int32_t xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size")); + if (xrefsize <= 0 || xrefsize > (1 << 20)) { + return FALSE; + } + m_CrossRef.SetSize(xrefsize); + m_V5Type.SetSize(xrefsize); + CFX_FileSizeArray CrossRefList, XRefStreamList; + CrossRefList.Add(xrefpos); + XRefStreamList.Add(GetDirectInteger(m_pTrailer, FX_BSTRC("XRefStm"))); + if (!CheckDirectType(m_pTrailer, FX_BSTRC("Prev"), PDFOBJ_NUMBER)) { + return FALSE; + } + FX_FILESIZE newxrefpos = GetDirectInteger(m_pTrailer, FX_BSTRC("Prev")); + if (newxrefpos == xrefpos) { + return FALSE; + } + xrefpos = newxrefpos; + while (xrefpos) { + CrossRefList.InsertAt(0, xrefpos); + LoadCrossRefV4(xrefpos, 0, TRUE, FALSE); + CPDF_Dictionary* pDict = LoadTrailerV4(); + if (pDict == NULL) { + return FALSE; + } + if (!CheckDirectType(pDict, FX_BSTRC("Prev"), PDFOBJ_NUMBER)) { + pDict->Release(); + return FALSE; + } + newxrefpos = GetDirectInteger(pDict, FX_BSTRC("Prev")); if (newxrefpos == xrefpos) { - return FALSE; + pDict->Release(); + return FALSE; } xrefpos = newxrefpos; - while (xrefpos) { - CrossRefList.InsertAt(0, xrefpos); - LoadCrossRefV4(xrefpos, 0, TRUE, FALSE); - CPDF_Dictionary* pDict = LoadTrailerV4(); - if (pDict == NULL) { - return FALSE; - } - if (!CheckDirectType(pDict, FX_BSTRC("Prev"), PDFOBJ_NUMBER)) { - pDict->Release(); - return FALSE; - } - newxrefpos = GetDirectInteger(pDict, FX_BSTRC("Prev")); - if (newxrefpos == xrefpos) { - pDict->Release(); - return FALSE; - } - xrefpos = newxrefpos; - XRefStreamList.InsertAt(0, pDict->GetInteger(FX_BSTRC("XRefStm"))); - m_Trailers.Add(pDict); - } - for (int32_t i = 0; i < CrossRefList.GetSize(); i ++) - if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE, i == 0)) { - return FALSE; - } - return TRUE; + XRefStreamList.InsertAt(0, pDict->GetInteger(FX_BSTRC("XRefStm"))); + m_Trailers.Add(pDict); + } + for (int32_t i = 0; i < CrossRefList.GetSize(); i++) + if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE, i == 0)) { + return FALSE; + } + return TRUE; } -FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV4(FX_FILESIZE xrefpos, FX_DWORD dwObjCount) -{ - if (!LoadLinearizedCrossRefV4(xrefpos, dwObjCount)) { - return FALSE; - } - m_pTrailer = LoadTrailerV4(); - if (m_pTrailer == NULL) { - return FALSE; - } - int32_t xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size")); - if (xrefsize == 0) { - return FALSE; - } - CFX_FileSizeArray CrossRefList, XRefStreamList; - CrossRefList.Add(xrefpos); - XRefStreamList.Add(GetDirectInteger(m_pTrailer, FX_BSTRC("XRefStm"))); - xrefpos = GetDirectInteger(m_pTrailer, FX_BSTRC("Prev")); - while (xrefpos) { - CrossRefList.InsertAt(0, xrefpos); - LoadCrossRefV4(xrefpos, 0, TRUE, FALSE); - CPDF_Dictionary* pDict = LoadTrailerV4(); - if (pDict == NULL) { - return FALSE; - } - xrefpos = GetDirectInteger(pDict, FX_BSTRC("Prev")); - XRefStreamList.InsertAt(0, pDict->GetInteger(FX_BSTRC("XRefStm"))); - m_Trailers.Add(pDict); - } - for (int32_t i = 1; i < CrossRefList.GetSize(); i ++) - if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE, i == 0)) { - return FALSE; - } - return TRUE; +FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV4(FX_FILESIZE xrefpos, + FX_DWORD dwObjCount) { + if (!LoadLinearizedCrossRefV4(xrefpos, dwObjCount)) { + return FALSE; + } + m_pTrailer = LoadTrailerV4(); + if (m_pTrailer == NULL) { + return FALSE; + } + int32_t xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size")); + if (xrefsize == 0) { + return FALSE; + } + CFX_FileSizeArray CrossRefList, XRefStreamList; + CrossRefList.Add(xrefpos); + XRefStreamList.Add(GetDirectInteger(m_pTrailer, FX_BSTRC("XRefStm"))); + xrefpos = GetDirectInteger(m_pTrailer, FX_BSTRC("Prev")); + while (xrefpos) { + CrossRefList.InsertAt(0, xrefpos); + LoadCrossRefV4(xrefpos, 0, TRUE, FALSE); + CPDF_Dictionary* pDict = LoadTrailerV4(); + if (pDict == NULL) { + return FALSE; + } + xrefpos = GetDirectInteger(pDict, FX_BSTRC("Prev")); + XRefStreamList.InsertAt(0, pDict->GetInteger(FX_BSTRC("XRefStm"))); + m_Trailers.Add(pDict); + } + for (int32_t i = 1; i < CrossRefList.GetSize(); i++) + if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE, i == 0)) { + return FALSE; + } + return TRUE; } -FX_BOOL CPDF_Parser::LoadLinearizedCrossRefV4(FX_FILESIZE pos, FX_DWORD dwObjCount) -{ - FX_FILESIZE dwStartPos = pos - m_Syntax.m_HeaderOffset; - m_Syntax.RestorePos(dwStartPos); - void* pResult = FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); +FX_BOOL CPDF_Parser::LoadLinearizedCrossRefV4(FX_FILESIZE pos, + FX_DWORD dwObjCount) { + FX_FILESIZE dwStartPos = pos - m_Syntax.m_HeaderOffset; + m_Syntax.RestorePos(dwStartPos); + void* pResult = + FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), + sizeof(FX_FILESIZE), _CompareFileSize); + if (pResult == NULL) { + m_SortedOffset.Add(pos); + } + FX_DWORD start_objnum = 0; + FX_DWORD count = dwObjCount; + FX_FILESIZE SavedPos = m_Syntax.SavePos(); + int32_t recordsize = 20; + char* pBuf = FX_Alloc(char, 1024 * recordsize + 1); + pBuf[1024 * recordsize] = '\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; + FX_DWORD dwReadSize = block_size * recordsize; + if ((FX_FILESIZE)(dwStartPos + dwReadSize) > m_Syntax.m_FileLen) { + FX_Free(pBuf); + return FALSE; + } + if (!m_Syntax.ReadBlock((uint8_t*)pBuf, dwReadSize)) { + FX_Free(pBuf); + return FALSE; + } + for (int32_t i = 0; i < block_size; i++) { + FX_DWORD objnum = start_objnum + block * 1024 + i; + char* pEntry = pBuf + i * recordsize; + if (pEntry[17] == 'f') { + m_CrossRef.SetAtGrow(objnum, 0); + m_V5Type.SetAtGrow(objnum, 0); + } else { + int32_t offset = FXSYS_atoi(pEntry); + if (offset == 0) { + for (int32_t c = 0; c < 10; c++) { + if (pEntry[c] < '0' || pEntry[c] > '9') { + FX_Free(pBuf); + return FALSE; + } + } + } + m_CrossRef.SetAtGrow(objnum, offset); + int32_t version = FXSYS_atoi(pEntry + 11); + if (version >= 1) { + 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]); + } + } + m_V5Type.SetAtGrow(objnum, 1); + } + } + } + FX_Free(pBuf); + 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) { + 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) { + m_SortedOffset.Add(pos); + } + if (streampos) { + void* pResult = FXSYS_bsearch(&streampos, m_SortedOffset.GetData(), + m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), + _CompareFileSize); if (pResult == NULL) { - m_SortedOffset.Add(pos); + m_SortedOffset.Add(streampos); } - FX_DWORD start_objnum = 0; - FX_DWORD count = dwObjCount; + } + while (1) { FX_FILESIZE SavedPos = m_Syntax.SavePos(); + FX_BOOL bIsNumber; + CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); + 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; + } + FX_DWORD count = m_Syntax.GetDirectNum(); + m_Syntax.ToNextWord(); + SavedPos = m_Syntax.SavePos(); + FX_BOOL bFirstItem = FALSE; int32_t recordsize = 20; - char* pBuf = FX_Alloc(char, 1024 * recordsize + 1); - pBuf[1024 * recordsize] = '\0'; - int32_t nBlocks = count / 1024 + 1; - for (int32_t block = 0; block < nBlocks; block ++) { + if (bFirst) { + bFirstItem = TRUE; + } + m_dwXrefStartObjNum = start_objnum; + if (!bSkip) { + char* pBuf = FX_Alloc(char, 1024 * recordsize + 1); + pBuf[1024 * recordsize] = '\0'; + int32_t nBlocks = count / 1024 + 1; + FX_BOOL bFirstBlock = TRUE; + for (int32_t block = 0; block < nBlocks; block++) { int32_t block_size = block == nBlocks - 1 ? count % 1024 : 1024; - FX_DWORD dwReadSize = block_size * recordsize; - if ((FX_FILESIZE)(dwStartPos + dwReadSize) > m_Syntax.m_FileLen) { - FX_Free(pBuf); - return FALSE; - } - if (!m_Syntax.ReadBlock((uint8_t*)pBuf, dwReadSize)) { - FX_Free(pBuf); - return FALSE; - } - for (int32_t i = 0; i < block_size; i ++) { - FX_DWORD objnum = start_objnum + block * 1024 + i; - char* pEntry = pBuf + i * recordsize; - if (pEntry[17] == 'f') { - m_CrossRef.SetAtGrow(objnum, 0); - m_V5Type.SetAtGrow(objnum, 0); - } else { - int32_t offset = FXSYS_atoi(pEntry); - if (offset == 0) { - for (int32_t c = 0; c < 10; c ++) { - if (pEntry[c] < '0' || pEntry[c] > '9') { - FX_Free(pBuf); - return FALSE; - } - } - } - m_CrossRef.SetAtGrow(objnum, offset); - int32_t version = FXSYS_atoi(pEntry + 11); - if (version >= 1) { - 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]); - } + m_Syntax.ReadBlock((uint8_t*)pBuf, block_size * recordsize); + for (int32_t i = 0; i < block_size; i++) { + FX_DWORD objnum = start_objnum + block * 1024 + i; + char* pEntry = pBuf + i * recordsize; + if (pEntry[17] == 'f') { + if (bFirstItem) { + objnum = 0; + bFirstItem = FALSE; + } + if (bFirstBlock) { + FX_FILESIZE offset = (FX_FILESIZE)FXSYS_atoi64(pEntry); + int32_t version = FXSYS_atoi(pEntry + 11); + if (offset == 0 && version == 65535 && start_objnum != 0) { + start_objnum--; + objnum = 0; + } + } + m_CrossRef.SetAtGrow(objnum, 0); + m_V5Type.SetAtGrow(objnum, 0); + } else { + FX_FILESIZE offset = (FX_FILESIZE)FXSYS_atoi64(pEntry); + if (offset == 0) { + for (int32_t c = 0; c < 10; c++) { + if (pEntry[c] < '0' || pEntry[c] > '9') { + FX_Free(pBuf); + return FALSE; } - m_V5Type.SetAtGrow(objnum, 1); + } + } + m_CrossRef.SetAtGrow(objnum, offset); + int32_t version = FXSYS_atoi(pEntry + 11); + if (version >= 1) { + 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]); + } + } + m_V5Type.SetAtGrow(objnum, 1); + } + if (bFirstBlock) { + bFirstBlock = FALSE; + } } + } + FX_Free(pBuf); } - FX_Free(pBuf); 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) -{ - 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) { - m_SortedOffset.Add(pos); + } + if (streampos) + if (!LoadCrossRefV5(streampos, streampos, FALSE)) { + return FALSE; } - if (streampos) { - void* pResult = FXSYS_bsearch(&streampos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); - if (pResult == NULL) { - m_SortedOffset.Add(streampos); - } + return TRUE; +} +FX_BOOL CPDF_Parser::LoadAllCrossRefV5(FX_FILESIZE xrefpos) { + if (!LoadCrossRefV5(xrefpos, xrefpos, TRUE)) { + return FALSE; + } + while (xrefpos) + if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) { + return FALSE; } - while (1) { - FX_FILESIZE SavedPos = m_Syntax.SavePos(); - FX_BOOL bIsNumber; - CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); - if (word.IsEmpty()) { - return FALSE; - } - if (!bIsNumber) { - m_Syntax.RestorePos(SavedPos); + m_ObjectStreamMap.InitHashTable(101, FALSE); + m_bXRefStream = TRUE; + return TRUE; +} +FX_BOOL CPDF_Parser::RebuildCrossRef() { + m_CrossRef.RemoveAll(); + m_V5Type.RemoveAll(); + m_SortedOffset.RemoveAll(); + m_ObjVersion.RemoveAll(); + if (m_pTrailer) { + m_pTrailer->Release(); + m_pTrailer = NULL; + } + int32_t status = 0; + int32_t inside_index = 0; + FX_DWORD objnum = 0, gennum = 0; + int32_t depth = 0; + uint8_t* buffer = FX_Alloc(uint8_t, 4096); + 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; + 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)) { + break; + } + for (FX_DWORD i = 0; i < size; i++) { + uint8_t byte = buffer[i]; + switch (status) { + case 0: + if (PDF_CharType[byte] == 'W') { + status = 1; + } + if (byte <= '9' && byte >= '0') { + --i; + status = 1; + } + if (byte == '%') { + inside_index = 0; + status = 9; + } + if (byte == '(') { + status = 10; + depth = 1; + } + if (byte == '<') { + inside_index = 1; + status = 11; + } + if (byte == '\\') { + status = 13; + } + if (byte == 't') { + status = 7; + inside_index = 1; + } + break; + case 1: + if (PDF_CharType[byte] == 'W') { break; - } - FX_DWORD start_objnum = FXSYS_atoi(word); - 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) { - bFirstItem = TRUE; - } - m_dwXrefStartObjNum = start_objnum; - if (!bSkip) { - char* pBuf = FX_Alloc(char, 1024 * recordsize + 1); - pBuf[1024 * recordsize] = '\0'; - int32_t nBlocks = count / 1024 + 1; - FX_BOOL bFirstBlock = TRUE; - for (int32_t block = 0; block < nBlocks; block ++) { - int32_t block_size = block == nBlocks - 1 ? count % 1024 : 1024; - m_Syntax.ReadBlock((uint8_t*)pBuf, block_size * recordsize); - for (int32_t i = 0; i < block_size; i ++) { - FX_DWORD objnum = start_objnum + block * 1024 + i; - char* pEntry = pBuf + i * recordsize; - if (pEntry[17] == 'f') { - if (bFirstItem) { - objnum = 0; - bFirstItem = FALSE; - } - if (bFirstBlock) { - FX_FILESIZE offset = (FX_FILESIZE)FXSYS_atoi64(pEntry); - int32_t version = FXSYS_atoi(pEntry + 11); - if (offset == 0 && version == 65535 && start_objnum != 0) { - start_objnum--; - objnum = 0; - } - } - m_CrossRef.SetAtGrow(objnum, 0); - m_V5Type.SetAtGrow(objnum, 0); - } else { - FX_FILESIZE offset = (FX_FILESIZE)FXSYS_atoi64(pEntry); - if (offset == 0) { - for (int32_t c = 0; c < 10; c ++) { - if (pEntry[c] < '0' || pEntry[c] > '9') { - FX_Free(pBuf); - return FALSE; - } - } - } - m_CrossRef.SetAtGrow(objnum, offset); - int32_t version = FXSYS_atoi(pEntry + 11); - if (version >= 1) { - 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]); + } else if (byte <= '9' && byte >= '0') { + start_pos = pos + i; + status = 2; + objnum = byte - '0'; + } else if (byte == 't') { + status = 7; + inside_index = 1; + } else if (byte == 'x') { + status = 8; + inside_index = 1; + } else { + --i; + status = 0; + } + break; + case 2: + if (byte <= '9' && byte >= '0') { + objnum = objnum * 10 + byte - '0'; + break; + } else if (PDF_CharType[byte] == 'W') { + status = 3; + } else { + --i; + status = 14; + inside_index = 0; + } + break; + case 3: + if (byte <= '9' && byte >= '0') { + start_pos1 = pos + i; + status = 4; + gennum = byte - '0'; + } else if (PDF_CharType[byte] == 'W') { + break; + } else if (byte == 't') { + status = 7; + inside_index = 1; + } else { + --i; + status = 0; + } + break; + case 4: + if (byte <= '9' && byte >= '0') { + gennum = gennum * 10 + byte - '0'; + break; + } else if (PDF_CharType[byte] == 'W') { + status = 5; + } else { + --i; + status = 0; + } + break; + case 5: + if (byte == 'o') { + status = 6; + inside_index = 1; + } else if (PDF_CharType[byte] == 'W') { + break; + } else if (byte <= '9' && byte >= '0') { + objnum = gennum; + gennum = byte - '0'; + start_pos = start_pos1; + start_pos1 = pos + i; + status = 4; + } else if (byte == 't') { + status = 7; + inside_index = 1; + } else { + --i; + status = 0; + } + break; + case 6: + switch (inside_index) { + case 1: + if (byte != 'b') { + --i; + status = 0; + } else { + inside_index++; + } + break; + case 2: + if (byte != 'j') { + --i; + status = 0; + } else { + inside_index++; + } + break; + case 3: + if (PDF_CharType[byte] == 'W' || PDF_CharType[byte] == 'D') { + if (objnum > 0x1000000) { + status = 0; + break; + } + FX_FILESIZE obj_pos = start_pos - m_Syntax.m_HeaderOffset; + last_obj = start_pos; + void* pResult = + FXSYS_bsearch(&obj_pos, m_SortedOffset.GetData(), + m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), + _CompareFileSize); + if (pResult == NULL) { + m_SortedOffset.Add(obj_pos); + } + FX_FILESIZE obj_end = 0; + CPDF_Object* pObject = ParseIndirectObjectAtByStrict( + m_pDocument, obj_pos, objnum, NULL, &obj_end); + if (pObject) { + int iType = pObject->GetType(); + if (iType == PDFOBJ_STREAM) { + CPDF_Stream* pStream = (CPDF_Stream*)pObject; + CPDF_Dictionary* pDict = pStream->GetDict(); + if (pDict) { + if (pDict->KeyExist(FX_BSTRC("Type"))) { + CFX_ByteString bsValue = + pDict->GetString(FX_BSTRC("Type")); + if (bsValue == FX_BSTRC("XRef") && + pDict->KeyExist(FX_BSTRC("Size"))) { + CPDF_Object* pRoot = + pDict->GetElement(FX_BSTRC("Root")); + if (pRoot && pRoot->GetDict() && + pRoot->GetDict()->GetElement(FX_BSTRC("Pages"))) { + if (m_pTrailer) { + m_pTrailer->Release(); } + m_pTrailer = (CPDF_Dictionary*)pDict->Clone(); + } } - m_V5Type.SetAtGrow(objnum, 1); - } - if (bFirstBlock) { - bFirstBlock = FALSE; + } } + } } - } - FX_Free(pBuf); - } - m_Syntax.RestorePos(SavedPos + count * recordsize); - } - if (streampos) - if (!LoadCrossRefV5(streampos, streampos, FALSE)) { - return FALSE; - } - return TRUE; -} -FX_BOOL CPDF_Parser::LoadAllCrossRefV5(FX_FILESIZE xrefpos) -{ - if (!LoadCrossRefV5(xrefpos, xrefpos, TRUE)) { - return FALSE; - } - while (xrefpos) - if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) { - return FALSE; - } - m_ObjectStreamMap.InitHashTable(101, FALSE); - m_bXRefStream = TRUE; - return TRUE; -} -FX_BOOL CPDF_Parser::RebuildCrossRef() -{ - m_CrossRef.RemoveAll(); - m_V5Type.RemoveAll(); - m_SortedOffset.RemoveAll(); - m_ObjVersion.RemoveAll(); - if (m_pTrailer) { - m_pTrailer->Release(); - m_pTrailer = NULL; - } - int32_t status = 0; - int32_t inside_index = 0; - FX_DWORD objnum = 0, gennum = 0; - int32_t depth = 0; - uint8_t* buffer = FX_Alloc(uint8_t, 4096); - 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; - 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)) { - break; - } - for (FX_DWORD i = 0; i < size; i ++) { - uint8_t byte = buffer[i]; - switch (status) { - case 0: - if (PDF_CharType[byte] == 'W') { - status = 1; - } - if (byte <= '9' && byte >= '0') { - --i; - status = 1; - } - if (byte == '%') { - inside_index = 0; - status = 9; - } - if (byte == '(') { - status = 10; - depth = 1; - } - if (byte == '<') { - inside_index = 1; - status = 11; - } - if (byte == '\\') { - status = 13; - } - if (byte == 't') { - status = 7; - inside_index = 1; - } - break; - case 1: - if (PDF_CharType[byte] == 'W') { - break; - } else if (byte <= '9' && byte >= '0') { - start_pos = pos + i; - status = 2; - objnum = byte - '0'; - } else if (byte == 't') { - status = 7; - inside_index = 1; - } else if (byte == 'x') { - status = 8; - inside_index = 1; - } else { - --i; - status = 0; - } - break; - case 2: - if (byte <= '9' && byte >= '0') { - objnum = objnum * 10 + byte - '0'; - break; - } else if (PDF_CharType[byte] == 'W') { - status = 3; - } else { - --i; - status = 14; - inside_index = 0; - } - break; - case 3: - if (byte <= '9' && byte >= '0') { - start_pos1 = pos + i; - status = 4; - gennum = byte - '0'; - } else if (PDF_CharType[byte] == 'W') { - break; - } else if (byte == 't') { - status = 7; - inside_index = 1; - } else { - --i; - status = 0; - } - break; - case 4: - if (byte <= '9' && byte >= '0') { - gennum = gennum * 10 + byte - '0'; - break; - } else if (PDF_CharType[byte] == 'W') { - status = 5; - } else { - --i; - status = 0; - } - break; - case 5: - if (byte == 'o') { - status = 6; - inside_index = 1; - } else if (PDF_CharType[byte] == 'W') { - break; - } else if (byte <= '9' && byte >= '0') { - objnum = gennum; - gennum = byte - '0'; - start_pos = start_pos1; - start_pos1 = pos + i; - status = 4; - } else if (byte == 't') { - status = 7; - inside_index = 1; - } else { - --i; - status = 0; - } - break; - case 6: - switch (inside_index) { - case 1: - if (byte != 'b') { - --i; - status = 0; - } else { - inside_index ++; - } - break; - case 2: - if (byte != 'j') { - --i; - status = 0; - } else { - inside_index ++; - } - break; - case 3: - if (PDF_CharType[byte] == 'W' || PDF_CharType[byte] == 'D') { - if (objnum > 0x1000000) { - status = 0; - break; - } - FX_FILESIZE obj_pos = start_pos - m_Syntax.m_HeaderOffset; - last_obj = start_pos; - void* pResult = FXSYS_bsearch(&obj_pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); - if (pResult == NULL) { - m_SortedOffset.Add(obj_pos); - } - FX_FILESIZE obj_end = 0; - CPDF_Object *pObject = ParseIndirectObjectAtByStrict(m_pDocument, obj_pos, objnum, NULL, &obj_end); - if (pObject) { - int iType = pObject->GetType(); - if (iType == PDFOBJ_STREAM) { - CPDF_Stream* pStream = (CPDF_Stream*)pObject; - CPDF_Dictionary* pDict = pStream->GetDict(); - if (pDict) { - if (pDict->KeyExist(FX_BSTRC("Type"))) { - CFX_ByteString bsValue = pDict->GetString(FX_BSTRC("Type")); - if (bsValue == FX_BSTRC("XRef") && pDict->KeyExist(FX_BSTRC("Size"))) { - CPDF_Object* pRoot = pDict->GetElement(FX_BSTRC("Root")); - if (pRoot && pRoot->GetDict() && pRoot->GetDict()->GetElement(FX_BSTRC("Pages"))) { - if (m_pTrailer) { - m_pTrailer->Release(); - } - m_pTrailer = (CPDF_Dictionary*)pDict->Clone(); - } - } - } - } - } - } - FX_FILESIZE offset = 0; - m_Syntax.RestorePos(obj_pos); - offset = m_Syntax.FindTag(FX_BSTRC("obj"), 0); - if (offset == -1) { - offset = 0; - } else { - offset += 3; - } - FX_FILESIZE nLen = obj_end - obj_pos - offset; - if ((FX_DWORD)nLen > size - i) { - pos = obj_end + m_Syntax.m_HeaderOffset; - bOverFlow = TRUE; - } else { - i += (FX_DWORD)nLen; - } - if (m_CrossRef.GetSize() > (int32_t)objnum && m_CrossRef[objnum]) { - if (pObject) { - FX_DWORD oldgen = m_ObjVersion.GetAt(objnum); - m_CrossRef[objnum] = obj_pos; - m_ObjVersion.SetAt(objnum, (int16_t)gennum); - if (oldgen != gennum) { - m_bVersionUpdated = TRUE; - } - } - } else { - m_CrossRef.SetAtGrow(objnum, obj_pos); - m_V5Type.SetAtGrow(objnum, 1); - m_ObjVersion.SetAtGrow(objnum, (int16_t)gennum); - } - if (pObject) { - pObject->Release(); - } - } - --i; - status = 0; - break; + FX_FILESIZE offset = 0; + m_Syntax.RestorePos(obj_pos); + offset = m_Syntax.FindTag(FX_BSTRC("obj"), 0); + if (offset == -1) { + offset = 0; + } else { + offset += 3; + } + FX_FILESIZE nLen = obj_end - obj_pos - offset; + if ((FX_DWORD)nLen > size - i) { + pos = obj_end + m_Syntax.m_HeaderOffset; + bOverFlow = TRUE; + } else { + i += (FX_DWORD)nLen; + } + if (m_CrossRef.GetSize() > (int32_t)objnum && + m_CrossRef[objnum]) { + if (pObject) { + FX_DWORD oldgen = m_ObjVersion.GetAt(objnum); + m_CrossRef[objnum] = obj_pos; + m_ObjVersion.SetAt(objnum, (int16_t)gennum); + if (oldgen != gennum) { + m_bVersionUpdated = TRUE; } - break; - case 7: - if (inside_index == 7) { - if (PDF_CharType[byte] == 'W' || PDF_CharType[byte] == 'D') { - last_trailer = pos + i - 7; - m_Syntax.RestorePos(pos + i - m_Syntax.m_HeaderOffset); - CPDF_Object* pObj = m_Syntax.GetObject(m_pDocument, 0, 0, 0); - if (pObj) { - if (pObj->GetType() != PDFOBJ_DICTIONARY && pObj->GetType() != PDFOBJ_STREAM) { - pObj->Release(); - } else { - CPDF_Dictionary* pTrailer = NULL; - if (pObj->GetType() == PDFOBJ_STREAM) { - pTrailer = ((CPDF_Stream*)pObj)->GetDict(); - } else { - pTrailer = (CPDF_Dictionary*)pObj; - } - if (pTrailer) { - if (m_pTrailer) { - CPDF_Object* pRoot = pTrailer->GetElement(FX_BSTRC("Root")); - if (pRoot == NULL || (pRoot->GetType() == PDFOBJ_REFERENCE && - (FX_DWORD)m_CrossRef.GetSize() > ((CPDF_Reference*)pRoot)->GetRefObjNum() && - m_CrossRef.GetAt(((CPDF_Reference*)pRoot)->GetRefObjNum()) != 0)) { - FX_POSITION pos = pTrailer->GetStartPos(); - while (pos) { - CFX_ByteString key; - CPDF_Object* pObj = pTrailer->GetNextElement(pos, key); - m_pTrailer->SetAt(key, pObj->Clone(), m_pDocument); - } - pObj->Release(); - } else { - pObj->Release(); - } - } else { - if (pObj->GetType() == PDFOBJ_STREAM) { - m_pTrailer = (CPDF_Dictionary*)pTrailer->Clone(); - pObj->Release(); - } else { - m_pTrailer = pTrailer; - } - FX_FILESIZE dwSavePos = m_Syntax.SavePos(); - CFX_ByteString strWord = m_Syntax.GetKeyword(); - if (!strWord.Compare(FX_BSTRC("startxref"))) { - FX_BOOL bNumber = FALSE; - CFX_ByteString bsOffset = m_Syntax.GetNextWord(bNumber); - if (bNumber) { - m_LastXRefOffset = FXSYS_atoi(bsOffset); - } - } - m_Syntax.RestorePos(dwSavePos); - } - } else { - pObj->Release(); - } - } - } + } + } else { + m_CrossRef.SetAtGrow(objnum, obj_pos); + m_V5Type.SetAtGrow(objnum, 1); + m_ObjVersion.SetAtGrow(objnum, (int16_t)gennum); + } + if (pObject) { + pObject->Release(); + } + } + --i; + status = 0; + break; + } + break; + case 7: + if (inside_index == 7) { + if (PDF_CharType[byte] == 'W' || PDF_CharType[byte] == 'D') { + last_trailer = pos + i - 7; + m_Syntax.RestorePos(pos + i - m_Syntax.m_HeaderOffset); + CPDF_Object* pObj = m_Syntax.GetObject(m_pDocument, 0, 0, 0); + if (pObj) { + if (pObj->GetType() != PDFOBJ_DICTIONARY && + pObj->GetType() != PDFOBJ_STREAM) { + pObj->Release(); + } else { + CPDF_Dictionary* pTrailer = NULL; + if (pObj->GetType() == PDFOBJ_STREAM) { + pTrailer = ((CPDF_Stream*)pObj)->GetDict(); + } else { + pTrailer = (CPDF_Dictionary*)pObj; + } + if (pTrailer) { + if (m_pTrailer) { + CPDF_Object* pRoot = + pTrailer->GetElement(FX_BSTRC("Root")); + if (pRoot == NULL || + (pRoot->GetType() == PDFOBJ_REFERENCE && + (FX_DWORD)m_CrossRef.GetSize() > + ((CPDF_Reference*)pRoot)->GetRefObjNum() && + m_CrossRef.GetAt(((CPDF_Reference*)pRoot) + ->GetRefObjNum()) != 0)) { + FX_POSITION pos = pTrailer->GetStartPos(); + while (pos) { + CFX_ByteString key; + CPDF_Object* pObj = + pTrailer->GetNextElement(pos, key); + m_pTrailer->SetAt(key, pObj->Clone(), m_pDocument); } - --i; - status = 0; - } else if (byte == "trailer"[inside_index]) { - inside_index ++; + pObj->Release(); + } else { + pObj->Release(); + } } else { - --i; - status = 0; - } - break; - case 8: - if (inside_index == 4) { - last_xref = pos + i - 4; - status = 1; - } else if (byte == "xref"[inside_index]) { - inside_index ++; - } else { - --i; - status = 0; - } - break; - case 9: - if (byte == '\r' || byte == '\n') { - status = 0; - } - break; - case 10: - if (byte == ')') { - if (depth > 0) { - depth--; + if (pObj->GetType() == PDFOBJ_STREAM) { + m_pTrailer = (CPDF_Dictionary*)pTrailer->Clone(); + pObj->Release(); + } else { + m_pTrailer = pTrailer; + } + FX_FILESIZE dwSavePos = m_Syntax.SavePos(); + CFX_ByteString strWord = m_Syntax.GetKeyword(); + if (!strWord.Compare(FX_BSTRC("startxref"))) { + FX_BOOL bNumber = FALSE; + CFX_ByteString bsOffset = m_Syntax.GetNextWord(bNumber); + if (bNumber) { + m_LastXRefOffset = FXSYS_atoi(bsOffset); } - } else if (byte == '(') { - depth++; - } - if (!depth) { - status = 0; - } - break; - case 11: - if (byte == '<' && inside_index == 1) { - status = 12; - } else if (byte == '>') { - status = 0; - } - inside_index = 0; - break; - case 12: - --i; - status = 0; - break; - case 13: - if (PDF_CharType[byte] == 'D' || PDF_CharType[byte] == 'W') { - --i; - status = 0; - } - break; - case 14: - if (PDF_CharType[byte] == 'W') { - status = 0; - } else if (byte == '%' || byte == '(' || byte == '<' || byte == '\\') { - status = 0; - --i; - } else if (inside_index == 6) { - status = 0; - --i; - } else if (byte == "endobj"[inside_index]) { - inside_index++; + } + m_Syntax.RestorePos(dwSavePos); } - break; + } else { + pObj->Release(); + } + } + } } - if (bOverFlow) { - size = 0; - break; + --i; + status = 0; + } else if (byte == "trailer"[inside_index]) { + inside_index++; + } else { + --i; + status = 0; + } + break; + case 8: + if (inside_index == 4) { + last_xref = pos + i - 4; + status = 1; + } else if (byte == "xref"[inside_index]) { + inside_index++; + } else { + --i; + status = 0; + } + break; + case 9: + if (byte == '\r' || byte == '\n') { + status = 0; + } + break; + case 10: + if (byte == ')') { + if (depth > 0) { + depth--; } - } - pos += size; - } - if (last_xref != -1 && last_xref > last_obj) { - last_trailer = last_xref; - } else if (last_trailer == -1 || last_xref < last_obj) { - last_trailer = m_Syntax.m_FileLen; - } - FX_FILESIZE offset = last_trailer - m_Syntax.m_HeaderOffset; - void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); - if (pResult == NULL) { - m_SortedOffset.Add(offset); - } - FX_Free(buffer); - return TRUE; + } else if (byte == '(') { + depth++; + } + if (!depth) { + status = 0; + } + break; + case 11: + if (byte == '<' && inside_index == 1) { + status = 12; + } else if (byte == '>') { + status = 0; + } + inside_index = 0; + break; + case 12: + --i; + status = 0; + break; + case 13: + if (PDF_CharType[byte] == 'D' || PDF_CharType[byte] == 'W') { + --i; + status = 0; + } + break; + case 14: + if (PDF_CharType[byte] == 'W') { + status = 0; + } else if (byte == '%' || byte == '(' || byte == '<' || + byte == '\\') { + status = 0; + --i; + } else if (inside_index == 6) { + status = 0; + --i; + } else if (byte == "endobj"[inside_index]) { + inside_index++; + } + break; + } + if (bOverFlow) { + size = 0; + break; + } + } + pos += size; + } + if (last_xref != -1 && last_xref > last_obj) { + last_trailer = last_xref; + } else if (last_trailer == -1 || last_xref < last_obj) { + last_trailer = m_Syntax.m_FileLen; + } + FX_FILESIZE offset = last_trailer - m_Syntax.m_HeaderOffset; + void* pResult = + FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), + 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; +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) -{ - CPDF_Stream* pStream = (CPDF_Stream*)ParseIndirectObjectAt(m_pDocument, pos, 0, NULL); - if (!pStream) { - return FALSE; - } - if (m_pDocument) { - CPDF_Dictionary * pDict = m_pDocument->GetRoot(); - if (!pDict || pDict->GetObjNum() != pStream->m_ObjNum) { - m_pDocument->InsertIndirectObject(pStream->m_ObjNum, pStream); - } else { - if (pStream->GetType() == PDFOBJ_STREAM) { - pStream->Release(); - } - return FALSE; - } - } - if (pStream->GetType() != PDFOBJ_STREAM) { - return FALSE; - } - prev = pStream->GetDict()->GetInteger(FX_BSTRC("Prev")); - int32_t size = pStream->GetDict()->GetInteger(FX_BSTRC("Size")); - if (size < 0) { - pStream->Release(); - return FALSE; - } - if (bMainXRef) { - m_pTrailer = (CPDF_Dictionary*)pStream->GetDict()->Clone(); - m_CrossRef.SetSize(size); - if (m_V5Type.SetSize(size)) { - FXSYS_memset(m_V5Type.GetData(), 0, size); - } +FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE pos, + FX_FILESIZE& prev, + FX_BOOL bMainXRef) { + CPDF_Stream* pStream = + (CPDF_Stream*)ParseIndirectObjectAt(m_pDocument, pos, 0, NULL); + if (!pStream) { + return FALSE; + } + if (m_pDocument) { + CPDF_Dictionary* pDict = m_pDocument->GetRoot(); + if (!pDict || pDict->GetObjNum() != pStream->m_ObjNum) { + m_pDocument->InsertIndirectObject(pStream->m_ObjNum, pStream); } else { - m_Trailers.Add((CPDF_Dictionary*)pStream->GetDict()->Clone()); - } - std::vector<std::pair<int32_t, int32_t> > arrIndex; - CPDF_Array* pArray = pStream->GetDict()->GetArray(FX_BSTRC("Index")); - if (pArray) { - FX_DWORD nPairSize = pArray->GetCount() / 2; - for (FX_DWORD i = 0; i < nPairSize; i++) { - CPDF_Object* pStartNumObj = pArray->GetElement(i * 2); - CPDF_Object* pCountObj = pArray->GetElement(i * 2 + 1); - if (pStartNumObj && pStartNumObj->GetType() == PDFOBJ_NUMBER - && pCountObj && pCountObj->GetType() == PDFOBJ_NUMBER) { - int nStartNum = pStartNumObj->GetInteger(); - int nCount = pCountObj->GetInteger(); - if (nStartNum >= 0 && nCount > 0) { - arrIndex.push_back(std::make_pair(nStartNum, nCount)); - } - } - } - } - if (arrIndex.size() == 0) { - arrIndex.push_back(std::make_pair(0, size)); - } - pArray = pStream->GetDict()->GetArray(FX_BSTRC("W")); - if (pArray == NULL) { - pStream->Release(); - return FALSE; - } - CFX_DWordArray WidthArray; - FX_SAFE_DWORD dwAccWidth = 0; - for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) { - WidthArray.Add(pArray->GetInteger(i)); - dwAccWidth += WidthArray[i]; - } - if (!dwAccWidth.IsValid() || WidthArray.GetSize() < 3) { + if (pStream->GetType() == PDFOBJ_STREAM) { pStream->Release(); - return FALSE; + } + return FALSE; } - FX_DWORD totalWidth = dwAccWidth.ValueOrDie(); - CPDF_StreamAcc acc; - acc.LoadAllData(pStream); - const uint8_t* pData = acc.GetData(); - FX_DWORD dwTotalSize = acc.GetSize(); - FX_DWORD segindex = 0; - for (FX_DWORD i = 0; i < arrIndex.size(); i ++) { - int32_t startnum = arrIndex[i].first; - if (startnum < 0) { - continue; - } - m_dwXrefStartObjNum = pdfium::base::checked_cast<FX_DWORD, int32_t> (startnum); - FX_DWORD count = pdfium::base::checked_cast<FX_DWORD, int32_t> (arrIndex[i].second); - FX_SAFE_DWORD dwCaculatedSize = segindex; - dwCaculatedSize += count; - dwCaculatedSize *= totalWidth; - if (!dwCaculatedSize.IsValid() || dwCaculatedSize.ValueOrDie() > dwTotalSize) { - continue; - } - const uint8_t* segstart = pData + segindex * totalWidth; - FX_SAFE_DWORD dwMaxObjNum = startnum; - dwMaxObjNum += count; - FX_DWORD dwV5Size = pdfium::base::checked_cast<FX_DWORD, int32_t> (m_V5Type.GetSize()); - if (!dwMaxObjNum.IsValid() || dwMaxObjNum.ValueOrDie() > dwV5Size) { - continue; - } - for (FX_DWORD j = 0; j < count; j ++) { - int32_t type = 1; - const uint8_t* entrystart = segstart + j * totalWidth; - if (WidthArray[0]) { - type = _GetVarInt(entrystart, WidthArray[0]); - } - if (m_V5Type[startnum + j] == 255) { - FX_FILESIZE offset = _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); - if (pResult == NULL) { - m_SortedOffset.Add(offset); - } - continue; - } - if (m_V5Type[startnum + j]) { - continue; - } - m_V5Type[startnum + j] = type; - if (type == 0) { - m_CrossRef[startnum + j] = 0; - } else { - FX_FILESIZE offset = _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); - if (pResult == NULL) { - m_SortedOffset.Add(offset); - } - } else { - if (offset < 0 || offset >= m_V5Type.GetSize()) { - pStream->Release(); - return FALSE; - } - m_V5Type[offset] = 255; - } - } + } + if (pStream->GetType() != PDFOBJ_STREAM) { + return FALSE; + } + prev = pStream->GetDict()->GetInteger(FX_BSTRC("Prev")); + int32_t size = pStream->GetDict()->GetInteger(FX_BSTRC("Size")); + if (size < 0) { + pStream->Release(); + return FALSE; + } + if (bMainXRef) { + m_pTrailer = (CPDF_Dictionary*)pStream->GetDict()->Clone(); + m_CrossRef.SetSize(size); + if (m_V5Type.SetSize(size)) { + FXSYS_memset(m_V5Type.GetData(), 0, size); + } + } else { + m_Trailers.Add((CPDF_Dictionary*)pStream->GetDict()->Clone()); + } + std::vector<std::pair<int32_t, int32_t> > arrIndex; + CPDF_Array* pArray = pStream->GetDict()->GetArray(FX_BSTRC("Index")); + if (pArray) { + FX_DWORD nPairSize = pArray->GetCount() / 2; + for (FX_DWORD i = 0; i < nPairSize; i++) { + CPDF_Object* pStartNumObj = pArray->GetElement(i * 2); + CPDF_Object* pCountObj = pArray->GetElement(i * 2 + 1); + if (pStartNumObj && pStartNumObj->GetType() == PDFOBJ_NUMBER && + pCountObj && pCountObj->GetType() == PDFOBJ_NUMBER) { + int nStartNum = pStartNumObj->GetInteger(); + int nCount = pCountObj->GetInteger(); + if (nStartNum >= 0 && nCount > 0) { + arrIndex.push_back(std::make_pair(nStartNum, nCount)); + } + } + } + } + if (arrIndex.size() == 0) { + arrIndex.push_back(std::make_pair(0, size)); + } + pArray = pStream->GetDict()->GetArray(FX_BSTRC("W")); + if (pArray == NULL) { + pStream->Release(); + return FALSE; + } + CFX_DWordArray WidthArray; + FX_SAFE_DWORD dwAccWidth = 0; + for (FX_DWORD i = 0; i < pArray->GetCount(); i++) { + WidthArray.Add(pArray->GetInteger(i)); + dwAccWidth += WidthArray[i]; + } + if (!dwAccWidth.IsValid() || WidthArray.GetSize() < 3) { + pStream->Release(); + return FALSE; + } + FX_DWORD totalWidth = dwAccWidth.ValueOrDie(); + CPDF_StreamAcc acc; + acc.LoadAllData(pStream); + const uint8_t* pData = acc.GetData(); + FX_DWORD dwTotalSize = acc.GetSize(); + FX_DWORD segindex = 0; + for (FX_DWORD i = 0; i < arrIndex.size(); i++) { + int32_t startnum = arrIndex[i].first; + if (startnum < 0) { + continue; + } + m_dwXrefStartObjNum = + pdfium::base::checked_cast<FX_DWORD, int32_t>(startnum); + FX_DWORD count = + pdfium::base::checked_cast<FX_DWORD, int32_t>(arrIndex[i].second); + FX_SAFE_DWORD dwCaculatedSize = segindex; + dwCaculatedSize += count; + dwCaculatedSize *= totalWidth; + if (!dwCaculatedSize.IsValid() || + dwCaculatedSize.ValueOrDie() > dwTotalSize) { + continue; + } + const uint8_t* segstart = pData + segindex * totalWidth; + FX_SAFE_DWORD dwMaxObjNum = startnum; + dwMaxObjNum += count; + FX_DWORD dwV5Size = + pdfium::base::checked_cast<FX_DWORD, int32_t>(m_V5Type.GetSize()); + if (!dwMaxObjNum.IsValid() || dwMaxObjNum.ValueOrDie() > dwV5Size) { + continue; + } + for (FX_DWORD j = 0; j < count; j++) { + int32_t type = 1; + const uint8_t* entrystart = segstart + j * totalWidth; + if (WidthArray[0]) { + type = _GetVarInt(entrystart, WidthArray[0]); + } + if (m_V5Type[startnum + j] == 255) { + FX_FILESIZE offset = + _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); + if (pResult == NULL) { + m_SortedOffset.Add(offset); + } + continue; + } + if (m_V5Type[startnum + j]) { + continue; + } + m_V5Type[startnum + j] = type; + if (type == 0) { + m_CrossRef[startnum + j] = 0; + } else { + FX_FILESIZE offset = + _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); + if (pResult == NULL) { + m_SortedOffset.Add(offset); + } + } else { + if (offset < 0 || offset >= m_V5Type.GetSize()) { + pStream->Release(); + return FALSE; + } + m_V5Type[offset] = 255; } - segindex += count; + } } - pStream->Release(); - return TRUE; + segindex += count; + } + pStream->Release(); + return TRUE; } -CPDF_Array* CPDF_Parser::GetIDArray() -{ - CPDF_Object* pID = m_pTrailer ? m_pTrailer->GetElement(FX_BSTRC("ID")) : NULL; - if (pID == NULL) { - return NULL; - } - if (pID->GetType() == PDFOBJ_REFERENCE) { - pID = ParseIndirectObject(NULL, ((CPDF_Reference*)pID)->GetRefObjNum()); - m_pTrailer->SetAt(FX_BSTRC("ID"), pID); - } - if (pID == NULL || pID->GetType() != PDFOBJ_ARRAY) { - return NULL; - } - return (CPDF_Array*)pID; +CPDF_Array* CPDF_Parser::GetIDArray() { + CPDF_Object* pID = m_pTrailer ? m_pTrailer->GetElement(FX_BSTRC("ID")) : NULL; + if (pID == NULL) { + return NULL; + } + if (pID->GetType() == PDFOBJ_REFERENCE) { + pID = ParseIndirectObject(NULL, ((CPDF_Reference*)pID)->GetRefObjNum()); + m_pTrailer->SetAt(FX_BSTRC("ID"), pID); + } + if (pID == NULL || pID->GetType() != PDFOBJ_ARRAY) { + return NULL; + } + return (CPDF_Array*)pID; } -FX_DWORD CPDF_Parser::GetRootObjNum() -{ - CPDF_Object* pRef = m_pTrailer ? m_pTrailer->GetElement(FX_BSTRC("Root")) : NULL; - if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) { - return 0; - } - return ((CPDF_Reference*) pRef)->GetRefObjNum(); +FX_DWORD CPDF_Parser::GetRootObjNum() { + CPDF_Object* pRef = + m_pTrailer ? m_pTrailer->GetElement(FX_BSTRC("Root")) : NULL; + if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) { + return 0; + } + return ((CPDF_Reference*)pRef)->GetRefObjNum(); } -FX_DWORD CPDF_Parser::GetInfoObjNum() -{ - CPDF_Object* pRef = m_pTrailer ? m_pTrailer->GetElement(FX_BSTRC("Info")) : NULL; - if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) { - return 0; - } - return ((CPDF_Reference*) pRef)->GetRefObjNum(); +FX_DWORD CPDF_Parser::GetInfoObjNum() { + CPDF_Object* pRef = + m_pTrailer ? m_pTrailer->GetElement(FX_BSTRC("Info")) : NULL; + if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) { + return 0; + } + return ((CPDF_Reference*)pRef)->GetRefObjNum(); } -FX_BOOL CPDF_Parser::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm) -{ - bForm = FALSE; - if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) { - return TRUE; - } - if (m_V5Type[objnum] == 0) { - return TRUE; - } - if (m_V5Type[objnum] == 2) { - return TRUE; - } - FX_FILESIZE pos = m_CrossRef[objnum]; - void* pResult = FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); - if (pResult == NULL) { - return TRUE; - } - if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)m_SortedOffset.GetData() == m_SortedOffset.GetSize() - 1) { - return FALSE; - } - FX_FILESIZE size = ((FX_FILESIZE*)pResult)[1] - pos; - FX_FILESIZE SavedPos = m_Syntax.SavePos(); - m_Syntax.RestorePos(pos); - bForm = m_Syntax.SearchMultiWord(FX_BSTRC("/Form\0stream"), TRUE, size) == 0; - m_Syntax.RestorePos(SavedPos); +FX_BOOL CPDF_Parser::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm) { + bForm = FALSE; + if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) { + return TRUE; + } + if (m_V5Type[objnum] == 0) { return TRUE; + } + if (m_V5Type[objnum] == 2) { + return TRUE; + } + FX_FILESIZE pos = m_CrossRef[objnum]; + void* pResult = + FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), + sizeof(FX_FILESIZE), _CompareFileSize); + if (pResult == NULL) { + return TRUE; + } + if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)m_SortedOffset.GetData() == + m_SortedOffset.GetSize() - 1) { + return FALSE; + } + FX_FILESIZE size = ((FX_FILESIZE*)pResult)[1] - pos; + FX_FILESIZE SavedPos = m_Syntax.SavePos(); + m_Syntax.RestorePos(pos); + bForm = m_Syntax.SearchMultiWord(FX_BSTRC("/Form\0stream"), TRUE, size) == 0; + m_Syntax.RestorePos(SavedPos); + return TRUE; } -CPDF_Object* CPDF_Parser::ParseIndirectObject(CPDF_IndirectObjects* pObjList, FX_DWORD objnum, PARSE_CONTEXT* pContext) -{ - if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) { - return NULL; - } - if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) { - FX_FILESIZE pos = m_CrossRef[objnum]; - if (pos <= 0) { - return NULL; - } - return ParseIndirectObjectAt(pObjList, pos, objnum, pContext); - } - if (m_V5Type[objnum] == 2) { - CPDF_StreamAcc* pObjStream = GetObjectStream((FX_DWORD)m_CrossRef[objnum]); - if (pObjStream == NULL) { - return NULL; - } - int32_t n = pObjStream->GetDict()->GetInteger(FX_BSTRC("N")); - int32_t offset = pObjStream->GetDict()->GetInteger(FX_BSTRC("First")); - CPDF_SyntaxParser syntax; - CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream((uint8_t*)pObjStream->GetData(), (size_t)pObjStream->GetSize(), FALSE)); - syntax.InitParser(file.Get(), 0); - CPDF_Object* pRet = NULL; - while (n) { - FX_DWORD thisnum = syntax.GetDirectNum(); - FX_DWORD thisoff = syntax.GetDirectNum(); - if (thisnum == objnum) { - syntax.RestorePos(offset + thisoff); - pRet = syntax.GetObject(pObjList, 0, 0, pContext); - break; - } - n --; - } - return pRet; - } +CPDF_Object* CPDF_Parser::ParseIndirectObject(CPDF_IndirectObjects* pObjList, + FX_DWORD objnum, + PARSE_CONTEXT* pContext) { + if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) { return NULL; -} -CPDF_StreamAcc* CPDF_Parser::GetObjectStream(FX_DWORD objnum) -{ - CPDF_StreamAcc* pStreamAcc = NULL; - if (m_ObjectStreamMap.Lookup((void*)(uintptr_t)objnum, (void*&)pStreamAcc)) { - return pStreamAcc; - } - const CPDF_Stream* pStream = m_pDocument ? (CPDF_Stream*)m_pDocument->GetIndirectObject(objnum) : NULL; - if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM) { - return NULL; + } + if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) { + FX_FILESIZE pos = m_CrossRef[objnum]; + if (pos <= 0) { + return NULL; + } + return ParseIndirectObjectAt(pObjList, pos, objnum, pContext); + } + if (m_V5Type[objnum] == 2) { + CPDF_StreamAcc* pObjStream = GetObjectStream((FX_DWORD)m_CrossRef[objnum]); + if (pObjStream == NULL) { + return NULL; + } + int32_t n = pObjStream->GetDict()->GetInteger(FX_BSTRC("N")); + int32_t offset = pObjStream->GetDict()->GetInteger(FX_BSTRC("First")); + CPDF_SyntaxParser syntax; + CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream( + (uint8_t*)pObjStream->GetData(), (size_t)pObjStream->GetSize(), FALSE)); + syntax.InitParser(file.Get(), 0); + CPDF_Object* pRet = NULL; + while (n) { + FX_DWORD thisnum = syntax.GetDirectNum(); + FX_DWORD thisoff = syntax.GetDirectNum(); + if (thisnum == objnum) { + syntax.RestorePos(offset + thisoff); + pRet = syntax.GetObject(pObjList, 0, 0, pContext); + break; + } + n--; } - pStreamAcc = new CPDF_StreamAcc; - pStreamAcc->LoadAllData(pStream); - m_ObjectStreamMap.SetAt((void*)(uintptr_t)objnum, pStreamAcc); + return pRet; + } + return NULL; +} +CPDF_StreamAcc* CPDF_Parser::GetObjectStream(FX_DWORD objnum) { + CPDF_StreamAcc* pStreamAcc = NULL; + if (m_ObjectStreamMap.Lookup((void*)(uintptr_t)objnum, (void*&)pStreamAcc)) { return pStreamAcc; + } + const CPDF_Stream* pStream = + m_pDocument ? (CPDF_Stream*)m_pDocument->GetIndirectObject(objnum) : NULL; + if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM) { + return NULL; + } + pStreamAcc = new CPDF_StreamAcc; + pStreamAcc->LoadAllData(pStream); + m_ObjectStreamMap.SetAt((void*)(uintptr_t)objnum, pStreamAcc); + return pStreamAcc; } -FX_FILESIZE CPDF_Parser::GetObjectSize(FX_DWORD objnum) -{ - if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) { - return 0; - } - if (m_V5Type[objnum] == 2) { - objnum = (FX_DWORD)m_CrossRef[objnum]; +FX_FILESIZE CPDF_Parser::GetObjectSize(FX_DWORD objnum) { + if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) { + return 0; + } + if (m_V5Type[objnum] == 2) { + objnum = (FX_DWORD)m_CrossRef[objnum]; + } + if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) { + FX_FILESIZE offset = m_CrossRef[objnum]; + if (offset == 0) { + return 0; + } + void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), + m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), + _CompareFileSize); + if (pResult == NULL) { + return 0; } - if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) { - FX_FILESIZE offset = m_CrossRef[objnum]; - if (offset == 0) { - return 0; - } - void* pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); - if (pResult == NULL) { - return 0; - } - if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)m_SortedOffset.GetData() == m_SortedOffset.GetSize() - 1) { - return 0; - } - return ((FX_FILESIZE*)pResult)[1] - offset; + if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)m_SortedOffset.GetData() == + m_SortedOffset.GetSize() - 1) { + return 0; } - return 0; + return ((FX_FILESIZE*)pResult)[1] - offset; + } + return 0; } -void CPDF_Parser::GetIndirectBinary(FX_DWORD objnum, uint8_t*& pBuffer, FX_DWORD& size) -{ - pBuffer = NULL; - size = 0; - if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) { - return; - } - if (m_V5Type[objnum] == 2) { - CPDF_StreamAcc* pObjStream = GetObjectStream((FX_DWORD)m_CrossRef[objnum]); - if (pObjStream == NULL) { - return; - } - int32_t n = pObjStream->GetDict()->GetInteger(FX_BSTRC("N")); - int32_t offset = pObjStream->GetDict()->GetInteger(FX_BSTRC("First")); - CPDF_SyntaxParser syntax; - const uint8_t* pData = pObjStream->GetData(); - FX_DWORD totalsize = pObjStream->GetSize(); - CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream((uint8_t*)pData, (size_t)totalsize, FALSE)); - syntax.InitParser(file.Get(), 0); - while (n) { - FX_DWORD thisnum = syntax.GetDirectNum(); - FX_DWORD thisoff = syntax.GetDirectNum(); - if (thisnum == objnum) { - if (n == 1) { - size = totalsize - (thisoff + offset); - } else { - syntax.GetDirectNum(); // Skip nextnum. - FX_DWORD nextoff = syntax.GetDirectNum(); - size = nextoff - thisoff; - } - pBuffer = FX_Alloc(uint8_t, size); - FXSYS_memcpy(pBuffer, pData + thisoff + offset, size); - return; - } - n --; +void CPDF_Parser::GetIndirectBinary(FX_DWORD objnum, + uint8_t*& pBuffer, + FX_DWORD& size) { + pBuffer = NULL; + size = 0; + if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) { + return; + } + if (m_V5Type[objnum] == 2) { + CPDF_StreamAcc* pObjStream = GetObjectStream((FX_DWORD)m_CrossRef[objnum]); + if (pObjStream == NULL) { + return; + } + int32_t n = pObjStream->GetDict()->GetInteger(FX_BSTRC("N")); + int32_t offset = pObjStream->GetDict()->GetInteger(FX_BSTRC("First")); + CPDF_SyntaxParser syntax; + const uint8_t* pData = pObjStream->GetData(); + FX_DWORD totalsize = pObjStream->GetSize(); + CFX_SmartPointer<IFX_FileStream> file( + FX_CreateMemoryStream((uint8_t*)pData, (size_t)totalsize, FALSE)); + syntax.InitParser(file.Get(), 0); + while (n) { + FX_DWORD thisnum = syntax.GetDirectNum(); + FX_DWORD thisoff = syntax.GetDirectNum(); + if (thisnum == objnum) { + if (n == 1) { + size = totalsize - (thisoff + offset); + } else { + syntax.GetDirectNum(); // Skip nextnum. + FX_DWORD nextoff = syntax.GetDirectNum(); + size = nextoff - thisoff; } + pBuffer = FX_Alloc(uint8_t, size); + FXSYS_memcpy(pBuffer, pData + thisoff + offset, size); return; + } + n--; } - if (m_V5Type[objnum] == 1) { - FX_FILESIZE pos = m_CrossRef[objnum]; - if (pos == 0) { - return; - } - FX_FILESIZE SavedPos = m_Syntax.SavePos(); - m_Syntax.RestorePos(pos); - FX_BOOL bIsNumber; - CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); - if (!bIsNumber) { - m_Syntax.RestorePos(SavedPos); - return; - } - FX_DWORD parser_objnum = FXSYS_atoi(word); - if (parser_objnum && parser_objnum != objnum) { - m_Syntax.RestorePos(SavedPos); - return; - } - word = m_Syntax.GetNextWord(bIsNumber); - if (!bIsNumber) { - m_Syntax.RestorePos(SavedPos); - return; - } - if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) { - m_Syntax.RestorePos(SavedPos); - return; - } - void* pResult = FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); - if (pResult == NULL) { - m_Syntax.RestorePos(SavedPos); - return; - } - FX_FILESIZE nextoff = ((FX_FILESIZE*)pResult)[1]; - FX_BOOL bNextOffValid = FALSE; - if (nextoff != pos) { - m_Syntax.RestorePos(nextoff); - word = m_Syntax.GetNextWord(bIsNumber); - if (word == FX_BSTRC("xref")) { - bNextOffValid = TRUE; - } else if (bIsNumber) { - word = m_Syntax.GetNextWord(bIsNumber); - if (bIsNumber && m_Syntax.GetKeyword() == FX_BSTRC("obj")) { - bNextOffValid = TRUE; - } - } - } - if (!bNextOffValid) { - m_Syntax.RestorePos(pos); - while (1) { - if (m_Syntax.GetKeyword() == FX_BSTRC("endobj")) { - break; - } - if (m_Syntax.SavePos() == m_Syntax.m_FileLen) { - break; - } - } - nextoff = m_Syntax.SavePos(); - } - size = (FX_DWORD)(nextoff - pos); - pBuffer = FX_Alloc(uint8_t, size); - m_Syntax.RestorePos(pos); - m_Syntax.ReadBlock(pBuffer, size); - m_Syntax.RestorePos(SavedPos); + return; + } + if (m_V5Type[objnum] == 1) { + FX_FILESIZE pos = m_CrossRef[objnum]; + if (pos == 0) { + return; } -} -CPDF_Object* CPDF_Parser::ParseIndirectObjectAt(CPDF_IndirectObjects* pObjList, FX_FILESIZE pos, FX_DWORD objnum, - PARSE_CONTEXT* pContext) -{ FX_FILESIZE SavedPos = m_Syntax.SavePos(); m_Syntax.RestorePos(pos); FX_BOOL bIsNumber; CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); if (!bIsNumber) { - m_Syntax.RestorePos(SavedPos); - return NULL; + m_Syntax.RestorePos(SavedPos); + return; } - FX_FILESIZE objOffset = m_Syntax.SavePos(); - objOffset -= word.GetLength(); FX_DWORD parser_objnum = FXSYS_atoi(word); - if (objnum && parser_objnum != objnum) { - m_Syntax.RestorePos(SavedPos); - return NULL; + if (parser_objnum && parser_objnum != objnum) { + m_Syntax.RestorePos(SavedPos); + return; } word = m_Syntax.GetNextWord(bIsNumber); if (!bIsNumber) { - m_Syntax.RestorePos(SavedPos); - return NULL; + m_Syntax.RestorePos(SavedPos); + return; } - FX_DWORD parser_gennum = FXSYS_atoi(word); if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) { - m_Syntax.RestorePos(SavedPos); - return NULL; + m_Syntax.RestorePos(SavedPos); + return; } - CPDF_Object* pObj = m_Syntax.GetObject(pObjList, objnum, parser_gennum, pContext); - m_Syntax.SavePos(); - CFX_ByteString bsWord = m_Syntax.GetKeyword(); - if (bsWord == FX_BSTRC("endobj")) { - m_Syntax.SavePos(); + void* pResult = + FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), + sizeof(FX_FILESIZE), _CompareFileSize); + if (pResult == NULL) { + m_Syntax.RestorePos(SavedPos); + return; + } + FX_FILESIZE nextoff = ((FX_FILESIZE*)pResult)[1]; + FX_BOOL bNextOffValid = FALSE; + if (nextoff != pos) { + m_Syntax.RestorePos(nextoff); + word = m_Syntax.GetNextWord(bIsNumber); + if (word == FX_BSTRC("xref")) { + bNextOffValid = TRUE; + } else if (bIsNumber) { + word = m_Syntax.GetNextWord(bIsNumber); + if (bIsNumber && m_Syntax.GetKeyword() == FX_BSTRC("obj")) { + bNextOffValid = TRUE; + } + } } - m_Syntax.RestorePos(SavedPos); - if (pObj) { - if (!objnum) { - pObj->m_ObjNum = parser_objnum; + if (!bNextOffValid) { + m_Syntax.RestorePos(pos); + while (1) { + if (m_Syntax.GetKeyword() == FX_BSTRC("endobj")) { + break; } - pObj->m_GenNum = parser_gennum; + if (m_Syntax.SavePos() == m_Syntax.m_FileLen) { + break; + } + } + nextoff = m_Syntax.SavePos(); } - return pObj; -} -CPDF_Object* CPDF_Parser::ParseIndirectObjectAtByStrict(CPDF_IndirectObjects* pObjList, FX_FILESIZE pos, FX_DWORD objnum, - struct PARSE_CONTEXT* pContext, FX_FILESIZE *pResultPos) -{ - FX_FILESIZE SavedPos = m_Syntax.SavePos(); + size = (FX_DWORD)(nextoff - pos); + pBuffer = FX_Alloc(uint8_t, size); m_Syntax.RestorePos(pos); - FX_BOOL bIsNumber; - CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); - if (!bIsNumber) { - m_Syntax.RestorePos(SavedPos); - return NULL; - } - FX_DWORD parser_objnum = FXSYS_atoi(word); - if (objnum && parser_objnum != objnum) { - m_Syntax.RestorePos(SavedPos); - return NULL; - } - word = m_Syntax.GetNextWord(bIsNumber); - if (!bIsNumber) { - m_Syntax.RestorePos(SavedPos); - return NULL; - } - FX_DWORD gennum = FXSYS_atoi(word); - if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) { - m_Syntax.RestorePos(SavedPos); - return NULL; - } - CPDF_Object* pObj = m_Syntax.GetObjectByStrict(pObjList, objnum, gennum, pContext); - if (pResultPos) { - *pResultPos = m_Syntax.m_Pos; - } + m_Syntax.ReadBlock(pBuffer, size); m_Syntax.RestorePos(SavedPos); - return pObj; + } } -CPDF_Dictionary* CPDF_Parser::LoadTrailerV4() -{ - if (m_Syntax.GetKeyword() != FX_BSTRC("trailer")) { - return NULL; - } - CPDF_Object* pObj = m_Syntax.GetObject(m_pDocument, 0, 0, 0); - if (pObj == NULL || pObj->GetType() != PDFOBJ_DICTIONARY) { - if (pObj) { - pObj->Release(); - } - return NULL; - } - return (CPDF_Dictionary*)pObj; +CPDF_Object* CPDF_Parser::ParseIndirectObjectAt(CPDF_IndirectObjects* pObjList, + FX_FILESIZE pos, + FX_DWORD objnum, + PARSE_CONTEXT* pContext) { + FX_FILESIZE SavedPos = m_Syntax.SavePos(); + m_Syntax.RestorePos(pos); + FX_BOOL bIsNumber; + CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); + if (!bIsNumber) { + m_Syntax.RestorePos(SavedPos); + return NULL; + } + FX_FILESIZE objOffset = m_Syntax.SavePos(); + objOffset -= word.GetLength(); + FX_DWORD parser_objnum = FXSYS_atoi(word); + if (objnum && parser_objnum != objnum) { + m_Syntax.RestorePos(SavedPos); + return NULL; + } + word = m_Syntax.GetNextWord(bIsNumber); + if (!bIsNumber) { + m_Syntax.RestorePos(SavedPos); + return NULL; + } + FX_DWORD parser_gennum = FXSYS_atoi(word); + if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) { + m_Syntax.RestorePos(SavedPos); + return NULL; + } + CPDF_Object* pObj = + m_Syntax.GetObject(pObjList, objnum, parser_gennum, pContext); + m_Syntax.SavePos(); + CFX_ByteString bsWord = m_Syntax.GetKeyword(); + if (bsWord == FX_BSTRC("endobj")) { + m_Syntax.SavePos(); + } + m_Syntax.RestorePos(SavedPos); + if (pObj) { + if (!objnum) { + pObj->m_ObjNum = parser_objnum; + } + pObj->m_GenNum = parser_gennum; + } + return pObj; } -FX_DWORD CPDF_Parser::GetPermissions(FX_BOOL bCheckRevision) -{ - if (m_pSecurityHandler == NULL) { - return (FX_DWORD) - 1; - } - FX_DWORD dwPermission = m_pSecurityHandler->GetPermissions(); - if (m_pEncryptDict && m_pEncryptDict->GetString(FX_BSTRC("Filter")) == FX_BSTRC("Standard")) { - dwPermission &= 0xFFFFFFFC; - dwPermission |= 0xFFFFF0C0; - if(bCheckRevision && m_pEncryptDict->GetInteger(FX_BSTRC("R")) == 2) { - dwPermission &= 0xFFFFF0FF; - } +CPDF_Object* CPDF_Parser::ParseIndirectObjectAtByStrict( + CPDF_IndirectObjects* pObjList, + FX_FILESIZE pos, + FX_DWORD objnum, + struct PARSE_CONTEXT* pContext, + FX_FILESIZE* pResultPos) { + FX_FILESIZE SavedPos = m_Syntax.SavePos(); + m_Syntax.RestorePos(pos); + FX_BOOL bIsNumber; + CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); + if (!bIsNumber) { + m_Syntax.RestorePos(SavedPos); + return NULL; + } + FX_DWORD parser_objnum = FXSYS_atoi(word); + if (objnum && parser_objnum != objnum) { + m_Syntax.RestorePos(SavedPos); + return NULL; + } + word = m_Syntax.GetNextWord(bIsNumber); + if (!bIsNumber) { + m_Syntax.RestorePos(SavedPos); + return NULL; + } + FX_DWORD gennum = FXSYS_atoi(word); + if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) { + m_Syntax.RestorePos(SavedPos); + return NULL; + } + CPDF_Object* pObj = + m_Syntax.GetObjectByStrict(pObjList, objnum, gennum, pContext); + if (pResultPos) { + *pResultPos = m_Syntax.m_Pos; + } + m_Syntax.RestorePos(SavedPos); + return pObj; +} +CPDF_Dictionary* CPDF_Parser::LoadTrailerV4() { + if (m_Syntax.GetKeyword() != FX_BSTRC("trailer")) { + return NULL; + } + CPDF_Object* pObj = m_Syntax.GetObject(m_pDocument, 0, 0, 0); + if (pObj == NULL || pObj->GetType() != PDFOBJ_DICTIONARY) { + if (pObj) { + pObj->Release(); } - return dwPermission; + return NULL; + } + return (CPDF_Dictionary*)pObj; } -FX_BOOL CPDF_Parser::IsOwner() -{ - return m_pSecurityHandler == NULL ? TRUE : m_pSecurityHandler->IsOwner(); +FX_DWORD CPDF_Parser::GetPermissions(FX_BOOL bCheckRevision) { + if (m_pSecurityHandler == NULL) { + return (FX_DWORD)-1; + } + FX_DWORD dwPermission = m_pSecurityHandler->GetPermissions(); + if (m_pEncryptDict && + m_pEncryptDict->GetString(FX_BSTRC("Filter")) == FX_BSTRC("Standard")) { + dwPermission &= 0xFFFFFFFC; + dwPermission |= 0xFFFFF0C0; + if (bCheckRevision && m_pEncryptDict->GetInteger(FX_BSTRC("R")) == 2) { + dwPermission &= 0xFFFFF0FF; + } + } + return dwPermission; } -void CPDF_Parser::SetSecurityHandler(CPDF_SecurityHandler* pSecurityHandler, FX_BOOL bForced) -{ - ASSERT(m_pSecurityHandler == NULL); - if (!m_bForceUseSecurityHandler) { - delete m_pSecurityHandler; - m_pSecurityHandler = NULL; - } - m_bForceUseSecurityHandler = bForced; - m_pSecurityHandler = pSecurityHandler; - if (m_bForceUseSecurityHandler) { - return; - } - m_Syntax.m_pCryptoHandler = pSecurityHandler->CreateCryptoHandler(); - m_Syntax.m_pCryptoHandler->Init(NULL, pSecurityHandler); +FX_BOOL CPDF_Parser::IsOwner() { + return m_pSecurityHandler == NULL ? TRUE : m_pSecurityHandler->IsOwner(); } -FX_BOOL CPDF_Parser::IsLinearizedFile(IFX_FileRead* pFileAccess, FX_DWORD offset) -{ - m_Syntax.InitParser(pFileAccess, offset); - m_Syntax.RestorePos(m_Syntax.m_HeaderOffset + 9); - FX_FILESIZE SavedPos = m_Syntax.SavePos(); - FX_BOOL bIsNumber; - CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); - if (!bIsNumber) { - return FALSE; - } - FX_DWORD objnum = FXSYS_atoi(word); - word = m_Syntax.GetNextWord(bIsNumber); - if (!bIsNumber) { - return FALSE; - } - FX_DWORD gennum = FXSYS_atoi(word); - if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) { - m_Syntax.RestorePos(SavedPos); - return FALSE; - } - m_pLinearized = m_Syntax.GetObject(NULL, objnum, gennum, 0); - if (!m_pLinearized) { - return FALSE; - } - if (m_pLinearized->GetDict() && m_pLinearized->GetDict()->GetElement(FX_BSTRC("Linearized"))) { - m_Syntax.GetNextWord(bIsNumber); - CPDF_Object *pLen = m_pLinearized->GetDict()->GetElement(FX_BSTRC("L")); - if (!pLen) { - m_pLinearized->Release(); - m_pLinearized = NULL; - return FALSE; - } - if (pLen->GetInteger() != (int)pFileAccess->GetSize()) { - return FALSE; - } - CPDF_Object *pNo = m_pLinearized->GetDict()->GetElement(FX_BSTRC("P")); - if (pNo && pNo->GetType() == PDFOBJ_NUMBER) { - m_dwFirstPageNo = pNo->GetInteger(); - } - CPDF_Object *pTable = m_pLinearized->GetDict()->GetElement(FX_BSTRC("T")); - if (pTable && pTable->GetType() == PDFOBJ_NUMBER) { - m_LastXRefOffset = pTable->GetInteger(); - } - return TRUE; - } - m_pLinearized->Release(); - m_pLinearized = NULL; +void CPDF_Parser::SetSecurityHandler(CPDF_SecurityHandler* pSecurityHandler, + FX_BOOL bForced) { + ASSERT(m_pSecurityHandler == NULL); + if (!m_bForceUseSecurityHandler) { + delete m_pSecurityHandler; + m_pSecurityHandler = NULL; + } + m_bForceUseSecurityHandler = bForced; + m_pSecurityHandler = pSecurityHandler; + if (m_bForceUseSecurityHandler) { + return; + } + m_Syntax.m_pCryptoHandler = pSecurityHandler->CreateCryptoHandler(); + m_Syntax.m_pCryptoHandler->Init(NULL, pSecurityHandler); +} +FX_BOOL CPDF_Parser::IsLinearizedFile(IFX_FileRead* pFileAccess, + FX_DWORD offset) { + m_Syntax.InitParser(pFileAccess, offset); + m_Syntax.RestorePos(m_Syntax.m_HeaderOffset + 9); + FX_FILESIZE SavedPos = m_Syntax.SavePos(); + FX_BOOL bIsNumber; + CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber); + if (!bIsNumber) { return FALSE; + } + FX_DWORD objnum = FXSYS_atoi(word); + word = m_Syntax.GetNextWord(bIsNumber); + if (!bIsNumber) { + return FALSE; + } + FX_DWORD gennum = FXSYS_atoi(word); + if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) { + m_Syntax.RestorePos(SavedPos); + return FALSE; + } + m_pLinearized = m_Syntax.GetObject(NULL, objnum, gennum, 0); + if (!m_pLinearized) { + return FALSE; + } + if (m_pLinearized->GetDict() && + m_pLinearized->GetDict()->GetElement(FX_BSTRC("Linearized"))) { + m_Syntax.GetNextWord(bIsNumber); + CPDF_Object* pLen = m_pLinearized->GetDict()->GetElement(FX_BSTRC("L")); + if (!pLen) { + m_pLinearized->Release(); + m_pLinearized = NULL; + return FALSE; + } + if (pLen->GetInteger() != (int)pFileAccess->GetSize()) { + return FALSE; + } + CPDF_Object* pNo = m_pLinearized->GetDict()->GetElement(FX_BSTRC("P")); + if (pNo && pNo->GetType() == PDFOBJ_NUMBER) { + m_dwFirstPageNo = pNo->GetInteger(); + } + CPDF_Object* pTable = m_pLinearized->GetDict()->GetElement(FX_BSTRC("T")); + if (pTable && pTable->GetType() == PDFOBJ_NUMBER) { + m_LastXRefOffset = pTable->GetInteger(); + } + return TRUE; + } + m_pLinearized->Release(); + m_pLinearized = NULL; + return FALSE; } -FX_DWORD CPDF_Parser::StartAsynParse(IFX_FileRead* pFileAccess, FX_BOOL bReParse, FX_BOOL bOwnFileRead) -{ - CloseParser(bReParse); - m_bXRefStream = FALSE; +FX_DWORD CPDF_Parser::StartAsynParse(IFX_FileRead* pFileAccess, + FX_BOOL bReParse, + FX_BOOL bOwnFileRead) { + CloseParser(bReParse); + m_bXRefStream = FALSE; + m_LastXRefOffset = 0; + m_bOwnFileRead = bOwnFileRead; + int32_t offset = GetHeaderOffset(pFileAccess); + if (offset == -1) { + return PDFPARSE_ERROR_FORMAT; + } + if (!IsLinearizedFile(pFileAccess, offset)) { + m_Syntax.m_pFileAccess = NULL; + return StartParse(pFileAccess, bReParse, bOwnFileRead); + } + if (!bReParse) { + m_pDocument = new CPDF_Document(this); + } + FX_FILESIZE dwFirstXRefOffset = m_Syntax.SavePos(); + FX_BOOL bXRefRebuilt = FALSE; + FX_BOOL bLoadV4 = FALSE; + if (!(bLoadV4 = LoadCrossRefV4(dwFirstXRefOffset, 0, FALSE, FALSE)) && + !LoadCrossRefV5(dwFirstXRefOffset, dwFirstXRefOffset, TRUE)) { + if (!RebuildCrossRef()) { + return PDFPARSE_ERROR_FORMAT; + } + bXRefRebuilt = TRUE; m_LastXRefOffset = 0; - m_bOwnFileRead = bOwnFileRead; - int32_t offset = GetHeaderOffset(pFileAccess); - if (offset == -1) { - return PDFPARSE_ERROR_FORMAT; - } - if (!IsLinearizedFile(pFileAccess, offset)) { - m_Syntax.m_pFileAccess = NULL; - return StartParse(pFileAccess, bReParse, bOwnFileRead); - } - if (!bReParse) { - m_pDocument = new CPDF_Document(this); + } + if (bLoadV4) { + m_pTrailer = LoadTrailerV4(); + if (m_pTrailer == NULL) { + return FALSE; } - FX_FILESIZE dwFirstXRefOffset = m_Syntax.SavePos(); - FX_BOOL bXRefRebuilt = FALSE; - FX_BOOL bLoadV4 = FALSE; - if (!(bLoadV4 = LoadCrossRefV4(dwFirstXRefOffset, 0, FALSE, FALSE)) && !LoadCrossRefV5(dwFirstXRefOffset, dwFirstXRefOffset, TRUE)) { - if (!RebuildCrossRef()) { - return PDFPARSE_ERROR_FORMAT; - } - bXRefRebuilt = TRUE; - m_LastXRefOffset = 0; + int32_t xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size")); + if (xrefsize > 0) { + m_CrossRef.SetSize(xrefsize); + m_V5Type.SetSize(xrefsize); + } + } + FX_DWORD dwRet = SetEncryptHandler(); + if (dwRet != PDFPARSE_ERROR_SUCCESS) { + return dwRet; + } + m_pDocument->LoadAsynDoc(m_pLinearized->GetDict()); + if (m_pDocument->GetRoot() == NULL || m_pDocument->GetPageCount() == 0) { + if (bXRefRebuilt) { + return PDFPARSE_ERROR_FORMAT; } - if (bLoadV4) { - m_pTrailer = LoadTrailerV4(); - if (m_pTrailer == NULL) { - return FALSE; - } - int32_t xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size")); - if (xrefsize > 0) { - m_CrossRef.SetSize(xrefsize); - m_V5Type.SetSize(xrefsize); - } + ReleaseEncryptHandler(); + if (!RebuildCrossRef()) { + return PDFPARSE_ERROR_FORMAT; } - FX_DWORD dwRet = SetEncryptHandler(); + dwRet = SetEncryptHandler(); if (dwRet != PDFPARSE_ERROR_SUCCESS) { - return dwRet; + return dwRet; } m_pDocument->LoadAsynDoc(m_pLinearized->GetDict()); - if (m_pDocument->GetRoot() == NULL || m_pDocument->GetPageCount() == 0) { - if (bXRefRebuilt) { - return PDFPARSE_ERROR_FORMAT; - } - ReleaseEncryptHandler(); - if (!RebuildCrossRef()) { - return PDFPARSE_ERROR_FORMAT; - } - dwRet = SetEncryptHandler(); - if (dwRet != PDFPARSE_ERROR_SUCCESS) { - return dwRet; - } - m_pDocument->LoadAsynDoc(m_pLinearized->GetDict()); - if (m_pDocument->GetRoot() == NULL) { - return PDFPARSE_ERROR_FORMAT; - } - } - FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); - FX_DWORD RootObjNum = GetRootObjNum(); + if (m_pDocument->GetRoot() == NULL) { + return PDFPARSE_ERROR_FORMAT; + } + } + FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(), + sizeof(FX_FILESIZE), _CompareFileSize); + FX_DWORD RootObjNum = GetRootObjNum(); + if (RootObjNum == 0) { + ReleaseEncryptHandler(); + RebuildCrossRef(); + RootObjNum = GetRootObjNum(); if (RootObjNum == 0) { - ReleaseEncryptHandler(); - RebuildCrossRef(); - RootObjNum = GetRootObjNum(); - if (RootObjNum == 0) { - return PDFPARSE_ERROR_FORMAT; - } - dwRet = SetEncryptHandler(); - if (dwRet != PDFPARSE_ERROR_SUCCESS) { - return dwRet; - } + return PDFPARSE_ERROR_FORMAT; } - if (m_pSecurityHandler && m_pSecurityHandler->IsMetadataEncrypted()) { - CPDF_Object* pMetadata = m_pDocument->GetRoot()->GetElement(FX_BSTRC("Metadata")); - if (pMetadata && pMetadata->GetType() == PDFOBJ_REFERENCE) { - m_Syntax.m_MetadataObjnum = ((CPDF_Reference*) pMetadata)->GetRefObjNum(); - } + dwRet = SetEncryptHandler(); + if (dwRet != PDFPARSE_ERROR_SUCCESS) { + return dwRet; + } + } + if (m_pSecurityHandler && m_pSecurityHandler->IsMetadataEncrypted()) { + CPDF_Object* pMetadata = + m_pDocument->GetRoot()->GetElement(FX_BSTRC("Metadata")); + if (pMetadata && pMetadata->GetType() == PDFOBJ_REFERENCE) { + m_Syntax.m_MetadataObjnum = ((CPDF_Reference*)pMetadata)->GetRefObjNum(); } - return PDFPARSE_ERROR_SUCCESS; + } + return PDFPARSE_ERROR_SUCCESS; } -FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV5(FX_FILESIZE xrefpos) -{ +FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV5(FX_FILESIZE xrefpos) { + if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) { + return FALSE; + } + while (xrefpos) if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) { - return FALSE; + return FALSE; } - while (xrefpos) - if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) { - return FALSE; - } - m_ObjectStreamMap.InitHashTable(101, FALSE); - m_bXRefStream = TRUE; - return TRUE; + m_ObjectStreamMap.InitHashTable(101, FALSE); + m_bXRefStream = TRUE; + return TRUE; } -FX_DWORD CPDF_Parser::LoadLinearizedMainXRefTable() -{ - FX_DWORD dwSaveMetadataObjnum = m_Syntax.m_MetadataObjnum; - m_Syntax.m_MetadataObjnum = 0; - if (m_pTrailer) { - m_pTrailer->Release(); - m_pTrailer = NULL; - } - m_Syntax.RestorePos(m_LastXRefOffset - m_Syntax.m_HeaderOffset); - uint8_t ch = 0; - FX_DWORD dwCount = 0; - m_Syntax.GetNextChar(ch); - int32_t type = PDF_CharType[ch]; - while (type == 'W') { - ++dwCount; - if (m_Syntax.m_FileLen >= (FX_FILESIZE)(m_Syntax.SavePos() + m_Syntax.m_HeaderOffset)) { - break; - } - m_Syntax.GetNextChar(ch); - type = PDF_CharType[ch]; - } - m_LastXRefOffset += dwCount; - FX_POSITION pos = m_ObjectStreamMap.GetStartPosition(); - while (pos) { - void* objnum; - CPDF_StreamAcc* pStream; - m_ObjectStreamMap.GetNextAssoc(pos, objnum, (void*&)pStream); - delete pStream; - } - m_ObjectStreamMap.RemoveAll(); - if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) && !LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) { - m_LastXRefOffset = 0; - m_Syntax.m_MetadataObjnum = dwSaveMetadataObjnum; - return PDFPARSE_ERROR_FORMAT; +FX_DWORD CPDF_Parser::LoadLinearizedMainXRefTable() { + FX_DWORD dwSaveMetadataObjnum = m_Syntax.m_MetadataObjnum; + m_Syntax.m_MetadataObjnum = 0; + if (m_pTrailer) { + m_pTrailer->Release(); + m_pTrailer = NULL; + } + m_Syntax.RestorePos(m_LastXRefOffset - m_Syntax.m_HeaderOffset); + uint8_t ch = 0; + FX_DWORD dwCount = 0; + m_Syntax.GetNextChar(ch); + int32_t type = PDF_CharType[ch]; + while (type == 'W') { + ++dwCount; + if (m_Syntax.m_FileLen >= + (FX_FILESIZE)(m_Syntax.SavePos() + m_Syntax.m_HeaderOffset)) { + break; } - FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); + m_Syntax.GetNextChar(ch); + type = PDF_CharType[ch]; + } + m_LastXRefOffset += dwCount; + FX_POSITION pos = m_ObjectStreamMap.GetStartPosition(); + while (pos) { + void* objnum; + CPDF_StreamAcc* pStream; + m_ObjectStreamMap.GetNextAssoc(pos, objnum, (void*&)pStream); + delete pStream; + } + m_ObjectStreamMap.RemoveAll(); + if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) && + !LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) { + m_LastXRefOffset = 0; m_Syntax.m_MetadataObjnum = dwSaveMetadataObjnum; - return PDFPARSE_ERROR_SUCCESS; + return PDFPARSE_ERROR_FORMAT; + } + FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(), + sizeof(FX_FILESIZE), _CompareFileSize); + m_Syntax.m_MetadataObjnum = dwSaveMetadataObjnum; + return PDFPARSE_ERROR_SUCCESS; } // static int CPDF_SyntaxParser::s_CurrentRecursionDepth = 0; -CPDF_SyntaxParser::CPDF_SyntaxParser() -{ - m_pFileAccess = NULL; - m_pCryptoHandler = NULL; - m_pFileBuf = NULL; - m_BufSize = CPDF_ModuleMgr::kFileBufSize; - m_pFileBuf = NULL; - m_MetadataObjnum = 0; - m_dwWordPos = 0; - m_bFileStream = FALSE; +CPDF_SyntaxParser::CPDF_SyntaxParser() { + m_pFileAccess = NULL; + m_pCryptoHandler = NULL; + m_pFileBuf = NULL; + m_BufSize = CPDF_ModuleMgr::kFileBufSize; + m_pFileBuf = NULL; + m_MetadataObjnum = 0; + m_dwWordPos = 0; + m_bFileStream = FALSE; } -CPDF_SyntaxParser::~CPDF_SyntaxParser() -{ - if (m_pFileBuf) { - FX_Free(m_pFileBuf); - } +CPDF_SyntaxParser::~CPDF_SyntaxParser() { + if (m_pFileBuf) { + FX_Free(m_pFileBuf); + } } -FX_BOOL CPDF_SyntaxParser::GetCharAt(FX_FILESIZE pos, uint8_t& ch) -{ - FX_FILESIZE save_pos = m_Pos; - m_Pos = pos; - FX_BOOL ret = GetNextChar(ch); - m_Pos = save_pos; - return ret; +FX_BOOL CPDF_SyntaxParser::GetCharAt(FX_FILESIZE pos, uint8_t& ch) { + FX_FILESIZE save_pos = m_Pos; + m_Pos = pos; + FX_BOOL ret = GetNextChar(ch); + m_Pos = save_pos; + return ret; } -FX_BOOL CPDF_SyntaxParser::GetNextChar(uint8_t& ch) -{ - FX_FILESIZE pos = m_Pos + m_HeaderOffset; - if (pos >= m_FileLen) { - return FALSE; - } - if (m_BufOffset >= pos || (FX_FILESIZE)(m_BufOffset + m_BufSize) <= pos) { - FX_FILESIZE read_pos = pos; - FX_DWORD read_size = m_BufSize; - if ((FX_FILESIZE)read_size > m_FileLen) { - read_size = (FX_DWORD)m_FileLen; - } - if ((FX_FILESIZE)(read_pos + read_size) > m_FileLen) { - if (m_FileLen < (FX_FILESIZE)read_size) { - read_pos = 0; - read_size = (FX_DWORD)m_FileLen; - } else { - read_pos = m_FileLen - read_size; - } - } - if (!m_pFileAccess->ReadBlock(m_pFileBuf, read_pos, read_size)) { - return FALSE; - } - m_BufOffset = read_pos; - } - ch = m_pFileBuf[pos - m_BufOffset]; - m_Pos ++; - return TRUE; +FX_BOOL CPDF_SyntaxParser::GetNextChar(uint8_t& ch) { + FX_FILESIZE pos = m_Pos + m_HeaderOffset; + if (pos >= m_FileLen) { + return FALSE; + } + if (m_BufOffset >= pos || (FX_FILESIZE)(m_BufOffset + m_BufSize) <= pos) { + FX_FILESIZE read_pos = pos; + FX_DWORD read_size = m_BufSize; + if ((FX_FILESIZE)read_size > m_FileLen) { + read_size = (FX_DWORD)m_FileLen; + } + if ((FX_FILESIZE)(read_pos + read_size) > m_FileLen) { + if (m_FileLen < (FX_FILESIZE)read_size) { + read_pos = 0; + read_size = (FX_DWORD)m_FileLen; + } else { + read_pos = m_FileLen - read_size; + } + } + if (!m_pFileAccess->ReadBlock(m_pFileBuf, read_pos, read_size)) { + return FALSE; + } + m_BufOffset = read_pos; + } + ch = m_pFileBuf[pos - m_BufOffset]; + m_Pos++; + return TRUE; } -FX_BOOL CPDF_SyntaxParser::GetCharAtBackward(FX_FILESIZE pos, uint8_t& ch) -{ - pos += m_HeaderOffset; - if (pos >= m_FileLen) { - return FALSE; - } - if (m_BufOffset >= pos || (FX_FILESIZE)(m_BufOffset + m_BufSize) <= pos) { - FX_FILESIZE read_pos; - if (pos < (FX_FILESIZE)m_BufSize) { - read_pos = 0; - } else { - read_pos = pos - m_BufSize + 1; - } - FX_DWORD read_size = m_BufSize; - if ((FX_FILESIZE)(read_pos + read_size) > m_FileLen) { - if (m_FileLen < (FX_FILESIZE)read_size) { - read_pos = 0; - read_size = (FX_DWORD)m_FileLen; - } else { - read_pos = m_FileLen - read_size; - } - } - if (!m_pFileAccess->ReadBlock(m_pFileBuf, read_pos, read_size)) { - return FALSE; - } - m_BufOffset = read_pos; - } - ch = m_pFileBuf[pos - m_BufOffset]; - return TRUE; +FX_BOOL CPDF_SyntaxParser::GetCharAtBackward(FX_FILESIZE pos, uint8_t& ch) { + pos += m_HeaderOffset; + if (pos >= m_FileLen) { + return FALSE; + } + if (m_BufOffset >= pos || (FX_FILESIZE)(m_BufOffset + m_BufSize) <= pos) { + FX_FILESIZE read_pos; + if (pos < (FX_FILESIZE)m_BufSize) { + read_pos = 0; + } else { + read_pos = pos - m_BufSize + 1; + } + FX_DWORD read_size = m_BufSize; + if ((FX_FILESIZE)(read_pos + read_size) > m_FileLen) { + if (m_FileLen < (FX_FILESIZE)read_size) { + read_pos = 0; + read_size = (FX_DWORD)m_FileLen; + } else { + read_pos = m_FileLen - read_size; + } + } + if (!m_pFileAccess->ReadBlock(m_pFileBuf, read_pos, read_size)) { + return FALSE; + } + m_BufOffset = read_pos; + } + ch = m_pFileBuf[pos - m_BufOffset]; + return TRUE; } -FX_BOOL CPDF_SyntaxParser::ReadBlock(uint8_t* pBuf, FX_DWORD size) -{ - if (!m_pFileAccess->ReadBlock(pBuf, m_Pos + m_HeaderOffset, size)) { - return FALSE; - } - m_Pos += size; - return TRUE; +FX_BOOL CPDF_SyntaxParser::ReadBlock(uint8_t* pBuf, FX_DWORD size) { + if (!m_pFileAccess->ReadBlock(pBuf, m_Pos + m_HeaderOffset, size)) { + return FALSE; + } + m_Pos += size; + return TRUE; } #define MAX_WORD_BUFFER 256 -void CPDF_SyntaxParser::GetNextWord() -{ - m_WordSize = 0; - m_bIsNumber = TRUE; - uint8_t ch; - if (!GetNextChar(ch)) { +void CPDF_SyntaxParser::GetNextWord() { + m_WordSize = 0; + m_bIsNumber = TRUE; + uint8_t ch; + if (!GetNextChar(ch)) { + return; + } + uint8_t type = PDF_CharType[ch]; + while (1) { + while (type == 'W') { + if (!GetNextChar(ch)) { return; + } + type = PDF_CharType[ch]; + } + if (ch != '%') { + break; } - uint8_t type = PDF_CharType[ch]; while (1) { - while (type == 'W') { - if (!GetNextChar(ch)) { - return; - } - type = PDF_CharType[ch]; + if (!GetNextChar(ch)) { + return; + } + if (ch == '\r' || ch == '\n') { + break; + } + } + type = PDF_CharType[ch]; + } + if (type == 'D') { + m_bIsNumber = FALSE; + m_WordBuffer[m_WordSize++] = ch; + if (ch == '/') { + while (1) { + if (!GetNextChar(ch)) { + return; } - if (ch != '%') { - break; + type = PDF_CharType[ch]; + if (type != 'R' && type != 'N') { + m_Pos--; + return; } - while (1) { - if (!GetNextChar(ch)) { - return; - } - if (ch == '\r' || ch == '\n') { - break; - } + if (m_WordSize < MAX_WORD_BUFFER) { + m_WordBuffer[m_WordSize++] = ch; } - type = PDF_CharType[ch]; - } - if (type == 'D') { - m_bIsNumber = FALSE; + } + } else if (ch == '<') { + if (!GetNextChar(ch)) { + return; + } + if (ch == '<') { m_WordBuffer[m_WordSize++] = ch; - if (ch == '/') { - while (1) { - if (!GetNextChar(ch)) { - return; - } - type = PDF_CharType[ch]; - if (type != 'R' && type != 'N') { - m_Pos --; - return; - } - if (m_WordSize < MAX_WORD_BUFFER) { - m_WordBuffer[m_WordSize++] = ch; - } - } - } else if (ch == '<') { - if (!GetNextChar(ch)) { - return; - } - if (ch == '<') { - m_WordBuffer[m_WordSize++] = ch; - } else { - m_Pos --; - } - } else if (ch == '>') { - if (!GetNextChar(ch)) { - return; - } - if (ch == '>') { - m_WordBuffer[m_WordSize++] = ch; - } else { - m_Pos --; - } - } + } else { + m_Pos--; + } + } else if (ch == '>') { + if (!GetNextChar(ch)) { return; + } + if (ch == '>') { + m_WordBuffer[m_WordSize++] = ch; + } else { + m_Pos--; + } } - while (1) { - if (m_WordSize < MAX_WORD_BUFFER) { - m_WordBuffer[m_WordSize++] = ch; - } - if (type != 'N') { - m_bIsNumber = FALSE; - } - if (!GetNextChar(ch)) { - return; - } - type = PDF_CharType[ch]; - if (type == 'D' || type == 'W') { - m_Pos --; - break; - } + return; + } + while (1) { + if (m_WordSize < MAX_WORD_BUFFER) { + m_WordBuffer[m_WordSize++] = ch; + } + if (type != 'N') { + m_bIsNumber = FALSE; } -} -CFX_ByteString CPDF_SyntaxParser::ReadString() -{ - uint8_t ch; if (!GetNextChar(ch)) { - return CFX_ByteString(); + return; } - CFX_ByteTextBuf buf; - int32_t parlevel = 0; - int32_t status = 0, iEscCode = 0; - while (1) { - switch (status) { - case 0: - if (ch == ')') { - if (parlevel == 0) { - return buf.GetByteString(); - } - parlevel --; - buf.AppendChar(')'); - } else if (ch == '(') { - parlevel ++; - buf.AppendChar('('); - } else if (ch == '\\') { - status = 1; - } else { - buf.AppendChar(ch); - } - break; - case 1: - if (ch >= '0' && ch <= '7') { - iEscCode = ch - '0'; - status = 2; - break; - } - if (ch == 'n') { - buf.AppendChar('\n'); - } else if (ch == 'r') { - buf.AppendChar('\r'); - } else if (ch == 't') { - buf.AppendChar('\t'); - } else if (ch == 'b') { - buf.AppendChar('\b'); - } else if (ch == 'f') { - buf.AppendChar('\f'); - } else if (ch == '\r') { - status = 4; - break; - } else if (ch == '\n') { - } else { - buf.AppendChar(ch); - } - status = 0; - break; - case 2: - if (ch >= '0' && ch <= '7') { - iEscCode = iEscCode * 8 + ch - '0'; - status = 3; - } else { - buf.AppendChar(iEscCode); - status = 0; - continue; - } - break; - case 3: - if (ch >= '0' && ch <= '7') { - iEscCode = iEscCode * 8 + ch - '0'; - buf.AppendChar(iEscCode); - status = 0; - } else { - buf.AppendChar(iEscCode); - status = 0; - continue; - } - break; - case 4: - status = 0; - if (ch != '\n') { - continue; - } - break; + type = PDF_CharType[ch]; + if (type == 'D' || type == 'W') { + m_Pos--; + break; + } + } +} +CFX_ByteString CPDF_SyntaxParser::ReadString() { + uint8_t ch; + if (!GetNextChar(ch)) { + return CFX_ByteString(); + } + CFX_ByteTextBuf buf; + int32_t parlevel = 0; + int32_t status = 0, iEscCode = 0; + while (1) { + switch (status) { + case 0: + if (ch == ')') { + if (parlevel == 0) { + return buf.GetByteString(); + } + parlevel--; + buf.AppendChar(')'); + } else if (ch == '(') { + parlevel++; + buf.AppendChar('('); + } else if (ch == '\\') { + status = 1; + } else { + buf.AppendChar(ch); + } + break; + case 1: + if (ch >= '0' && ch <= '7') { + iEscCode = ch - '0'; + status = 2; + break; + } + if (ch == 'n') { + buf.AppendChar('\n'); + } else if (ch == 'r') { + buf.AppendChar('\r'); + } else if (ch == 't') { + buf.AppendChar('\t'); + } else if (ch == 'b') { + buf.AppendChar('\b'); + } else if (ch == 'f') { + buf.AppendChar('\f'); + } else if (ch == '\r') { + status = 4; + break; + } else if (ch == '\n') { + } else { + buf.AppendChar(ch); + } + status = 0; + break; + case 2: + if (ch >= '0' && ch <= '7') { + iEscCode = iEscCode * 8 + ch - '0'; + status = 3; + } else { + buf.AppendChar(iEscCode); + status = 0; + continue; + } + break; + case 3: + if (ch >= '0' && ch <= '7') { + iEscCode = iEscCode * 8 + ch - '0'; + buf.AppendChar(iEscCode); + status = 0; + } else { + buf.AppendChar(iEscCode); + status = 0; + continue; } - if (!GetNextChar(ch)) { - break; + break; + case 4: + status = 0; + if (ch != '\n') { + continue; } + break; } - GetNextChar(ch); - return buf.GetByteString(); -} -CFX_ByteString CPDF_SyntaxParser::ReadHexString() -{ - uint8_t ch; if (!GetNextChar(ch)) { - return CFX_ByteString(); + break; } - CFX_BinaryBuf buf; - FX_BOOL bFirst = TRUE; - uint8_t code = 0; - while (1) { - if (ch == '>') { - break; - } - if (ch >= '0' && ch <= '9') { - if (bFirst) { - code = (ch - '0') * 16; - } else { - code += ch - '0'; - buf.AppendByte((uint8_t)code); - } - bFirst = !bFirst; - } else if (ch >= 'A' && ch <= 'F') { - if (bFirst) { - code = (ch - 'A' + 10) * 16; - } else { - code += ch - 'A' + 10; - buf.AppendByte((uint8_t)code); - } - bFirst = !bFirst; - } else if (ch >= 'a' && ch <= 'f') { - if (bFirst) { - code = (ch - 'a' + 10) * 16; - } else { - code += ch - 'a' + 10; - buf.AppendByte((uint8_t)code); - } - bFirst = !bFirst; - } - if (!GetNextChar(ch)) { - break; - } + } + GetNextChar(ch); + return buf.GetByteString(); +} +CFX_ByteString CPDF_SyntaxParser::ReadHexString() { + uint8_t ch; + if (!GetNextChar(ch)) { + return CFX_ByteString(); + } + CFX_BinaryBuf buf; + FX_BOOL bFirst = TRUE; + uint8_t code = 0; + while (1) { + if (ch == '>') { + break; } - if (!bFirst) { + if (ch >= '0' && ch <= '9') { + if (bFirst) { + code = (ch - '0') * 16; + } else { + code += ch - '0'; + buf.AppendByte((uint8_t)code); + } + bFirst = !bFirst; + } else if (ch >= 'A' && ch <= 'F') { + if (bFirst) { + code = (ch - 'A' + 10) * 16; + } else { + code += ch - 'A' + 10; buf.AppendByte((uint8_t)code); + } + bFirst = !bFirst; + } else if (ch >= 'a' && ch <= 'f') { + if (bFirst) { + code = (ch - 'a' + 10) * 16; + } else { + code += ch - 'a' + 10; + buf.AppendByte((uint8_t)code); + } + bFirst = !bFirst; } - return buf.GetByteString(); -} -void CPDF_SyntaxParser::ToNextLine() -{ - uint8_t ch; - while (GetNextChar(ch)) { - if (ch == '\n') { - break; - } - if (ch == '\r') { - GetNextChar(ch); - if (ch != '\n') { - --m_Pos; - } - break; - } + if (!GetNextChar(ch)) { + break; } + } + if (!bFirst) { + buf.AppendByte((uint8_t)code); + } + return buf.GetByteString(); } -void CPDF_SyntaxParser::ToNextWord() -{ - uint8_t ch; - if (!GetNextChar(ch)) { +void CPDF_SyntaxParser::ToNextLine() { + uint8_t ch; + while (GetNextChar(ch)) { + if (ch == '\n') { + break; + } + if (ch == '\r') { + GetNextChar(ch); + if (ch != '\n') { + --m_Pos; + } + break; + } + } +} +void CPDF_SyntaxParser::ToNextWord() { + uint8_t ch; + if (!GetNextChar(ch)) { + return; + } + uint8_t type = PDF_CharType[ch]; + while (1) { + while (type == 'W') { + m_dwWordPos = m_Pos; + if (!GetNextChar(ch)) { return; + } + type = PDF_CharType[ch]; } - uint8_t type = PDF_CharType[ch]; - while (1) { - while (type == 'W') { - m_dwWordPos = m_Pos; - if (!GetNextChar(ch)) { - return; - } - type = PDF_CharType[ch]; - } - if (ch != '%') { - break; - } - while (1) { - if (!GetNextChar(ch)) { - return; - } - if (ch == '\r' || ch == '\n') { - break; - } - } - type = PDF_CharType[ch]; + if (ch != '%') { + break; } - m_Pos --; + while (1) { + if (!GetNextChar(ch)) { + return; + } + if (ch == '\r' || ch == '\n') { + break; + } + } + type = PDF_CharType[ch]; + } + m_Pos--; } -CFX_ByteString CPDF_SyntaxParser::GetNextWord(FX_BOOL& bIsNumber) -{ - GetNextWord(); - bIsNumber = m_bIsNumber; - return CFX_ByteString((const FX_CHAR*)m_WordBuffer, m_WordSize); +CFX_ByteString CPDF_SyntaxParser::GetNextWord(FX_BOOL& bIsNumber) { + GetNextWord(); + bIsNumber = m_bIsNumber; + return CFX_ByteString((const FX_CHAR*)m_WordBuffer, m_WordSize); } -CFX_ByteString CPDF_SyntaxParser::GetKeyword() -{ - GetNextWord(); - return CFX_ByteString((const FX_CHAR*)m_WordBuffer, m_WordSize); +CFX_ByteString CPDF_SyntaxParser::GetKeyword() { + GetNextWord(); + return CFX_ByteString((const FX_CHAR*)m_WordBuffer, m_WordSize); } -CPDF_Object* CPDF_SyntaxParser::GetObject(CPDF_IndirectObjects* pObjList, FX_DWORD objnum, FX_DWORD gennum, PARSE_CONTEXT* pContext, FX_BOOL bDecrypt) -{ - CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth); - if (++s_CurrentRecursionDepth > kParserMaxRecursionDepth) { - return NULL; +CPDF_Object* CPDF_SyntaxParser::GetObject(CPDF_IndirectObjects* pObjList, + FX_DWORD objnum, + FX_DWORD gennum, + PARSE_CONTEXT* pContext, + FX_BOOL bDecrypt) { + CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth); + if (++s_CurrentRecursionDepth > kParserMaxRecursionDepth) { + return NULL; + } + FX_FILESIZE SavedPos = m_Pos; + FX_BOOL bTypeOnly = pContext && (pContext->m_Flags & PDFPARSE_TYPEONLY); + FX_BOOL bIsNumber; + CFX_ByteString word = GetNextWord(bIsNumber); + if (word.GetLength() == 0) { + if (bTypeOnly) { + return (CPDF_Object*)PDFOBJ_INVALID; } + return NULL; + } + if (bIsNumber) { FX_FILESIZE SavedPos = m_Pos; - FX_BOOL bTypeOnly = pContext && (pContext->m_Flags & PDFPARSE_TYPEONLY); - FX_BOOL bIsNumber; - CFX_ByteString word = GetNextWord(bIsNumber); - if (word.GetLength() == 0) { - if (bTypeOnly) { - return (CPDF_Object*)PDFOBJ_INVALID; - } - return NULL; - } + CFX_ByteString nextword = GetNextWord(bIsNumber); if (bIsNumber) { - FX_FILESIZE SavedPos = m_Pos; - CFX_ByteString nextword = GetNextWord(bIsNumber); - if (bIsNumber) { - CFX_ByteString nextword2 = GetNextWord(bIsNumber); - if (nextword2 == FX_BSTRC("R")) { - FX_DWORD objnum = FXSYS_atoi(word); - if (bTypeOnly) { - return (CPDF_Object*)PDFOBJ_REFERENCE; - } - return new CPDF_Reference(pObjList, objnum); - } - } - m_Pos = SavedPos; + CFX_ByteString nextword2 = GetNextWord(bIsNumber); + if (nextword2 == FX_BSTRC("R")) { + FX_DWORD objnum = FXSYS_atoi(word); if (bTypeOnly) { - return (CPDF_Object*)PDFOBJ_NUMBER; + return (CPDF_Object*)PDFOBJ_REFERENCE; } - return CPDF_Number::Create(word); + return new CPDF_Reference(pObjList, objnum); + } } - if (word == FX_BSTRC("true") || word == FX_BSTRC("false")) { - if (bTypeOnly) { - return (CPDF_Object*)PDFOBJ_BOOLEAN; - } - return CPDF_Boolean::Create(word == FX_BSTRC("true")); + m_Pos = SavedPos; + if (bTypeOnly) { + return (CPDF_Object*)PDFOBJ_NUMBER; } - if (word == FX_BSTRC("null")) { - if (bTypeOnly) { - return (CPDF_Object*)PDFOBJ_NULL; - } - return CPDF_Null::Create(); + return CPDF_Number::Create(word); + } + if (word == FX_BSTRC("true") || word == FX_BSTRC("false")) { + if (bTypeOnly) { + return (CPDF_Object*)PDFOBJ_BOOLEAN; } - if (word == FX_BSTRC("(")) { - if (bTypeOnly) { - return (CPDF_Object*)PDFOBJ_STRING; - } - CFX_ByteString str = ReadString(); - if (m_pCryptoHandler && bDecrypt) { - m_pCryptoHandler->Decrypt(objnum, gennum, str); - } - return CPDF_String::Create(str, FALSE); + return CPDF_Boolean::Create(word == FX_BSTRC("true")); + } + if (word == FX_BSTRC("null")) { + if (bTypeOnly) { + return (CPDF_Object*)PDFOBJ_NULL; } - if (word == FX_BSTRC("<")) { - if (bTypeOnly) { - return (CPDF_Object*)PDFOBJ_STRING; - } - CFX_ByteString str = ReadHexString(); - if (m_pCryptoHandler && bDecrypt) { - m_pCryptoHandler->Decrypt(objnum, gennum, str); - } - return CPDF_String::Create(str, TRUE); + return CPDF_Null::Create(); + } + if (word == FX_BSTRC("(")) { + if (bTypeOnly) { + return (CPDF_Object*)PDFOBJ_STRING; } - if (word == FX_BSTRC("[")) { - if (bTypeOnly) { - return (CPDF_Object*)PDFOBJ_ARRAY; - } - CPDF_Array* pArray = CPDF_Array::Create(); - while (1) { - CPDF_Object* pObj = GetObject(pObjList, objnum, gennum); - if (pObj == NULL) { - return pArray; - } - pArray->Add(pObj); - } + CFX_ByteString str = ReadString(); + if (m_pCryptoHandler && bDecrypt) { + m_pCryptoHandler->Decrypt(objnum, gennum, str); } - if (word[0] == '/') { - if (bTypeOnly) { - return (CPDF_Object*)PDFOBJ_NAME; - } - return CPDF_Name::Create( - PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))); + return CPDF_String::Create(str, FALSE); + } + if (word == FX_BSTRC("<")) { + if (bTypeOnly) { + return (CPDF_Object*)PDFOBJ_STRING; } - if (word == FX_BSTRC("<<")) { - if (bTypeOnly) { - return (CPDF_Object*)PDFOBJ_DICTIONARY; - } - if (pContext) { - pContext->m_DictStart = SavedPos; - } - CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); - int32_t nKeys = 0; - FX_FILESIZE dwSignValuePos = 0; - while (1) { - FX_BOOL bIsNumber; - CFX_ByteString key = GetNextWord(bIsNumber); - if (key.IsEmpty()) { - if (pDict) - pDict->Release(); - return NULL; - } - FX_FILESIZE SavedPos = m_Pos - key.GetLength(); - if (key == FX_BSTRC(">>")) { - break; - } - if (key == FX_BSTRC("endobj")) { - m_Pos = SavedPos; - break; - } - if (key[0] != '/') { - continue; - } - nKeys ++; - key = PDF_NameDecode(key); - if (key == FX_BSTRC("/Contents")) { - dwSignValuePos = m_Pos; - } - CPDF_Object* pObj = GetObject(pObjList, objnum, gennum); - if (pObj == NULL) { - continue; - } - if (key.GetLength() >= 1) { - if (nKeys < 32) { - pDict->SetAt(CFX_ByteStringC(key.c_str() + 1, key.GetLength() - 1), pObj); - } else { - pDict->AddValue(CFX_ByteStringC(key.c_str() + 1, key.GetLength() - 1), pObj); - } - } - } - if (IsSignatureDict(pDict)) { - FX_FILESIZE dwSavePos = m_Pos; - m_Pos = dwSignValuePos; - CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, NULL, FALSE); - pDict->SetAt(FX_BSTRC("Contents"), pObj); - m_Pos = dwSavePos; - } - if (pContext) { - pContext->m_DictEnd = m_Pos; - if (pContext->m_Flags & PDFPARSE_NOSTREAM) { - return pDict; - } - } - FX_FILESIZE SavedPos = m_Pos; - FX_BOOL bIsNumber; - CFX_ByteString nextword = GetNextWord(bIsNumber); - if (nextword == FX_BSTRC("stream")) { - CPDF_Stream* pStream = ReadStream(pDict, pContext, objnum, gennum); - if (pStream) { - return pStream; - } - if (pDict) - pDict->Release(); - return NULL; - } else { - m_Pos = SavedPos; - return pDict; - } + CFX_ByteString str = ReadHexString(); + if (m_pCryptoHandler && bDecrypt) { + m_pCryptoHandler->Decrypt(objnum, gennum, str); } - if (word == FX_BSTRC(">>")) { - m_Pos = SavedPos; - return NULL; + return CPDF_String::Create(str, TRUE); + } + if (word == FX_BSTRC("[")) { + if (bTypeOnly) { + return (CPDF_Object*)PDFOBJ_ARRAY; } + CPDF_Array* pArray = CPDF_Array::Create(); + while (1) { + CPDF_Object* pObj = GetObject(pObjList, objnum, gennum); + if (pObj == NULL) { + return pArray; + } + pArray->Add(pObj); + } + } + if (word[0] == '/') { if (bTypeOnly) { - return (CPDF_Object*)PDFOBJ_INVALID; + return (CPDF_Object*)PDFOBJ_NAME; } - return NULL; -} -CPDF_Object* CPDF_SyntaxParser::GetObjectByStrict(CPDF_IndirectObjects* pObjList, FX_DWORD objnum, FX_DWORD gennum, struct PARSE_CONTEXT* pContext) -{ - CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth); - if (++s_CurrentRecursionDepth > kParserMaxRecursionDepth) { + return CPDF_Name::Create( + PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))); + } + if (word == FX_BSTRC("<<")) { + if (bTypeOnly) { + return (CPDF_Object*)PDFOBJ_DICTIONARY; + } + if (pContext) { + pContext->m_DictStart = SavedPos; + } + CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); + int32_t nKeys = 0; + FX_FILESIZE dwSignValuePos = 0; + while (1) { + FX_BOOL bIsNumber; + CFX_ByteString key = GetNextWord(bIsNumber); + if (key.IsEmpty()) { + if (pDict) + pDict->Release(); return NULL; + } + FX_FILESIZE SavedPos = m_Pos - key.GetLength(); + if (key == FX_BSTRC(">>")) { + break; + } + if (key == FX_BSTRC("endobj")) { + m_Pos = SavedPos; + break; + } + if (key[0] != '/') { + continue; + } + nKeys++; + key = PDF_NameDecode(key); + if (key == FX_BSTRC("/Contents")) { + dwSignValuePos = m_Pos; + } + CPDF_Object* pObj = GetObject(pObjList, objnum, gennum); + if (pObj == NULL) { + continue; + } + if (key.GetLength() >= 1) { + if (nKeys < 32) { + pDict->SetAt(CFX_ByteStringC(key.c_str() + 1, key.GetLength() - 1), + pObj); + } else { + pDict->AddValue(CFX_ByteStringC(key.c_str() + 1, key.GetLength() - 1), + pObj); + } + } + } + if (IsSignatureDict(pDict)) { + FX_FILESIZE dwSavePos = m_Pos; + m_Pos = dwSignValuePos; + CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, NULL, FALSE); + pDict->SetAt(FX_BSTRC("Contents"), pObj); + m_Pos = dwSavePos; + } + if (pContext) { + pContext->m_DictEnd = m_Pos; + if (pContext->m_Flags & PDFPARSE_NOSTREAM) { + return pDict; + } } FX_FILESIZE SavedPos = m_Pos; - FX_BOOL bTypeOnly = pContext && (pContext->m_Flags & PDFPARSE_TYPEONLY); FX_BOOL bIsNumber; - CFX_ByteString word = GetNextWord(bIsNumber); - if (word.GetLength() == 0) { - if (bTypeOnly) { - return (CPDF_Object*)PDFOBJ_INVALID; - } - return NULL; + CFX_ByteString nextword = GetNextWord(bIsNumber); + if (nextword == FX_BSTRC("stream")) { + CPDF_Stream* pStream = ReadStream(pDict, pContext, objnum, gennum); + if (pStream) { + return pStream; + } + if (pDict) + pDict->Release(); + return NULL; + } else { + m_Pos = SavedPos; + return pDict; } + } + if (word == FX_BSTRC(">>")) { + m_Pos = SavedPos; + return NULL; + } + if (bTypeOnly) { + return (CPDF_Object*)PDFOBJ_INVALID; + } + return NULL; +} +CPDF_Object* CPDF_SyntaxParser::GetObjectByStrict( + CPDF_IndirectObjects* pObjList, + FX_DWORD objnum, + FX_DWORD gennum, + struct PARSE_CONTEXT* pContext) { + CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth); + if (++s_CurrentRecursionDepth > kParserMaxRecursionDepth) { + return NULL; + } + FX_FILESIZE SavedPos = m_Pos; + FX_BOOL bTypeOnly = pContext && (pContext->m_Flags & PDFPARSE_TYPEONLY); + FX_BOOL bIsNumber; + CFX_ByteString word = GetNextWord(bIsNumber); + if (word.GetLength() == 0) { + if (bTypeOnly) { + return (CPDF_Object*)PDFOBJ_INVALID; + } + return NULL; + } + if (bIsNumber) { + FX_FILESIZE SavedPos = m_Pos; + CFX_ByteString nextword = GetNextWord(bIsNumber); if (bIsNumber) { - FX_FILESIZE SavedPos = m_Pos; - CFX_ByteString nextword = GetNextWord(bIsNumber); - if (bIsNumber) { - CFX_ByteString nextword2 = GetNextWord(bIsNumber); - if (nextword2 == FX_BSTRC("R")) { - if (bTypeOnly) { - return (CPDF_Object*)PDFOBJ_REFERENCE; - } - FX_DWORD objnum = FXSYS_atoi(word); - return new CPDF_Reference(pObjList, objnum); - } - } - m_Pos = SavedPos; + CFX_ByteString nextword2 = GetNextWord(bIsNumber); + if (nextword2 == FX_BSTRC("R")) { if (bTypeOnly) { - return (CPDF_Object*)PDFOBJ_NUMBER; + return (CPDF_Object*)PDFOBJ_REFERENCE; } - return CPDF_Number::Create(word); + FX_DWORD objnum = FXSYS_atoi(word); + return new CPDF_Reference(pObjList, objnum); + } } - if (word == FX_BSTRC("true") || word == FX_BSTRC("false")) { - if (bTypeOnly) { - return (CPDF_Object*)PDFOBJ_BOOLEAN; - } - return CPDF_Boolean::Create(word == FX_BSTRC("true")); + m_Pos = SavedPos; + if (bTypeOnly) { + return (CPDF_Object*)PDFOBJ_NUMBER; } - if (word == FX_BSTRC("null")) { - if (bTypeOnly) { - return (CPDF_Object*)PDFOBJ_NULL; - } - return CPDF_Null::Create(); + return CPDF_Number::Create(word); + } + if (word == FX_BSTRC("true") || word == FX_BSTRC("false")) { + if (bTypeOnly) { + return (CPDF_Object*)PDFOBJ_BOOLEAN; } - if (word == FX_BSTRC("(")) { - if (bTypeOnly) { - return (CPDF_Object*)PDFOBJ_STRING; - } - CFX_ByteString str = ReadString(); - if (m_pCryptoHandler) { - m_pCryptoHandler->Decrypt(objnum, gennum, str); - } - return CPDF_String::Create(str, FALSE); + return CPDF_Boolean::Create(word == FX_BSTRC("true")); + } + if (word == FX_BSTRC("null")) { + if (bTypeOnly) { + return (CPDF_Object*)PDFOBJ_NULL; } - if (word == FX_BSTRC("<")) { - if (bTypeOnly) { - return (CPDF_Object*)PDFOBJ_STRING; - } - CFX_ByteString str = ReadHexString(); - if (m_pCryptoHandler) { - m_pCryptoHandler->Decrypt(objnum, gennum, str); - } - return CPDF_String::Create(str, TRUE); + return CPDF_Null::Create(); + } + if (word == FX_BSTRC("(")) { + if (bTypeOnly) { + return (CPDF_Object*)PDFOBJ_STRING; } - if (word == FX_BSTRC("[")) { - if (bTypeOnly) { - return (CPDF_Object*)PDFOBJ_ARRAY; - } - CPDF_Array* pArray = CPDF_Array::Create(); - while (1) { - CPDF_Object* pObj = GetObject(pObjList, objnum, gennum); - if (pObj == NULL) { - if (m_WordBuffer[0] == ']') { - return pArray; - } - if (pArray) { - pArray->Release(); - } - return NULL; - } - pArray->Add(pObj); - } + CFX_ByteString str = ReadString(); + if (m_pCryptoHandler) { + m_pCryptoHandler->Decrypt(objnum, gennum, str); } - if (word[0] == '/') { - if (bTypeOnly) { - return (CPDF_Object*)PDFOBJ_NAME; - } - return CPDF_Name::Create(PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))); + return CPDF_String::Create(str, FALSE); + } + if (word == FX_BSTRC("<")) { + if (bTypeOnly) { + return (CPDF_Object*)PDFOBJ_STRING; } - if (word == FX_BSTRC("<<")) { - if (bTypeOnly) { - return (CPDF_Object*)PDFOBJ_DICTIONARY; - } - if (pContext) { - pContext->m_DictStart = SavedPos; - } - CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); - while (1) { - FX_BOOL bIsNumber; - FX_FILESIZE SavedPos = m_Pos; - CFX_ByteString key = GetNextWord(bIsNumber); - if (key.IsEmpty()) { - if (pDict) { - pDict->Release(); - } - return NULL; - } - if (key == FX_BSTRC(">>")) { - break; - } - if (key == FX_BSTRC("endobj")) { - m_Pos = SavedPos; - break; - } - if (key[0] != '/') { - continue; - } - key = PDF_NameDecode(key); - CPDF_Object* pObj = GetObject(pObjList, objnum, gennum); - if (pObj == NULL) { - if (pDict) { - pDict->Release(); - } - uint8_t ch; - while (1) { - if (!GetNextChar(ch)) { - break; - } - if (ch == 0x0A || ch == 0x0D) { - break; - } - } - return NULL; - } - if (key.GetLength() > 1) { - pDict->AddValue(CFX_ByteStringC(key.c_str() + 1, key.GetLength() - 1), pObj); - } - } - if (pContext) { - pContext->m_DictEnd = m_Pos; - if (pContext->m_Flags & PDFPARSE_NOSTREAM) { - return pDict; - } + CFX_ByteString str = ReadHexString(); + if (m_pCryptoHandler) { + m_pCryptoHandler->Decrypt(objnum, gennum, str); + } + return CPDF_String::Create(str, TRUE); + } + if (word == FX_BSTRC("[")) { + if (bTypeOnly) { + return (CPDF_Object*)PDFOBJ_ARRAY; + } + CPDF_Array* pArray = CPDF_Array::Create(); + while (1) { + CPDF_Object* pObj = GetObject(pObjList, objnum, gennum); + if (pObj == NULL) { + if (m_WordBuffer[0] == ']') { + return pArray; } - FX_FILESIZE SavedPos = m_Pos; - FX_BOOL bIsNumber; - CFX_ByteString nextword = GetNextWord(bIsNumber); - if (nextword == FX_BSTRC("stream")) { - CPDF_Stream* pStream = ReadStream(pDict, pContext, objnum, gennum); - if (pStream) { - return pStream; - } - if (pDict) { - pDict->Release(); - } - return NULL; - } else { - m_Pos = SavedPos; - return pDict; + if (pArray) { + pArray->Release(); } - } - if (word == FX_BSTRC(">>")) { - m_Pos = SavedPos; return NULL; + } + pArray->Add(pObj); } + } + if (word[0] == '/') { if (bTypeOnly) { - return (CPDF_Object*)PDFOBJ_INVALID; + return (CPDF_Object*)PDFOBJ_NAME; } - return NULL; -} -CPDF_Stream* CPDF_SyntaxParser::ReadStream(CPDF_Dictionary* pDict, PARSE_CONTEXT* pContext, - FX_DWORD objnum, FX_DWORD gennum) -{ - CPDF_Object* pLenObj = pDict->GetElement(FX_BSTRC("Length")); - FX_FILESIZE len = 0; - if (pLenObj && ((pLenObj->GetType() != PDFOBJ_REFERENCE) || - ((((CPDF_Reference*)pLenObj)->GetObjList() != NULL) && - ((CPDF_Reference*)pLenObj)->GetRefObjNum() != objnum))) { - len = pLenObj->GetInteger(); + return CPDF_Name::Create( + PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))); + } + if (word == FX_BSTRC("<<")) { + if (bTypeOnly) { + return (CPDF_Object*)PDFOBJ_DICTIONARY; } - - ToNextLine(); - FX_FILESIZE StreamStartPos = m_Pos; if (pContext) { - pContext->m_DataStart = m_Pos; + pContext->m_DictStart = SavedPos; } - - CPDF_CryptoHandler* pCryptoHandler = objnum == (FX_DWORD)m_MetadataObjnum ? NULL : m_pCryptoHandler; - if (pCryptoHandler == NULL) { - pdfium::base::CheckedNumeric<FX_FILESIZE> pos = m_Pos; - pos += len; - if (pos.IsValid() && pos.ValueOrDie() < m_FileLen) { - m_Pos = pos.ValueOrDie(); + CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); + while (1) { + FX_BOOL bIsNumber; + FX_FILESIZE SavedPos = m_Pos; + CFX_ByteString key = GetNextWord(bIsNumber); + if (key.IsEmpty()) { + if (pDict) { + pDict->Release(); } - GetNextWord(); - if (m_WordSize < 9 || FXSYS_memcmp(m_WordBuffer, "endstream", 9)) { - m_Pos = StreamStartPos; - FX_FILESIZE offset = FindTag(FX_BSTRC("endstream"), 0); - if (offset >= 0) { - FX_FILESIZE curPos = m_Pos; - m_Pos = StreamStartPos; - FX_FILESIZE endobjOffset = FindTag(FX_BSTRC("endobj"), 0); - if (endobjOffset < offset && endobjOffset >= 0) { - offset = endobjOffset; - } else { - m_Pos = curPos; - } - uint8_t byte1, byte2; - GetCharAt(StreamStartPos + offset - 1, byte1); - GetCharAt(StreamStartPos + offset - 2, byte2); - if (byte1 == 0x0a && byte2 == 0x0d) { - len -= 2; - } else if (byte1 == 0x0a || byte1 == 0x0d) { - len --; - } - len = (FX_DWORD)offset; - pDict->SetAtInteger(FX_BSTRC("Length"), len); - } else { - m_Pos = StreamStartPos; - if (FindTag(FX_BSTRC("endobj"), 0) < 0) { - return NULL; - } - } + return NULL; + } + if (key == FX_BSTRC(">>")) { + break; + } + if (key == FX_BSTRC("endobj")) { + m_Pos = SavedPos; + break; + } + if (key[0] != '/') { + continue; + } + key = PDF_NameDecode(key); + CPDF_Object* pObj = GetObject(pObjList, objnum, gennum); + if (pObj == NULL) { + if (pDict) { + pDict->Release(); } - m_Pos = StreamStartPos; + uint8_t ch; + while (1) { + if (!GetNextChar(ch)) { + break; + } + if (ch == 0x0A || ch == 0x0D) { + break; + } + } + return NULL; + } + if (key.GetLength() > 1) { + pDict->AddValue(CFX_ByteStringC(key.c_str() + 1, key.GetLength() - 1), + pObj); + } } - CPDF_Stream* pStream; - uint8_t* pData = FX_Alloc(uint8_t, len); - ReadBlock(pData, len); - if (pCryptoHandler) { - CFX_BinaryBuf dest_buf; - dest_buf.EstimateSize(pCryptoHandler->DecryptGetSize(len)); - void* context = pCryptoHandler->DecryptStart(objnum, gennum); - pCryptoHandler->DecryptStream(context, pData, len, dest_buf); - pCryptoHandler->DecryptFinish(context, dest_buf); - FX_Free(pData); - pData = dest_buf.GetBuffer(); - len = dest_buf.GetSize(); - dest_buf.DetachBuffer(); - } - pStream = new CPDF_Stream(pData, len, pDict); if (pContext) { - pContext->m_DataEnd = pContext->m_DataStart + len; + pContext->m_DictEnd = m_Pos; + if (pContext->m_Flags & PDFPARSE_NOSTREAM) { + return pDict; + } + } + FX_FILESIZE SavedPos = m_Pos; + FX_BOOL bIsNumber; + CFX_ByteString nextword = GetNextWord(bIsNumber); + if (nextword == FX_BSTRC("stream")) { + CPDF_Stream* pStream = ReadStream(pDict, pContext, objnum, gennum); + if (pStream) { + return pStream; + } + if (pDict) { + pDict->Release(); + } + return NULL; + } else { + m_Pos = SavedPos; + return pDict; + } + } + if (word == FX_BSTRC(">>")) { + m_Pos = SavedPos; + return NULL; + } + if (bTypeOnly) { + return (CPDF_Object*)PDFOBJ_INVALID; + } + return NULL; +} +CPDF_Stream* CPDF_SyntaxParser::ReadStream(CPDF_Dictionary* pDict, + PARSE_CONTEXT* pContext, + FX_DWORD objnum, + FX_DWORD gennum) { + CPDF_Object* pLenObj = pDict->GetElement(FX_BSTRC("Length")); + FX_FILESIZE len = 0; + if (pLenObj && ((pLenObj->GetType() != PDFOBJ_REFERENCE) || + ((((CPDF_Reference*)pLenObj)->GetObjList() != NULL) && + ((CPDF_Reference*)pLenObj)->GetRefObjNum() != objnum))) { + len = pLenObj->GetInteger(); + } + + ToNextLine(); + FX_FILESIZE StreamStartPos = m_Pos; + if (pContext) { + pContext->m_DataStart = m_Pos; + } + + CPDF_CryptoHandler* pCryptoHandler = + objnum == (FX_DWORD)m_MetadataObjnum ? NULL : m_pCryptoHandler; + if (pCryptoHandler == NULL) { + pdfium::base::CheckedNumeric<FX_FILESIZE> pos = m_Pos; + pos += len; + if (pos.IsValid() && pos.ValueOrDie() < m_FileLen) { + m_Pos = pos.ValueOrDie(); } - StreamStartPos = m_Pos; GetNextWord(); - if (m_WordSize == 6 && 0 == FXSYS_memcmp(m_WordBuffer, "endobj", 6)) { + if (m_WordSize < 9 || FXSYS_memcmp(m_WordBuffer, "endstream", 9)) { + m_Pos = StreamStartPos; + FX_FILESIZE offset = FindTag(FX_BSTRC("endstream"), 0); + if (offset >= 0) { + FX_FILESIZE curPos = m_Pos; m_Pos = StreamStartPos; - } - return pStream; + FX_FILESIZE endobjOffset = FindTag(FX_BSTRC("endobj"), 0); + if (endobjOffset < offset && endobjOffset >= 0) { + offset = endobjOffset; + } else { + m_Pos = curPos; + } + uint8_t byte1, byte2; + GetCharAt(StreamStartPos + offset - 1, byte1); + GetCharAt(StreamStartPos + offset - 2, byte2); + if (byte1 == 0x0a && byte2 == 0x0d) { + len -= 2; + } else if (byte1 == 0x0a || byte1 == 0x0d) { + len--; + } + len = (FX_DWORD)offset; + pDict->SetAtInteger(FX_BSTRC("Length"), len); + } else { + m_Pos = StreamStartPos; + if (FindTag(FX_BSTRC("endobj"), 0) < 0) { + return NULL; + } + } + } + m_Pos = StreamStartPos; + } + CPDF_Stream* pStream; + uint8_t* pData = FX_Alloc(uint8_t, len); + ReadBlock(pData, len); + if (pCryptoHandler) { + CFX_BinaryBuf dest_buf; + dest_buf.EstimateSize(pCryptoHandler->DecryptGetSize(len)); + void* context = pCryptoHandler->DecryptStart(objnum, gennum); + pCryptoHandler->DecryptStream(context, pData, len, dest_buf); + pCryptoHandler->DecryptFinish(context, dest_buf); + FX_Free(pData); + pData = dest_buf.GetBuffer(); + len = dest_buf.GetSize(); + dest_buf.DetachBuffer(); + } + pStream = new CPDF_Stream(pData, len, pDict); + if (pContext) { + pContext->m_DataEnd = pContext->m_DataStart + len; + } + StreamStartPos = m_Pos; + GetNextWord(); + if (m_WordSize == 6 && 0 == FXSYS_memcmp(m_WordBuffer, "endobj", 6)) { + m_Pos = StreamStartPos; + } + return pStream; } -void CPDF_SyntaxParser::InitParser(IFX_FileRead* pFileAccess, FX_DWORD HeaderOffset) -{ - if (m_pFileBuf) { - FX_Free(m_pFileBuf); - m_pFileBuf = NULL; - } - m_pFileBuf = FX_Alloc(uint8_t, m_BufSize); - m_HeaderOffset = HeaderOffset; - m_FileLen = pFileAccess->GetSize(); - m_Pos = 0; - m_pFileAccess = pFileAccess; - m_BufOffset = 0; - pFileAccess->ReadBlock(m_pFileBuf, 0, (size_t)((FX_FILESIZE)m_BufSize > m_FileLen ? m_FileLen : m_BufSize)); +void CPDF_SyntaxParser::InitParser(IFX_FileRead* pFileAccess, + FX_DWORD HeaderOffset) { + if (m_pFileBuf) { + FX_Free(m_pFileBuf); + m_pFileBuf = NULL; + } + m_pFileBuf = FX_Alloc(uint8_t, m_BufSize); + m_HeaderOffset = HeaderOffset; + m_FileLen = pFileAccess->GetSize(); + m_Pos = 0; + m_pFileAccess = pFileAccess; + m_BufOffset = 0; + pFileAccess->ReadBlock( + m_pFileBuf, 0, + (size_t)((FX_FILESIZE)m_BufSize > m_FileLen ? m_FileLen : m_BufSize)); } -int32_t CPDF_SyntaxParser::GetDirectNum() -{ - GetNextWord(); - if (!m_bIsNumber) { - return 0; - } - m_WordBuffer[m_WordSize] = 0; - return FXSYS_atoi((const FX_CHAR*)m_WordBuffer); +int32_t CPDF_SyntaxParser::GetDirectNum() { + GetNextWord(); + if (!m_bIsNumber) { + return 0; + } + m_WordBuffer[m_WordSize] = 0; + return FXSYS_atoi((const FX_CHAR*)m_WordBuffer); } -FX_BOOL CPDF_SyntaxParser::IsWholeWord(FX_FILESIZE startpos, FX_FILESIZE limit, const uint8_t* tag, FX_DWORD taglen) -{ - uint8_t type = PDF_CharType[tag[0]]; - FX_BOOL bCheckLeft = type != 'D' && type != 'W'; - type = PDF_CharType[tag[taglen - 1]]; - FX_BOOL bCheckRight = type != 'D' && type != 'W'; - uint8_t ch; - if (bCheckRight && startpos + (int32_t)taglen <= limit && GetCharAt(startpos + (int32_t)taglen, ch)) { - uint8_t type = PDF_CharType[ch]; - if (type == 'N' || type == 'R') { - return FALSE; - } +FX_BOOL CPDF_SyntaxParser::IsWholeWord(FX_FILESIZE startpos, + FX_FILESIZE limit, + const uint8_t* tag, + FX_DWORD taglen) { + uint8_t type = PDF_CharType[tag[0]]; + FX_BOOL bCheckLeft = type != 'D' && type != 'W'; + type = PDF_CharType[tag[taglen - 1]]; + FX_BOOL bCheckRight = type != 'D' && type != 'W'; + uint8_t ch; + if (bCheckRight && startpos + (int32_t)taglen <= limit && + GetCharAt(startpos + (int32_t)taglen, ch)) { + uint8_t type = PDF_CharType[ch]; + if (type == 'N' || type == 'R') { + return FALSE; } - if (bCheckLeft && startpos > 0 && GetCharAt(startpos - 1, ch)) { - uint8_t type = PDF_CharType[ch]; - if (type == 'N' || type == 'R') { - return FALSE; - } + } + if (bCheckLeft && startpos > 0 && GetCharAt(startpos - 1, ch)) { + uint8_t type = PDF_CharType[ch]; + if (type == 'N' || type == 'R') { + return FALSE; } - return TRUE; + } + return TRUE; } -FX_BOOL CPDF_SyntaxParser::SearchWord(const CFX_ByteStringC& tag, FX_BOOL bWholeWord, FX_BOOL bForward, FX_FILESIZE limit) -{ - int32_t taglen = tag.GetLength(); - if (taglen == 0) { +FX_BOOL CPDF_SyntaxParser::SearchWord(const CFX_ByteStringC& tag, + FX_BOOL bWholeWord, + FX_BOOL bForward, + FX_FILESIZE limit) { + int32_t taglen = tag.GetLength(); + if (taglen == 0) { + return FALSE; + } + FX_FILESIZE pos = m_Pos; + int32_t offset = 0; + if (!bForward) { + offset = taglen - 1; + } + const uint8_t* tag_data = tag.GetPtr(); + uint8_t byte; + while (1) { + if (bForward) { + if (limit) { + if (pos >= m_Pos + limit) { + return FALSE; + } + } + if (!GetCharAt(pos, byte)) { return FALSE; + } + } else { + if (limit) { + if (pos <= m_Pos - limit) { + return FALSE; + } + } + if (!GetCharAtBackward(pos, byte)) { + return FALSE; + } + } + if (byte == tag_data[offset]) { + if (bForward) { + offset++; + if (offset < taglen) { + pos++; + continue; + } + } else { + offset--; + if (offset >= 0) { + pos--; + continue; + } + } + FX_FILESIZE startpos = bForward ? pos - taglen + 1 : pos; + if (!bWholeWord || IsWholeWord(startpos, limit, tag.GetPtr(), taglen)) { + m_Pos = startpos; + return TRUE; + } } - FX_FILESIZE pos = m_Pos; - int32_t offset = 0; - if (!bForward) { - offset = taglen - 1; + if (bForward) { + offset = byte == tag_data[0] ? 1 : 0; + pos++; + } else { + offset = byte == tag_data[taglen - 1] ? taglen - 2 : taglen - 1; + pos--; } - const uint8_t* tag_data = tag.GetPtr(); - uint8_t byte; - while (1) { - if (bForward) { - if (limit) { - if (pos >= m_Pos + limit) { - return FALSE; - } - } - if (!GetCharAt(pos, byte)) { - return FALSE; - } - } else { - if (limit) { - if (pos <= m_Pos - limit) { - return FALSE; - } - } - if (!GetCharAtBackward(pos, byte)) { - return FALSE; - } - } - if (byte == tag_data[offset]) { - if (bForward) { - offset ++; - if (offset < taglen) { - pos ++; - continue; - } - } else { - offset --; - if (offset >= 0) { - pos --; - continue; - } - } - FX_FILESIZE startpos = bForward ? pos - taglen + 1 : pos; - if (!bWholeWord || IsWholeWord(startpos, limit, tag.GetPtr(), taglen)) { - m_Pos = startpos; - return TRUE; - } - } - if (bForward) { - offset = byte == tag_data[0] ? 1 : 0; - pos ++; - } else { - offset = byte == tag_data[taglen - 1] ? taglen - 2 : taglen - 1; - pos --; - } - if (pos < 0) { - return FALSE; - } + if (pos < 0) { + return FALSE; } - return FALSE; + } + return FALSE; } struct _SearchTagRecord { - const uint8_t* m_pTag; - FX_DWORD m_Len; - FX_DWORD m_Offset; + 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 ++) - if (tags[i] == 0) { - ntags ++; - } - _SearchTagRecord* pPatterns = FX_Alloc(_SearchTagRecord, ntags); - FX_DWORD start = 0, itag = 0, max_len = 0; - for (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; - start = i + 1; - 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)) { - found = i; - goto end; - } else { - if (pPatterns[i].m_pTag[0] == byte) { - pPatterns[i].m_Offset = 1; - } else { - pPatterns[i].m_Offset = 0; - } - } - } +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++) + if (tags[i] == 0) { + ntags++; + } + _SearchTagRecord* pPatterns = FX_Alloc(_SearchTagRecord, ntags); + FX_DWORD start = 0, itag = 0, max_len = 0; + for (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; + start = i + 1; + 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)) { + found = i; + goto end; + } else { + if (pPatterns[i].m_pTag[0] == byte) { + pPatterns[i].m_Offset = 1; } else { - if (pPatterns[i].m_pTag[0] == byte) { - pPatterns[i].m_Offset = 1; - } else { - pPatterns[i].m_Offset = 0; - } + pPatterns[i].m_Offset = 0; } + } } - if (limit && pos >= m_Pos + limit) { - goto end; - } - if (!GetCharAt(pos, byte)) { - goto end; + } else { + if (pPatterns[i].m_pTag[0] == byte) { + pPatterns[i].m_Offset = 1; + } else { + pPatterns[i].m_Offset = 0; } - pos ++; + } + } + if (limit && pos >= m_Pos + limit) { + goto end; } + if (!GetCharAt(pos, byte)) { + goto end; + } + pos++; + } end: - FX_Free(pPatterns); - return found; + FX_Free(pPatterns); + return found; } -FX_FILESIZE CPDF_SyntaxParser::FindTag(const CFX_ByteStringC& tag, FX_FILESIZE limit) -{ - int32_t taglen = tag.GetLength(); - int32_t match = 0; - limit += m_Pos; - FX_FILESIZE startpos = m_Pos; - while (1) { - uint8_t ch; - if (!GetNextChar(ch)) { - return -1; - } - if (ch == tag[match]) { - match ++; - if (match == taglen) { - return m_Pos - startpos - taglen; - } - } else { - match = ch == tag[0] ? 1 : 0; - } - if (limit && m_Pos == limit) { - return -1; - } +FX_FILESIZE CPDF_SyntaxParser::FindTag(const CFX_ByteStringC& tag, + FX_FILESIZE limit) { + int32_t taglen = tag.GetLength(); + int32_t match = 0; + limit += m_Pos; + FX_FILESIZE startpos = m_Pos; + while (1) { + uint8_t ch; + if (!GetNextChar(ch)) { + return -1; } - return -1; + if (ch == tag[match]) { + match++; + if (match == taglen) { + return m_Pos - startpos - taglen; + } + } else { + match = ch == tag[0] ? 1 : 0; + } + if (limit && m_Pos == limit) { + return -1; + } + } + return -1; } -void CPDF_SyntaxParser::GetBinary(uint8_t* buffer, FX_DWORD size) -{ - FX_DWORD offset = 0; - uint8_t ch; - while (1) { - if (!GetNextChar(ch)) { - return; - } - buffer[offset++] = ch; - if (offset == size) { - break; - } +void CPDF_SyntaxParser::GetBinary(uint8_t* buffer, FX_DWORD size) { + FX_DWORD offset = 0; + uint8_t ch; + while (1) { + if (!GetNextChar(ch)) { + return; + } + buffer[offset++] = ch; + if (offset == size) { + break; } + } } -class CPDF_DataAvail final : public IPDF_DataAvail -{ -public: - CPDF_DataAvail(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRead); - ~CPDF_DataAvail(); +class CPDF_DataAvail final : public IPDF_DataAvail { + public: + CPDF_DataAvail(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRead); + ~CPDF_DataAvail(); - virtual FX_BOOL IsDocAvail(IFX_DownloadHints* pHints) override; + virtual FX_BOOL IsDocAvail(IFX_DownloadHints* pHints) override; - virtual void SetDocument(CPDF_Document* pDoc) override; + virtual void SetDocument(CPDF_Document* pDoc) override; - virtual FX_BOOL IsPageAvail(int iPage, IFX_DownloadHints* pHints) override; + virtual FX_BOOL IsPageAvail(int iPage, IFX_DownloadHints* pHints) override; - virtual int32_t IsFormAvail(IFX_DownloadHints *pHints) override; + virtual int32_t IsFormAvail(IFX_DownloadHints* pHints) override; - virtual int32_t IsLinearizedPDF() override; + virtual int32_t IsLinearizedPDF() override; - virtual FX_BOOL IsLinearized() override - { - return m_bLinearized; - } + virtual FX_BOOL IsLinearized() override { return m_bLinearized; } - virtual void GetLinearizedMainXRefInfo(FX_FILESIZE *pPos, FX_DWORD *pSize) override; + virtual void GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, + FX_DWORD* pSize) override; -protected: - static const int kMaxDataAvailRecursionDepth = 64; - static int s_CurrentDataAvailRecursionDepth; + protected: + static const int kMaxDataAvailRecursionDepth = 64; + static int s_CurrentDataAvailRecursionDepth; - FX_DWORD GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset); - FX_BOOL IsObjectsAvail(CFX_PtrArray& obj_array, FX_BOOL bParsePage, IFX_DownloadHints* pHints, CFX_PtrArray &ret_array); - FX_BOOL CheckDocStatus(IFX_DownloadHints *pHints); - FX_BOOL CheckHeader(IFX_DownloadHints* pHints); - FX_BOOL CheckFirstPage(IFX_DownloadHints *pHints); - FX_BOOL CheckEnd(IFX_DownloadHints *pHints); - FX_BOOL CheckCrossRef(IFX_DownloadHints* pHints); - FX_BOOL CheckCrossRefItem(IFX_DownloadHints *pHints); - FX_BOOL CheckTrailer(IFX_DownloadHints* pHints); - FX_BOOL CheckRoot(IFX_DownloadHints* pHints); - FX_BOOL CheckInfo(IFX_DownloadHints* pHints); - FX_BOOL CheckPages(IFX_DownloadHints* pHints); - FX_BOOL CheckPage(IFX_DownloadHints* pHints); - FX_BOOL CheckResources(IFX_DownloadHints* pHints); - FX_BOOL CheckAnnots(IFX_DownloadHints* pHints); - FX_BOOL CheckAcroForm(IFX_DownloadHints* pHints); - FX_BOOL CheckAcroFormSubObject(IFX_DownloadHints* pHints); - FX_BOOL CheckTrailerAppend(IFX_DownloadHints* pHints); - FX_BOOL CheckPageStatus(IFX_DownloadHints* pHints); - FX_BOOL CheckAllCrossRefStream(IFX_DownloadHints *pHints); + FX_DWORD GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset); + FX_BOOL IsObjectsAvail(CFX_PtrArray& obj_array, + FX_BOOL bParsePage, + IFX_DownloadHints* pHints, + CFX_PtrArray& ret_array); + FX_BOOL CheckDocStatus(IFX_DownloadHints* pHints); + FX_BOOL CheckHeader(IFX_DownloadHints* pHints); + FX_BOOL CheckFirstPage(IFX_DownloadHints* pHints); + FX_BOOL CheckEnd(IFX_DownloadHints* pHints); + FX_BOOL CheckCrossRef(IFX_DownloadHints* pHints); + FX_BOOL CheckCrossRefItem(IFX_DownloadHints* pHints); + FX_BOOL CheckTrailer(IFX_DownloadHints* pHints); + FX_BOOL CheckRoot(IFX_DownloadHints* pHints); + FX_BOOL CheckInfo(IFX_DownloadHints* pHints); + FX_BOOL CheckPages(IFX_DownloadHints* pHints); + FX_BOOL CheckPage(IFX_DownloadHints* pHints); + FX_BOOL CheckResources(IFX_DownloadHints* pHints); + FX_BOOL CheckAnnots(IFX_DownloadHints* pHints); + FX_BOOL CheckAcroForm(IFX_DownloadHints* pHints); + FX_BOOL CheckAcroFormSubObject(IFX_DownloadHints* pHints); + FX_BOOL CheckTrailerAppend(IFX_DownloadHints* pHints); + FX_BOOL CheckPageStatus(IFX_DownloadHints* pHints); + FX_BOOL CheckAllCrossRefStream(IFX_DownloadHints* pHints); - int32_t CheckCrossRefStream(IFX_DownloadHints *pHints, FX_FILESIZE &xref_offset); - FX_BOOL IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen); - void SetStartOffset(FX_FILESIZE dwOffset); - FX_BOOL GetNextToken(CFX_ByteString &token); - FX_BOOL GetNextChar(uint8_t &ch); - CPDF_Object * ParseIndirectObjectAt(FX_FILESIZE pos, FX_DWORD objnum); - CPDF_Object * GetObject(FX_DWORD objnum, IFX_DownloadHints* pHints, FX_BOOL *pExistInFile); - FX_BOOL GetPageKids(CPDF_Parser *pParser, CPDF_Object *pPages); - FX_BOOL PreparePageItem(); - FX_BOOL LoadPages(IFX_DownloadHints* pHints); - FX_BOOL LoadAllXref(IFX_DownloadHints* pHints); - FX_BOOL LoadAllFile(IFX_DownloadHints* pHints); - FX_BOOL CheckLinearizedData(IFX_DownloadHints* pHints); - FX_BOOL CheckFileResources(IFX_DownloadHints* pHints); - FX_BOOL CheckPageAnnots(int iPage, IFX_DownloadHints* pHints); + int32_t CheckCrossRefStream(IFX_DownloadHints* pHints, + FX_FILESIZE& xref_offset); + FX_BOOL IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen); + void SetStartOffset(FX_FILESIZE dwOffset); + FX_BOOL GetNextToken(CFX_ByteString& token); + FX_BOOL GetNextChar(uint8_t& ch); + CPDF_Object* ParseIndirectObjectAt(FX_FILESIZE pos, FX_DWORD objnum); + CPDF_Object* GetObject(FX_DWORD objnum, + IFX_DownloadHints* pHints, + FX_BOOL* pExistInFile); + FX_BOOL GetPageKids(CPDF_Parser* pParser, CPDF_Object* pPages); + FX_BOOL PreparePageItem(); + FX_BOOL LoadPages(IFX_DownloadHints* pHints); + FX_BOOL LoadAllXref(IFX_DownloadHints* pHints); + FX_BOOL LoadAllFile(IFX_DownloadHints* pHints); + FX_BOOL CheckLinearizedData(IFX_DownloadHints* pHints); + FX_BOOL CheckFileResources(IFX_DownloadHints* pHints); + FX_BOOL CheckPageAnnots(int iPage, IFX_DownloadHints* pHints); - FX_BOOL CheckLinearizedFirstPage(int iPage, IFX_DownloadHints* pHints); - FX_BOOL HaveResourceAncestor(CPDF_Dictionary *pDict); - FX_BOOL CheckPage(int32_t iPage, IFX_DownloadHints* pHints); - FX_BOOL LoadDocPages(IFX_DownloadHints* pHints); - FX_BOOL LoadDocPage(int32_t iPage, IFX_DownloadHints* pHints); - FX_BOOL CheckPageNode(CPDF_PageNode &pageNodes, int32_t iPage, int32_t &iCount, IFX_DownloadHints* pHints); - FX_BOOL CheckUnkownPageNode(FX_DWORD dwPageNo, CPDF_PageNode *pPageNode, IFX_DownloadHints* pHints); - FX_BOOL CheckArrayPageNode(FX_DWORD dwPageNo, CPDF_PageNode *pPageNode, IFX_DownloadHints* pHints); - FX_BOOL CheckPageCount(IFX_DownloadHints* pHints); - FX_BOOL IsFirstCheck(int iPage); - void ResetFirstCheck(int iPage); + FX_BOOL CheckLinearizedFirstPage(int iPage, IFX_DownloadHints* pHints); + FX_BOOL HaveResourceAncestor(CPDF_Dictionary* pDict); + FX_BOOL CheckPage(int32_t iPage, IFX_DownloadHints* pHints); + FX_BOOL LoadDocPages(IFX_DownloadHints* pHints); + FX_BOOL LoadDocPage(int32_t iPage, IFX_DownloadHints* pHints); + FX_BOOL CheckPageNode(CPDF_PageNode& pageNodes, + int32_t iPage, + int32_t& iCount, + IFX_DownloadHints* pHints); + FX_BOOL CheckUnkownPageNode(FX_DWORD dwPageNo, + CPDF_PageNode* pPageNode, + IFX_DownloadHints* pHints); + FX_BOOL CheckArrayPageNode(FX_DWORD dwPageNo, + CPDF_PageNode* pPageNode, + IFX_DownloadHints* pHints); + FX_BOOL CheckPageCount(IFX_DownloadHints* pHints); + FX_BOOL IsFirstCheck(int iPage); + void ResetFirstCheck(int iPage); - CPDF_Parser m_parser; + CPDF_Parser m_parser; - CPDF_SyntaxParser m_syntaxParser; + CPDF_SyntaxParser m_syntaxParser; - CPDF_Object *m_pRoot; + CPDF_Object* m_pRoot; - FX_DWORD m_dwRootObjNum; + FX_DWORD m_dwRootObjNum; - FX_DWORD m_dwInfoObjNum; + FX_DWORD m_dwInfoObjNum; - CPDF_Object *m_pLinearized; + CPDF_Object* m_pLinearized; - CPDF_Object *m_pTrailer; + CPDF_Object* m_pTrailer; - FX_BOOL m_bDocAvail; + FX_BOOL m_bDocAvail; - FX_FILESIZE m_dwHeaderOffset; + FX_FILESIZE m_dwHeaderOffset; - FX_FILESIZE m_dwLastXRefOffset; + FX_FILESIZE m_dwLastXRefOffset; - FX_FILESIZE m_dwXRefOffset; + FX_FILESIZE m_dwXRefOffset; - FX_FILESIZE m_dwTrailerOffset; + FX_FILESIZE m_dwTrailerOffset; - FX_FILESIZE m_dwCurrentOffset; + FX_FILESIZE m_dwCurrentOffset; - PDF_DATAAVAIL_STATUS m_docStatus; + PDF_DATAAVAIL_STATUS m_docStatus; - FX_FILESIZE m_dwFileLen; + FX_FILESIZE m_dwFileLen; - CPDF_Document* m_pDocument; + CPDF_Document* m_pDocument; - CPDF_SortObjNumArray m_objnum_array; + CPDF_SortObjNumArray m_objnum_array; - CFX_PtrArray m_objs_array; + CFX_PtrArray m_objs_array; - FX_FILESIZE m_Pos; + FX_FILESIZE m_Pos; - FX_FILESIZE m_bufferOffset; + FX_FILESIZE m_bufferOffset; - FX_DWORD m_bufferSize; + FX_DWORD m_bufferSize; - CFX_ByteString m_WordBuf; + CFX_ByteString m_WordBuf; - uint8_t m_WordBuffer[257]; + uint8_t m_WordBuffer[257]; - FX_DWORD m_WordSize; + FX_DWORD m_WordSize; - uint8_t m_bufferData[512]; + uint8_t m_bufferData[512]; - CFX_FileSizeArray m_CrossOffset; + CFX_FileSizeArray m_CrossOffset; - CFX_DWordArray m_XRefStreamList; + CFX_DWordArray m_XRefStreamList; - CFX_DWordArray m_PageObjList; + CFX_DWordArray m_PageObjList; - FX_DWORD m_PagesObjNum; + FX_DWORD m_PagesObjNum; - FX_BOOL m_bLinearized; + FX_BOOL m_bLinearized; - FX_DWORD m_dwFirstPageNo; + FX_DWORD m_dwFirstPageNo; - FX_BOOL m_bLinearedDataOK; + FX_BOOL m_bLinearedDataOK; - FX_BOOL m_bMainXRefLoadTried; + FX_BOOL m_bMainXRefLoadTried; - FX_BOOL m_bMainXRefLoadedOK; + FX_BOOL m_bMainXRefLoadedOK; - FX_BOOL m_bPagesTreeLoad; + FX_BOOL m_bPagesTreeLoad; - FX_BOOL m_bPagesLoad; + FX_BOOL m_bPagesLoad; - CPDF_Parser * m_pCurrentParser; + CPDF_Parser* m_pCurrentParser; - FX_FILESIZE m_dwCurrentXRefSteam; + FX_FILESIZE m_dwCurrentXRefSteam; - FX_BOOL m_bAnnotsLoad; + FX_BOOL m_bAnnotsLoad; - FX_BOOL m_bHaveAcroForm; + FX_BOOL m_bHaveAcroForm; - FX_DWORD m_dwAcroFormObjNum; + FX_DWORD m_dwAcroFormObjNum; - FX_BOOL m_bAcroFormLoad; + FX_BOOL m_bAcroFormLoad; - CPDF_Object * m_pAcroForm; + CPDF_Object* m_pAcroForm; - CFX_PtrArray m_arrayAcroforms; + CFX_PtrArray m_arrayAcroforms; - CPDF_Dictionary * m_pPageDict; + CPDF_Dictionary* m_pPageDict; - CPDF_Object * m_pPageResource; + CPDF_Object* m_pPageResource; - FX_BOOL m_bNeedDownLoadResource; + FX_BOOL m_bNeedDownLoadResource; - FX_BOOL m_bPageLoadedOK; + FX_BOOL m_bPageLoadedOK; - FX_BOOL m_bLinearizedFormParamLoad; + FX_BOOL m_bLinearizedFormParamLoad; - CFX_PtrArray m_PagesArray; + CFX_PtrArray m_PagesArray; - FX_DWORD m_dwEncryptObjNum; + FX_DWORD m_dwEncryptObjNum; - FX_FILESIZE m_dwPrevXRefOffset; + FX_FILESIZE m_dwPrevXRefOffset; - FX_BOOL m_bTotalLoadPageTree; + FX_BOOL m_bTotalLoadPageTree; - FX_BOOL m_bCurPageDictLoadOK; + FX_BOOL m_bCurPageDictLoadOK; - CPDF_PageNode m_pageNodes; + CPDF_PageNode m_pageNodes; - CFX_CMapDWordToDWord * m_pageMapCheckState; + CFX_CMapDWordToDWord* m_pageMapCheckState; - CFX_CMapDWordToDWord * m_pagesLoadState; + CFX_CMapDWordToDWord* m_pagesLoadState; }; -IPDF_DataAvail::IPDF_DataAvail(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRead) : - m_pFileAvail(pFileAvail), - m_pFileRead(pFileRead) { -} +IPDF_DataAvail::IPDF_DataAvail(IFX_FileAvail* pFileAvail, + IFX_FileRead* pFileRead) + : m_pFileAvail(pFileAvail), m_pFileRead(pFileRead) {} // static -IPDF_DataAvail* IPDF_DataAvail::Create(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRead) -{ +IPDF_DataAvail* IPDF_DataAvail::Create(IFX_FileAvail* pFileAvail, + IFX_FileRead* pFileRead) { return new CPDF_DataAvail(pFileAvail, pFileRead); } // static int CPDF_DataAvail::s_CurrentDataAvailRecursionDepth = 0; -CPDF_DataAvail::CPDF_DataAvail(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRead) - : IPDF_DataAvail(pFileAvail, pFileRead) -{ - m_Pos = 0; - m_dwFileLen = 0; - if (m_pFileRead) { - m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize(); - } - m_dwCurrentOffset = 0; - m_WordSize = 0; - m_dwXRefOffset = 0; - m_bufferOffset = 0; - m_dwFirstPageNo = 0; - m_bufferSize = 0; - m_PagesObjNum = 0; - m_dwCurrentXRefSteam = 0; - m_dwAcroFormObjNum = 0; - m_dwInfoObjNum = 0; - m_pDocument = 0; - m_dwEncryptObjNum = 0; - m_dwPrevXRefOffset = 0; - m_dwLastXRefOffset = 0; - m_bDocAvail = FALSE; - m_bMainXRefLoadTried = FALSE; - m_bDocAvail = FALSE; - m_bLinearized = FALSE; - m_bPagesLoad = FALSE; - m_bPagesTreeLoad = FALSE; - m_bMainXRefLoadedOK = FALSE; - m_bAnnotsLoad = FALSE; - m_bHaveAcroForm = FALSE; - m_bAcroFormLoad = FALSE; - m_bPageLoadedOK = FALSE; - m_bNeedDownLoadResource = FALSE; - m_bLinearizedFormParamLoad = FALSE; - m_pLinearized = NULL; - m_pRoot = NULL; - m_pTrailer = NULL; - m_pCurrentParser = NULL; - m_pAcroForm = NULL; - m_pPageDict = NULL; - m_pPageResource = NULL; - m_pageMapCheckState = NULL; - m_docStatus = PDF_DATAAVAIL_HEADER; - m_parser.m_bOwnFileRead = FALSE; - m_bTotalLoadPageTree = FALSE; - m_bCurPageDictLoadOK = FALSE; - m_bLinearedDataOK = FALSE; - m_pagesLoadState = NULL; +CPDF_DataAvail::CPDF_DataAvail(IFX_FileAvail* pFileAvail, + IFX_FileRead* pFileRead) + : IPDF_DataAvail(pFileAvail, pFileRead) { + m_Pos = 0; + m_dwFileLen = 0; + if (m_pFileRead) { + m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize(); + } + m_dwCurrentOffset = 0; + m_WordSize = 0; + m_dwXRefOffset = 0; + m_bufferOffset = 0; + m_dwFirstPageNo = 0; + m_bufferSize = 0; + m_PagesObjNum = 0; + m_dwCurrentXRefSteam = 0; + m_dwAcroFormObjNum = 0; + m_dwInfoObjNum = 0; + m_pDocument = 0; + m_dwEncryptObjNum = 0; + m_dwPrevXRefOffset = 0; + m_dwLastXRefOffset = 0; + m_bDocAvail = FALSE; + m_bMainXRefLoadTried = FALSE; + m_bDocAvail = FALSE; + m_bLinearized = FALSE; + m_bPagesLoad = FALSE; + m_bPagesTreeLoad = FALSE; + m_bMainXRefLoadedOK = FALSE; + m_bAnnotsLoad = FALSE; + m_bHaveAcroForm = FALSE; + m_bAcroFormLoad = FALSE; + m_bPageLoadedOK = FALSE; + m_bNeedDownLoadResource = FALSE; + m_bLinearizedFormParamLoad = FALSE; + m_pLinearized = NULL; + m_pRoot = NULL; + m_pTrailer = NULL; + m_pCurrentParser = NULL; + m_pAcroForm = NULL; + m_pPageDict = NULL; + m_pPageResource = NULL; + m_pageMapCheckState = NULL; + m_docStatus = PDF_DATAAVAIL_HEADER; + m_parser.m_bOwnFileRead = FALSE; + m_bTotalLoadPageTree = FALSE; + m_bCurPageDictLoadOK = FALSE; + m_bLinearedDataOK = FALSE; + m_pagesLoadState = NULL; } -CPDF_DataAvail::~CPDF_DataAvail() -{ - if (m_pLinearized) { - m_pLinearized->Release(); - } - if (m_pRoot) { - m_pRoot->Release(); - } - if (m_pTrailer) { - m_pTrailer->Release(); - } - delete m_pageMapCheckState; - delete m_pagesLoadState; - int32_t i = 0; - int32_t iSize = m_arrayAcroforms.GetSize(); - for (i = 0; i < iSize; ++i) { - ((CPDF_Object *)m_arrayAcroforms.GetAt(i))->Release(); - } +CPDF_DataAvail::~CPDF_DataAvail() { + if (m_pLinearized) { + m_pLinearized->Release(); + } + if (m_pRoot) { + m_pRoot->Release(); + } + if (m_pTrailer) { + m_pTrailer->Release(); + } + delete m_pageMapCheckState; + delete m_pagesLoadState; + int32_t i = 0; + int32_t iSize = m_arrayAcroforms.GetSize(); + for (i = 0; i < iSize; ++i) { + ((CPDF_Object*)m_arrayAcroforms.GetAt(i))->Release(); + } } -void CPDF_DataAvail::SetDocument(CPDF_Document* pDoc) -{ - m_pDocument = pDoc; +void CPDF_DataAvail::SetDocument(CPDF_Document* pDoc) { + m_pDocument = pDoc; } -FX_DWORD CPDF_DataAvail::GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset) -{ - CPDF_Parser *pParser = (CPDF_Parser *)(m_pDocument->GetParser()); - if (pParser == NULL) { - return 0; - } - if (objnum >= (FX_DWORD)pParser->m_CrossRef.GetSize()) { - return 0; +FX_DWORD CPDF_DataAvail::GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset) { + CPDF_Parser* pParser = (CPDF_Parser*)(m_pDocument->GetParser()); + if (pParser == NULL) { + return 0; + } + if (objnum >= (FX_DWORD)pParser->m_CrossRef.GetSize()) { + return 0; + } + if (pParser->m_V5Type[objnum] == 2) { + objnum = (FX_DWORD)pParser->m_CrossRef[objnum]; + } + if (pParser->m_V5Type[objnum] == 1 || pParser->m_V5Type[objnum] == 255) { + offset = pParser->m_CrossRef[objnum]; + if (offset == 0) { + return 0; + } + void* pResult = FXSYS_bsearch(&offset, pParser->m_SortedOffset.GetData(), + pParser->m_SortedOffset.GetSize(), + sizeof(FX_FILESIZE), _CompareFileSize); + if (pResult == NULL) { + return 0; } - if (pParser->m_V5Type[objnum] == 2) { - objnum = (FX_DWORD)pParser->m_CrossRef[objnum]; + if ((FX_FILESIZE*)pResult - + (FX_FILESIZE*)pParser->m_SortedOffset.GetData() == + pParser->m_SortedOffset.GetSize() - 1) { + return 0; } - if (pParser->m_V5Type[objnum] == 1 || pParser->m_V5Type[objnum] == 255) { - offset = pParser->m_CrossRef[objnum]; - if (offset == 0) { - return 0; - } - void* pResult = FXSYS_bsearch(&offset, pParser->m_SortedOffset.GetData(), pParser->m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); - if (pResult == NULL) { - return 0; - } - if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)pParser->m_SortedOffset.GetData() == pParser->m_SortedOffset.GetSize() - 1) { - return 0; - } - return (FX_DWORD)(((FX_FILESIZE*)pResult)[1] - offset); - } - return 0; + return (FX_DWORD)(((FX_FILESIZE*)pResult)[1] - offset); + } + return 0; } -FX_BOOL CPDF_DataAvail::IsObjectsAvail(CFX_PtrArray& obj_array, FX_BOOL bParsePage, IFX_DownloadHints* pHints, CFX_PtrArray &ret_array) -{ - if (!obj_array.GetSize()) { - return TRUE; - } - FX_DWORD count = 0; - CFX_PtrArray new_obj_array; - int32_t i = 0; - for (i = 0; i < obj_array.GetSize(); i++) { - CPDF_Object *pObj = (CPDF_Object *)obj_array[i]; - if (!pObj) { - continue; +FX_BOOL CPDF_DataAvail::IsObjectsAvail(CFX_PtrArray& obj_array, + FX_BOOL bParsePage, + IFX_DownloadHints* pHints, + CFX_PtrArray& ret_array) { + if (!obj_array.GetSize()) { + return TRUE; + } + FX_DWORD count = 0; + CFX_PtrArray new_obj_array; + int32_t i = 0; + for (i = 0; i < obj_array.GetSize(); i++) { + CPDF_Object* pObj = (CPDF_Object*)obj_array[i]; + if (!pObj) { + continue; + } + int32_t type = pObj->GetType(); + switch (type) { + case PDFOBJ_ARRAY: { + CPDF_Array* pArray = pObj->GetArray(); + for (FX_DWORD k = 0; k < pArray->GetCount(); k++) { + new_obj_array.Add(pArray->GetElement(k)); + } + } break; + case PDFOBJ_STREAM: + pObj = pObj->GetDict(); + case PDFOBJ_DICTIONARY: { + CPDF_Dictionary* pDict = pObj->GetDict(); + if (pDict && pDict->GetString("Type") == "Page" && !bParsePage) { + continue; + } + FX_POSITION pos = pDict->GetStartPos(); + while (pos) { + CPDF_Object* value; + CFX_ByteString key; + value = pDict->GetNextElement(pos, key); + if (key != "Parent") { + new_obj_array.Add(value); + } + } + } break; + case PDFOBJ_REFERENCE: { + CPDF_Reference* pRef = (CPDF_Reference*)pObj; + FX_DWORD dwNum = pRef->GetRefObjNum(); + FX_FILESIZE offset; + FX_DWORD original_size = GetObjectSize(dwNum, offset); + pdfium::base::CheckedNumeric<FX_DWORD> size = original_size; + if (size.ValueOrDefault(0) == 0 || offset < 0 || + offset >= m_dwFileLen) { + break; } - int32_t type = pObj->GetType(); - switch (type) { - case PDFOBJ_ARRAY: { - CPDF_Array *pArray = pObj->GetArray(); - for (FX_DWORD k = 0; k < pArray->GetCount(); k++) { - new_obj_array.Add(pArray->GetElement(k)); - } - } - break; - case PDFOBJ_STREAM: - pObj = pObj->GetDict(); - case PDFOBJ_DICTIONARY: { - CPDF_Dictionary *pDict = pObj->GetDict(); - if (pDict && pDict->GetString("Type") == "Page" && !bParsePage) { - continue; - } - FX_POSITION pos = pDict->GetStartPos(); - while (pos) { - CPDF_Object *value; - CFX_ByteString key; - value = pDict->GetNextElement(pos, key); - if (key != "Parent") { - new_obj_array.Add(value); - } - } - } - break; - case PDFOBJ_REFERENCE: { - CPDF_Reference *pRef = (CPDF_Reference*)pObj; - FX_DWORD dwNum = pRef->GetRefObjNum(); - FX_FILESIZE offset; - FX_DWORD original_size = GetObjectSize(dwNum, offset); - pdfium::base::CheckedNumeric<FX_DWORD> size = original_size; - if (size.ValueOrDefault(0) == 0 || offset < 0 || offset >= m_dwFileLen) { - break; - } - size += offset; - size += 512; - if (!size.IsValid()) { - break; - } - if (size.ValueOrDie() > m_dwFileLen) { - size = m_dwFileLen - offset; - } else { - size = original_size + 512; - } - if (!size.IsValid()) { - break; - } - if (!m_pFileAvail->IsDataAvail(offset, size.ValueOrDie())) { - pHints->AddSegment(offset, size.ValueOrDie()); - ret_array.Add(pObj); - count++; - } else if (!m_objnum_array.Find(dwNum)) { - m_objnum_array.AddObjNum(dwNum); - CPDF_Object *pReferred = m_pDocument->GetIndirectObject(pRef->GetRefObjNum(), NULL); - if (pReferred) { - new_obj_array.Add(pReferred); - } - } - } - break; + size += offset; + size += 512; + if (!size.IsValid()) { + break; } + if (size.ValueOrDie() > m_dwFileLen) { + size = m_dwFileLen - offset; + } else { + size = original_size + 512; + } + if (!size.IsValid()) { + break; + } + if (!m_pFileAvail->IsDataAvail(offset, size.ValueOrDie())) { + pHints->AddSegment(offset, size.ValueOrDie()); + ret_array.Add(pObj); + count++; + } else if (!m_objnum_array.Find(dwNum)) { + m_objnum_array.AddObjNum(dwNum); + CPDF_Object* pReferred = + m_pDocument->GetIndirectObject(pRef->GetRefObjNum(), NULL); + if (pReferred) { + new_obj_array.Add(pReferred); + } + } + } break; + } + } + if (count > 0) { + int32_t iSize = new_obj_array.GetSize(); + for (i = 0; i < iSize; ++i) { + CPDF_Object* pObj = (CPDF_Object*)new_obj_array[i]; + int32_t type = pObj->GetType(); + if (type == PDFOBJ_REFERENCE) { + CPDF_Reference* pRef = (CPDF_Reference*)pObj; + FX_DWORD dwNum = pRef->GetRefObjNum(); + if (!m_objnum_array.Find(dwNum)) { + ret_array.Add(pObj); + } + } else { + ret_array.Add(pObj); + } } - if (count > 0) { - int32_t iSize = new_obj_array.GetSize(); - for (i = 0; i < iSize; ++i) { - CPDF_Object *pObj = (CPDF_Object *)new_obj_array[i]; - int32_t type = pObj->GetType(); - if (type == PDFOBJ_REFERENCE) { - CPDF_Reference *pRef = (CPDF_Reference *)pObj; - FX_DWORD dwNum = pRef->GetRefObjNum(); - if (!m_objnum_array.Find(dwNum)) { - ret_array.Add(pObj); - } - } else { - ret_array.Add(pObj); - } - } - return FALSE; - } - obj_array.RemoveAll(); - obj_array.Append(new_obj_array); - return IsObjectsAvail(obj_array, FALSE, pHints, ret_array); + return FALSE; + } + obj_array.RemoveAll(); + obj_array.Append(new_obj_array); + return IsObjectsAvail(obj_array, FALSE, pHints, ret_array); } -FX_BOOL CPDF_DataAvail::IsDocAvail(IFX_DownloadHints* pHints) -{ - if (!m_dwFileLen && m_pFileRead) { - m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize(); - if (!m_dwFileLen) { - return TRUE; - } - } - while (!m_bDocAvail) { - if (!CheckDocStatus(pHints)) { - return FALSE; - } - } - return TRUE; +FX_BOOL CPDF_DataAvail::IsDocAvail(IFX_DownloadHints* pHints) { + if (!m_dwFileLen && m_pFileRead) { + m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize(); + if (!m_dwFileLen) { + return TRUE; + } + } + while (!m_bDocAvail) { + if (!CheckDocStatus(pHints)) { + return FALSE; + } + } + return TRUE; } -FX_BOOL CPDF_DataAvail::CheckAcroFormSubObject(IFX_DownloadHints* pHints) -{ - if (!m_objs_array.GetSize()) { - m_objs_array.RemoveAll(); - m_objnum_array.RemoveAll(); - CFX_PtrArray obj_array; - obj_array.Append(m_arrayAcroforms); - FX_BOOL bRet = IsObjectsAvail(obj_array, FALSE, pHints, m_objs_array); - if (bRet) { - m_objs_array.RemoveAll(); - } - return bRet; - } - CFX_PtrArray new_objs_array; - FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); +FX_BOOL CPDF_DataAvail::CheckAcroFormSubObject(IFX_DownloadHints* pHints) { + if (!m_objs_array.GetSize()) { + m_objs_array.RemoveAll(); + m_objnum_array.RemoveAll(); + CFX_PtrArray obj_array; + obj_array.Append(m_arrayAcroforms); + FX_BOOL bRet = IsObjectsAvail(obj_array, FALSE, pHints, m_objs_array); if (bRet) { - int32_t iSize = m_arrayAcroforms.GetSize(); - for (int32_t i = 0; i < iSize; ++i) { - ((CPDF_Object *)m_arrayAcroforms.GetAt(i))->Release(); - } - m_arrayAcroforms.RemoveAll(); - } else { - m_objs_array.RemoveAll(); - m_objs_array.Append(new_objs_array); + m_objs_array.RemoveAll(); } return bRet; -} -FX_BOOL CPDF_DataAvail::CheckAcroForm(IFX_DownloadHints* pHints) -{ - FX_BOOL bExist = FALSE; - m_pAcroForm = GetObject(m_dwAcroFormObjNum, pHints, &bExist); - if (!bExist) { - m_docStatus = PDF_DATAAVAIL_PAGETREE; - return TRUE; - } - if (!m_pAcroForm) { - if (m_docStatus == PDF_DATAAVAIL_ERROR) { - m_docStatus = PDF_DATAAVAIL_LOADALLFILE; - return TRUE; - } - return FALSE; + } + CFX_PtrArray new_objs_array; + FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); + if (bRet) { + int32_t iSize = m_arrayAcroforms.GetSize(); + for (int32_t i = 0; i < iSize; ++i) { + ((CPDF_Object*)m_arrayAcroforms.GetAt(i))->Release(); } - m_arrayAcroforms.Add(m_pAcroForm); + m_arrayAcroforms.RemoveAll(); + } else { + m_objs_array.RemoveAll(); + m_objs_array.Append(new_objs_array); + } + return bRet; +} +FX_BOOL CPDF_DataAvail::CheckAcroForm(IFX_DownloadHints* pHints) { + FX_BOOL bExist = FALSE; + m_pAcroForm = GetObject(m_dwAcroFormObjNum, pHints, &bExist); + if (!bExist) { m_docStatus = PDF_DATAAVAIL_PAGETREE; return TRUE; -} -FX_BOOL CPDF_DataAvail::CheckDocStatus(IFX_DownloadHints *pHints) -{ - switch (m_docStatus) { - case PDF_DATAAVAIL_HEADER: - return CheckHeader(pHints); - case PDF_DATAAVAIL_FIRSTPAGE: - case PDF_DATAAVAIL_FIRSTPAGE_PREPARE: - return CheckFirstPage(pHints); - case PDF_DATAAVAIL_END: - return CheckEnd(pHints); - case PDF_DATAAVAIL_CROSSREF: - return CheckCrossRef(pHints); - case PDF_DATAAVAIL_CROSSREF_ITEM: - return CheckCrossRefItem(pHints); - case PDF_DATAAVAIL_CROSSREF_STREAM: - return CheckAllCrossRefStream(pHints); - case PDF_DATAAVAIL_TRAILER: - return CheckTrailer(pHints); - case PDF_DATAAVAIL_TRAILER_APPEND: - return CheckTrailerAppend(pHints); - case PDF_DATAAVAIL_LOADALLCRSOSSREF: - return LoadAllXref(pHints); - case PDF_DATAAVAIL_LOADALLFILE: - return LoadAllFile(pHints); - case PDF_DATAAVAIL_ROOT: - return CheckRoot(pHints); - case PDF_DATAAVAIL_INFO: - return CheckInfo(pHints); - case PDF_DATAAVAIL_ACROFORM: - return CheckAcroForm(pHints); - case PDF_DATAAVAIL_PAGETREE: - if (m_bTotalLoadPageTree) { - return CheckPages(pHints); - } - return LoadDocPages(pHints); - case PDF_DATAAVAIL_PAGE: - if (m_bTotalLoadPageTree) { - return CheckPage(pHints); - } - m_docStatus = PDF_DATAAVAIL_PAGE_LATERLOAD; - return TRUE; - case PDF_DATAAVAIL_ERROR: - return LoadAllFile(pHints); - case PDF_DATAAVAIL_PAGE_LATERLOAD: - m_docStatus = PDF_DATAAVAIL_PAGE; - default: - m_bDocAvail = TRUE; - return TRUE; + } + if (!m_pAcroForm) { + if (m_docStatus == PDF_DATAAVAIL_ERROR) { + m_docStatus = PDF_DATAAVAIL_LOADALLFILE; + return TRUE; } + return FALSE; + } + m_arrayAcroforms.Add(m_pAcroForm); + m_docStatus = PDF_DATAAVAIL_PAGETREE; + return TRUE; } -FX_BOOL CPDF_DataAvail::CheckPageStatus(IFX_DownloadHints* pHints) -{ - switch (m_docStatus) { - case PDF_DATAAVAIL_PAGETREE: - return CheckPages(pHints); - case PDF_DATAAVAIL_PAGE: - return CheckPage(pHints); - case PDF_DATAAVAIL_ERROR: - return LoadAllFile(pHints); - default: - m_bPagesTreeLoad = TRUE; - m_bPagesLoad = TRUE; - return TRUE; - } +FX_BOOL CPDF_DataAvail::CheckDocStatus(IFX_DownloadHints* pHints) { + switch (m_docStatus) { + case PDF_DATAAVAIL_HEADER: + return CheckHeader(pHints); + case PDF_DATAAVAIL_FIRSTPAGE: + case PDF_DATAAVAIL_FIRSTPAGE_PREPARE: + return CheckFirstPage(pHints); + case PDF_DATAAVAIL_END: + return CheckEnd(pHints); + case PDF_DATAAVAIL_CROSSREF: + return CheckCrossRef(pHints); + case PDF_DATAAVAIL_CROSSREF_ITEM: + return CheckCrossRefItem(pHints); + case PDF_DATAAVAIL_CROSSREF_STREAM: + return CheckAllCrossRefStream(pHints); + case PDF_DATAAVAIL_TRAILER: + return CheckTrailer(pHints); + case PDF_DATAAVAIL_TRAILER_APPEND: + return CheckTrailerAppend(pHints); + case PDF_DATAAVAIL_LOADALLCRSOSSREF: + return LoadAllXref(pHints); + case PDF_DATAAVAIL_LOADALLFILE: + return LoadAllFile(pHints); + case PDF_DATAAVAIL_ROOT: + return CheckRoot(pHints); + case PDF_DATAAVAIL_INFO: + return CheckInfo(pHints); + case PDF_DATAAVAIL_ACROFORM: + return CheckAcroForm(pHints); + case PDF_DATAAVAIL_PAGETREE: + if (m_bTotalLoadPageTree) { + return CheckPages(pHints); + } + return LoadDocPages(pHints); + case PDF_DATAAVAIL_PAGE: + if (m_bTotalLoadPageTree) { + return CheckPage(pHints); + } + m_docStatus = PDF_DATAAVAIL_PAGE_LATERLOAD; + return TRUE; + case PDF_DATAAVAIL_ERROR: + return LoadAllFile(pHints); + case PDF_DATAAVAIL_PAGE_LATERLOAD: + m_docStatus = PDF_DATAAVAIL_PAGE; + default: + m_bDocAvail = TRUE; + return TRUE; + } } -FX_BOOL CPDF_DataAvail::LoadAllFile(IFX_DownloadHints* pHints) -{ - if (m_pFileAvail->IsDataAvail(0, (FX_DWORD)m_dwFileLen)) { - m_docStatus = PDF_DATAAVAIL_DONE; - return TRUE; - } - pHints->AddSegment(0, (FX_DWORD)m_dwFileLen); - return FALSE; +FX_BOOL CPDF_DataAvail::CheckPageStatus(IFX_DownloadHints* pHints) { + switch (m_docStatus) { + case PDF_DATAAVAIL_PAGETREE: + return CheckPages(pHints); + case PDF_DATAAVAIL_PAGE: + return CheckPage(pHints); + case PDF_DATAAVAIL_ERROR: + return LoadAllFile(pHints); + default: + m_bPagesTreeLoad = TRUE; + m_bPagesLoad = TRUE; + return TRUE; + } } -FX_BOOL CPDF_DataAvail::LoadAllXref(IFX_DownloadHints* pHints) -{ - m_parser.m_Syntax.InitParser(m_pFileRead, (FX_DWORD)m_dwHeaderOffset); - m_parser.m_bOwnFileRead = FALSE; - if (!m_parser.LoadAllCrossRefV4(m_dwLastXRefOffset) && !m_parser.LoadAllCrossRefV5(m_dwLastXRefOffset)) { - m_docStatus = PDF_DATAAVAIL_LOADALLFILE; - return FALSE; - } - FXSYS_qsort(m_parser.m_SortedOffset.GetData(), m_parser.m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize); - m_dwRootObjNum = m_parser.GetRootObjNum(); - m_dwInfoObjNum = m_parser.GetInfoObjNum(); - m_pCurrentParser = &m_parser; - m_docStatus = PDF_DATAAVAIL_ROOT; +FX_BOOL CPDF_DataAvail::LoadAllFile(IFX_DownloadHints* pHints) { + if (m_pFileAvail->IsDataAvail(0, (FX_DWORD)m_dwFileLen)) { + m_docStatus = PDF_DATAAVAIL_DONE; return TRUE; + } + pHints->AddSegment(0, (FX_DWORD)m_dwFileLen); + return FALSE; +} +FX_BOOL CPDF_DataAvail::LoadAllXref(IFX_DownloadHints* pHints) { + m_parser.m_Syntax.InitParser(m_pFileRead, (FX_DWORD)m_dwHeaderOffset); + m_parser.m_bOwnFileRead = FALSE; + if (!m_parser.LoadAllCrossRefV4(m_dwLastXRefOffset) && + !m_parser.LoadAllCrossRefV5(m_dwLastXRefOffset)) { + m_docStatus = PDF_DATAAVAIL_LOADALLFILE; + return FALSE; + } + FXSYS_qsort(m_parser.m_SortedOffset.GetData(), + m_parser.m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), + _CompareFileSize); + m_dwRootObjNum = m_parser.GetRootObjNum(); + m_dwInfoObjNum = m_parser.GetInfoObjNum(); + m_pCurrentParser = &m_parser; + m_docStatus = PDF_DATAAVAIL_ROOT; + return TRUE; } -CPDF_Object* CPDF_DataAvail::GetObject(FX_DWORD objnum, IFX_DownloadHints* pHints, FX_BOOL *pExistInFile) -{ - CPDF_Object *pRet = NULL; - FX_DWORD original_size = 0; - FX_FILESIZE offset = 0; - CPDF_Parser *pParser = NULL; +CPDF_Object* CPDF_DataAvail::GetObject(FX_DWORD objnum, + IFX_DownloadHints* pHints, + FX_BOOL* pExistInFile) { + CPDF_Object* pRet = NULL; + FX_DWORD original_size = 0; + FX_FILESIZE offset = 0; + CPDF_Parser* pParser = NULL; - if (pExistInFile) { - *pExistInFile = TRUE; - } + if (pExistInFile) { + *pExistInFile = TRUE; + } - if (m_pDocument == NULL) { - original_size = (FX_DWORD)m_parser.GetObjectSize(objnum); - offset = m_parser.GetObjectOffset(objnum); - pParser = &m_parser; - } else { - original_size = GetObjectSize(objnum, offset); - pParser = (CPDF_Parser *)(m_pDocument->GetParser()); - } + if (m_pDocument == NULL) { + original_size = (FX_DWORD)m_parser.GetObjectSize(objnum); + offset = m_parser.GetObjectOffset(objnum); + pParser = &m_parser; + } else { + original_size = GetObjectSize(objnum, offset); + pParser = (CPDF_Parser*)(m_pDocument->GetParser()); + } - pdfium::base::CheckedNumeric<FX_DWORD> size = original_size; - if (size.ValueOrDefault(0) == 0 || offset < 0 || offset >= m_dwFileLen) { - if (pExistInFile) - *pExistInFile = FALSE; + pdfium::base::CheckedNumeric<FX_DWORD> size = original_size; + if (size.ValueOrDefault(0) == 0 || offset < 0 || offset >= m_dwFileLen) { + if (pExistInFile) + *pExistInFile = FALSE; - return NULL; - } + return NULL; + } - size += offset; - size += 512; - if (!size.IsValid()) { - return NULL; - } + size += offset; + size += 512; + if (!size.IsValid()) { + return NULL; + } - if (size.ValueOrDie() > m_dwFileLen) { - size = m_dwFileLen - offset; - } else { - size = original_size + 512; - } + if (size.ValueOrDie() > m_dwFileLen) { + size = m_dwFileLen - offset; + } else { + size = original_size + 512; + } - if (!size.IsValid()) { - return NULL; - } + if (!size.IsValid()) { + return NULL; + } - if (!m_pFileAvail->IsDataAvail(offset, size.ValueOrDie())) { - pHints->AddSegment(offset, size.ValueOrDie()); - return NULL; - } + if (!m_pFileAvail->IsDataAvail(offset, size.ValueOrDie())) { + pHints->AddSegment(offset, size.ValueOrDie()); + return NULL; + } - if (pParser) { - pRet = pParser->ParseIndirectObject(NULL, objnum, NULL); - } + if (pParser) { + pRet = pParser->ParseIndirectObject(NULL, objnum, NULL); + } - if (!pRet && pExistInFile) { - *pExistInFile = FALSE; - } + if (!pRet && pExistInFile) { + *pExistInFile = FALSE; + } - return pRet; + return pRet; } -FX_BOOL CPDF_DataAvail::CheckInfo(IFX_DownloadHints* pHints) -{ - FX_BOOL bExist = FALSE; - CPDF_Object *pInfo = GetObject(m_dwInfoObjNum, pHints, &bExist); - if (!bExist) { - if (m_bHaveAcroForm) { - m_docStatus = PDF_DATAAVAIL_ACROFORM; - } else { - m_docStatus = PDF_DATAAVAIL_PAGETREE; - } - return TRUE; - } - if (!pInfo) { - if (m_docStatus == PDF_DATAAVAIL_ERROR) { - m_docStatus = PDF_DATAAVAIL_LOADALLFILE; - return TRUE; - } - if (m_Pos == m_dwFileLen) { - m_docStatus = PDF_DATAAVAIL_ERROR; - } - return FALSE; - } - if (pInfo) { - pInfo->Release(); - } +FX_BOOL CPDF_DataAvail::CheckInfo(IFX_DownloadHints* pHints) { + FX_BOOL bExist = FALSE; + CPDF_Object* pInfo = GetObject(m_dwInfoObjNum, pHints, &bExist); + if (!bExist) { if (m_bHaveAcroForm) { - m_docStatus = PDF_DATAAVAIL_ACROFORM; + m_docStatus = PDF_DATAAVAIL_ACROFORM; } else { - m_docStatus = PDF_DATAAVAIL_PAGETREE; + m_docStatus = PDF_DATAAVAIL_PAGETREE; } return TRUE; -} -FX_BOOL CPDF_DataAvail::CheckRoot(IFX_DownloadHints* pHints) -{ - FX_BOOL bExist = FALSE; - m_pRoot = GetObject(m_dwRootObjNum, pHints, &bExist); - if (!bExist) { - m_docStatus = PDF_DATAAVAIL_LOADALLFILE; - return TRUE; + } + if (!pInfo) { + if (m_docStatus == PDF_DATAAVAIL_ERROR) { + m_docStatus = PDF_DATAAVAIL_LOADALLFILE; + return TRUE; } - if (!m_pRoot) { - if (m_docStatus == PDF_DATAAVAIL_ERROR) { - m_docStatus = PDF_DATAAVAIL_LOADALLFILE; - return TRUE; - } - return FALSE; + if (m_Pos == m_dwFileLen) { + m_docStatus = PDF_DATAAVAIL_ERROR; } - CPDF_Dictionary* pDict = m_pRoot->GetDict(); - if (!pDict) { - m_docStatus = PDF_DATAAVAIL_ERROR; - return FALSE; - } - CPDF_Reference* pRef = (CPDF_Reference*)pDict->GetElement(FX_BSTRC("Pages")); - if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) { - m_docStatus = PDF_DATAAVAIL_ERROR; - return FALSE; - } - m_PagesObjNum = pRef->GetRefObjNum(); - CPDF_Reference* pAcroFormRef = (CPDF_Reference*)m_pRoot->GetDict()->GetElement(FX_BSTRC("AcroForm")); - if (pAcroFormRef && pAcroFormRef->GetType() == PDFOBJ_REFERENCE) { - m_bHaveAcroForm = TRUE; - m_dwAcroFormObjNum = pAcroFormRef->GetRefObjNum(); - } - if (m_dwInfoObjNum) { - m_docStatus = PDF_DATAAVAIL_INFO; - } else { - if (m_bHaveAcroForm) { - m_docStatus = PDF_DATAAVAIL_ACROFORM; - } else { - m_docStatus = PDF_DATAAVAIL_PAGETREE; - } - } - return TRUE; -} -FX_BOOL CPDF_DataAvail::PreparePageItem() -{ - CPDF_Dictionary *pRoot = m_pDocument->GetRoot(); - CPDF_Reference* pRef = pRoot ? (CPDF_Reference*)pRoot->GetElement(FX_BSTRC("Pages")) : NULL; - if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) { - m_docStatus = PDF_DATAAVAIL_ERROR; - return FALSE; - } - m_PagesObjNum = pRef->GetRefObjNum(); - m_pCurrentParser = (CPDF_Parser *)m_pDocument->GetParser(); + return FALSE; + } + if (pInfo) { + pInfo->Release(); + } + if (m_bHaveAcroForm) { + m_docStatus = PDF_DATAAVAIL_ACROFORM; + } else { m_docStatus = PDF_DATAAVAIL_PAGETREE; - return TRUE; + } + return TRUE; } -FX_BOOL CPDF_DataAvail::IsFirstCheck(int iPage) -{ - if (NULL == m_pageMapCheckState) { - m_pageMapCheckState = new CFX_CMapDWordToDWord(); - } - FX_DWORD dwValue = 0; - if (!m_pageMapCheckState->Lookup(iPage, dwValue)) { - m_pageMapCheckState->SetAt(iPage, 1); - return TRUE; - } - if (dwValue != 0) { - return FALSE; - } - m_pageMapCheckState->SetAt(iPage, 1); +FX_BOOL CPDF_DataAvail::CheckRoot(IFX_DownloadHints* pHints) { + FX_BOOL bExist = FALSE; + m_pRoot = GetObject(m_dwRootObjNum, pHints, &bExist); + if (!bExist) { + m_docStatus = PDF_DATAAVAIL_LOADALLFILE; return TRUE; -} -void CPDF_DataAvail::ResetFirstCheck(int iPage) -{ - if (NULL == m_pageMapCheckState) { - m_pageMapCheckState = new CFX_CMapDWordToDWord(); + } + if (!m_pRoot) { + if (m_docStatus == PDF_DATAAVAIL_ERROR) { + m_docStatus = PDF_DATAAVAIL_LOADALLFILE; + return TRUE; } - FX_DWORD dwValue = 1; - if (!m_pageMapCheckState->Lookup(iPage, dwValue)) { - return; + return FALSE; + } + CPDF_Dictionary* pDict = m_pRoot->GetDict(); + if (!pDict) { + m_docStatus = PDF_DATAAVAIL_ERROR; + return FALSE; + } + CPDF_Reference* pRef = (CPDF_Reference*)pDict->GetElement(FX_BSTRC("Pages")); + if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) { + m_docStatus = PDF_DATAAVAIL_ERROR; + return FALSE; + } + m_PagesObjNum = pRef->GetRefObjNum(); + CPDF_Reference* pAcroFormRef = + (CPDF_Reference*)m_pRoot->GetDict()->GetElement(FX_BSTRC("AcroForm")); + if (pAcroFormRef && pAcroFormRef->GetType() == PDFOBJ_REFERENCE) { + m_bHaveAcroForm = TRUE; + m_dwAcroFormObjNum = pAcroFormRef->GetRefObjNum(); + } + if (m_dwInfoObjNum) { + m_docStatus = PDF_DATAAVAIL_INFO; + } else { + if (m_bHaveAcroForm) { + m_docStatus = PDF_DATAAVAIL_ACROFORM; + } else { + m_docStatus = PDF_DATAAVAIL_PAGETREE; } - m_pageMapCheckState->SetAt(iPage, 0); + } + return TRUE; } -FX_BOOL CPDF_DataAvail::CheckPage(IFX_DownloadHints* pHints) -{ - FX_DWORD iPageObjs = m_PageObjList.GetSize(); - CFX_DWordArray UnavailObjList; - for (FX_DWORD i = 0; i < iPageObjs; ++i) { - FX_DWORD dwPageObjNum = m_PageObjList.GetAt(i); - FX_BOOL bExist = FALSE; - CPDF_Object *pObj = GetObject(dwPageObjNum, pHints, &bExist); - if (!pObj) { - if (bExist) { - UnavailObjList.Add(dwPageObjNum); - } - continue; - } - if (pObj->GetType() == PDFOBJ_ARRAY) { - CPDF_Array *pArray = pObj->GetArray(); - if (pArray) { - int32_t iSize = pArray->GetCount(); - CPDF_Object *pItem = NULL; - for (int32_t j = 0; j < iSize; ++j) { - pItem = pArray->GetElement(j); - if (pItem && pItem->GetType() == PDFOBJ_REFERENCE) { - UnavailObjList.Add(((CPDF_Reference *)pItem)->GetRefObjNum()); - } - } - } - } - if (pObj->GetType() != PDFOBJ_DICTIONARY) { - pObj->Release(); - continue; - } - CFX_ByteString type = pObj->GetDict()->GetString(FX_BSTRC("Type")); - if (type == FX_BSTRC("Pages")) { - m_PagesArray.Add(pObj); - continue; - } - pObj->Release(); - } - m_PageObjList.RemoveAll(); - if (UnavailObjList.GetSize()) { - m_PageObjList.Append(UnavailObjList); - return FALSE; - } - FX_DWORD iPages = m_PagesArray.GetSize(); - for (FX_DWORD i = 0; i < iPages; i++) { - CPDF_Object *pPages = (CPDF_Object *)m_PagesArray.GetAt(i); - if (!pPages) { - continue; - } - if (!GetPageKids(m_pCurrentParser, pPages)) { - pPages->Release(); - while (++i < iPages) { - pPages = (CPDF_Object *)m_PagesArray.GetAt(i); - pPages->Release(); - } - m_PagesArray.RemoveAll(); - m_docStatus = PDF_DATAAVAIL_ERROR; - return FALSE; - } - pPages->Release(); - } - m_PagesArray.RemoveAll(); - if (!m_PageObjList.GetSize()) { - m_docStatus = PDF_DATAAVAIL_DONE; - } - return TRUE; +FX_BOOL CPDF_DataAvail::PreparePageItem() { + CPDF_Dictionary* pRoot = m_pDocument->GetRoot(); + CPDF_Reference* pRef = + pRoot ? (CPDF_Reference*)pRoot->GetElement(FX_BSTRC("Pages")) : NULL; + if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) { + m_docStatus = PDF_DATAAVAIL_ERROR; + return FALSE; + } + m_PagesObjNum = pRef->GetRefObjNum(); + m_pCurrentParser = (CPDF_Parser*)m_pDocument->GetParser(); + m_docStatus = PDF_DATAAVAIL_PAGETREE; + return TRUE; } -FX_BOOL CPDF_DataAvail::GetPageKids(CPDF_Parser *pParser, CPDF_Object *pPages) -{ - if (!pParser) { - m_docStatus = PDF_DATAAVAIL_ERROR; - return FALSE; - } - CPDF_Dictionary* pDict = pPages->GetDict(); - CPDF_Object *pKids = pDict ? pDict->GetElement(FX_BSTRC("Kids")) : NULL; - if (!pKids) { - return TRUE; - } - switch (pKids->GetType()) { - case PDFOBJ_REFERENCE: { - CPDF_Reference *pKid = (CPDF_Reference *)pKids; - m_PageObjList.Add(pKid->GetRefObjNum()); - } - break; - case PDFOBJ_ARRAY: { - CPDF_Array *pKidsArray = (CPDF_Array *)pKids; - for (FX_DWORD i = 0; i < pKidsArray->GetCount(); ++i) { - CPDF_Object *pKid = (CPDF_Object *)pKidsArray->GetElement(i); - if (pKid && pKid->GetType() == PDFOBJ_REFERENCE) { - m_PageObjList.Add(((CPDF_Reference *)pKid)->GetRefObjNum()); - } - } - } - break; - default: - m_docStatus = PDF_DATAAVAIL_ERROR; - return FALSE; - } +FX_BOOL CPDF_DataAvail::IsFirstCheck(int iPage) { + if (NULL == m_pageMapCheckState) { + m_pageMapCheckState = new CFX_CMapDWordToDWord(); + } + FX_DWORD dwValue = 0; + if (!m_pageMapCheckState->Lookup(iPage, dwValue)) { + m_pageMapCheckState->SetAt(iPage, 1); return TRUE; + } + if (dwValue != 0) { + return FALSE; + } + m_pageMapCheckState->SetAt(iPage, 1); + return TRUE; } -FX_BOOL CPDF_DataAvail::CheckPages(IFX_DownloadHints* pHints) -{ +void CPDF_DataAvail::ResetFirstCheck(int iPage) { + if (NULL == m_pageMapCheckState) { + m_pageMapCheckState = new CFX_CMapDWordToDWord(); + } + FX_DWORD dwValue = 1; + if (!m_pageMapCheckState->Lookup(iPage, dwValue)) { + return; + } + m_pageMapCheckState->SetAt(iPage, 0); +} +FX_BOOL CPDF_DataAvail::CheckPage(IFX_DownloadHints* pHints) { + FX_DWORD iPageObjs = m_PageObjList.GetSize(); + CFX_DWordArray UnavailObjList; + for (FX_DWORD i = 0; i < iPageObjs; ++i) { + FX_DWORD dwPageObjNum = m_PageObjList.GetAt(i); FX_BOOL bExist = FALSE; - CPDF_Object *pPages = GetObject(m_PagesObjNum, pHints, &bExist); - if (!bExist) { - m_docStatus = PDF_DATAAVAIL_LOADALLFILE; - return TRUE; - } + CPDF_Object* pObj = GetObject(dwPageObjNum, pHints, &bExist); + if (!pObj) { + if (bExist) { + UnavailObjList.Add(dwPageObjNum); + } + continue; + } + if (pObj->GetType() == PDFOBJ_ARRAY) { + CPDF_Array* pArray = pObj->GetArray(); + if (pArray) { + int32_t iSize = pArray->GetCount(); + CPDF_Object* pItem = NULL; + for (int32_t j = 0; j < iSize; ++j) { + pItem = pArray->GetElement(j); + if (pItem && pItem->GetType() == PDFOBJ_REFERENCE) { + UnavailObjList.Add(((CPDF_Reference*)pItem)->GetRefObjNum()); + } + } + } + } + if (pObj->GetType() != PDFOBJ_DICTIONARY) { + pObj->Release(); + continue; + } + CFX_ByteString type = pObj->GetDict()->GetString(FX_BSTRC("Type")); + if (type == FX_BSTRC("Pages")) { + m_PagesArray.Add(pObj); + continue; + } + pObj->Release(); + } + m_PageObjList.RemoveAll(); + if (UnavailObjList.GetSize()) { + m_PageObjList.Append(UnavailObjList); + return FALSE; + } + FX_DWORD iPages = m_PagesArray.GetSize(); + for (FX_DWORD i = 0; i < iPages; i++) { + CPDF_Object* pPages = (CPDF_Object*)m_PagesArray.GetAt(i); if (!pPages) { - if (m_docStatus == PDF_DATAAVAIL_ERROR) { - m_docStatus = PDF_DATAAVAIL_LOADALLFILE; - return TRUE; - } - return FALSE; + continue; } if (!GetPageKids(m_pCurrentParser, pPages)) { + pPages->Release(); + while (++i < iPages) { + pPages = (CPDF_Object*)m_PagesArray.GetAt(i); pPages->Release(); - m_docStatus = PDF_DATAAVAIL_ERROR; - return FALSE; + } + m_PagesArray.RemoveAll(); + m_docStatus = PDF_DATAAVAIL_ERROR; + return FALSE; } pPages->Release(); - m_docStatus = PDF_DATAAVAIL_PAGE; + } + m_PagesArray.RemoveAll(); + if (!m_PageObjList.GetSize()) { + m_docStatus = PDF_DATAAVAIL_DONE; + } + return TRUE; +} +FX_BOOL CPDF_DataAvail::GetPageKids(CPDF_Parser* pParser, CPDF_Object* pPages) { + if (!pParser) { + m_docStatus = PDF_DATAAVAIL_ERROR; + return FALSE; + } + CPDF_Dictionary* pDict = pPages->GetDict(); + CPDF_Object* pKids = pDict ? pDict->GetElement(FX_BSTRC("Kids")) : NULL; + if (!pKids) { return TRUE; + } + switch (pKids->GetType()) { + case PDFOBJ_REFERENCE: { + CPDF_Reference* pKid = (CPDF_Reference*)pKids; + m_PageObjList.Add(pKid->GetRefObjNum()); + } break; + case PDFOBJ_ARRAY: { + CPDF_Array* pKidsArray = (CPDF_Array*)pKids; + for (FX_DWORD i = 0; i < pKidsArray->GetCount(); ++i) { + CPDF_Object* pKid = (CPDF_Object*)pKidsArray->GetElement(i); + if (pKid && pKid->GetType() == PDFOBJ_REFERENCE) { + m_PageObjList.Add(((CPDF_Reference*)pKid)->GetRefObjNum()); + } + } + } break; + default: + m_docStatus = PDF_DATAAVAIL_ERROR; + return FALSE; + } + return TRUE; } -FX_BOOL CPDF_DataAvail::CheckHeader(IFX_DownloadHints* pHints) -{ - FX_DWORD req_size = 1024; - if ((FX_FILESIZE)req_size > m_dwFileLen) { - req_size = (FX_DWORD)m_dwFileLen; - } - if (m_pFileAvail->IsDataAvail(0, req_size)) { - uint8_t buffer[1024]; - m_pFileRead->ReadBlock(buffer, 0, req_size); - if (IsLinearizedFile(buffer, req_size)) { - m_docStatus = PDF_DATAAVAIL_FIRSTPAGE; - } else { - if (m_docStatus == PDF_DATAAVAIL_ERROR) { - return FALSE; - } - m_docStatus = PDF_DATAAVAIL_END; - } - return TRUE; +FX_BOOL CPDF_DataAvail::CheckPages(IFX_DownloadHints* pHints) { + FX_BOOL bExist = FALSE; + CPDF_Object* pPages = GetObject(m_PagesObjNum, pHints, &bExist); + if (!bExist) { + m_docStatus = PDF_DATAAVAIL_LOADALLFILE; + return TRUE; + } + if (!pPages) { + if (m_docStatus == PDF_DATAAVAIL_ERROR) { + m_docStatus = PDF_DATAAVAIL_LOADALLFILE; + return TRUE; } - pHints->AddSegment(0, req_size); return FALSE; + } + if (!GetPageKids(m_pCurrentParser, pPages)) { + pPages->Release(); + m_docStatus = PDF_DATAAVAIL_ERROR; + return FALSE; + } + pPages->Release(); + m_docStatus = PDF_DATAAVAIL_PAGE; + return TRUE; } -FX_BOOL CPDF_DataAvail::CheckFirstPage(IFX_DownloadHints *pHints) -{ - CPDF_Dictionary* pDict = m_pLinearized->GetDict(); - CPDF_Object *pEndOffSet = pDict ? pDict->GetElement(FX_BSTRC("E")) : NULL; - if (!pEndOffSet) { - m_docStatus = PDF_DATAAVAIL_ERROR; - return FALSE; - } - CPDF_Object *pXRefOffset = pDict ? pDict->GetElement(FX_BSTRC("T")) : NULL; - if (!pXRefOffset) { - m_docStatus = PDF_DATAAVAIL_ERROR; - return FALSE; - } - CPDF_Object *pFileLen = pDict ? pDict->GetElement(FX_BSTRC("L")) : NULL; - if (!pFileLen) { - m_docStatus = PDF_DATAAVAIL_ERROR; - return FALSE; - } - FX_BOOL bNeedDownLoad = FALSE; - if (pEndOffSet->GetType() == PDFOBJ_NUMBER) { - FX_DWORD dwEnd = pEndOffSet->GetInteger(); - dwEnd += 512; - if ((FX_FILESIZE)dwEnd > m_dwFileLen) { - dwEnd = (FX_DWORD)m_dwFileLen; - } - int32_t iStartPos = (int32_t)(m_dwFileLen > 1024 ? 1024 : m_dwFileLen); - int32_t iSize = dwEnd > 1024 ? dwEnd - 1024 : 0; - if (!m_pFileAvail->IsDataAvail(iStartPos, iSize)) { - pHints->AddSegment(iStartPos, iSize); - bNeedDownLoad = TRUE; - } - } - m_dwLastXRefOffset = 0; - FX_FILESIZE dwFileLen = 0; - if (pXRefOffset->GetType() == PDFOBJ_NUMBER) { - m_dwLastXRefOffset = pXRefOffset->GetInteger(); - } - if (pFileLen->GetType() == PDFOBJ_NUMBER) { - dwFileLen = pFileLen->GetInteger(); - } - if (!m_pFileAvail->IsDataAvail(m_dwLastXRefOffset, (FX_DWORD)(dwFileLen - m_dwLastXRefOffset))) { - if (m_docStatus == PDF_DATAAVAIL_FIRSTPAGE) { - FX_DWORD dwSize = (FX_DWORD)(dwFileLen - m_dwLastXRefOffset); - FX_FILESIZE offset = m_dwLastXRefOffset; - if (dwSize < 512 && dwFileLen > 512) { - dwSize = 512; - offset = dwFileLen - 512; - } - pHints->AddSegment(offset, dwSize); - } +FX_BOOL CPDF_DataAvail::CheckHeader(IFX_DownloadHints* pHints) { + FX_DWORD req_size = 1024; + if ((FX_FILESIZE)req_size > m_dwFileLen) { + req_size = (FX_DWORD)m_dwFileLen; + } + if (m_pFileAvail->IsDataAvail(0, req_size)) { + uint8_t buffer[1024]; + m_pFileRead->ReadBlock(buffer, 0, req_size); + if (IsLinearizedFile(buffer, req_size)) { + m_docStatus = PDF_DATAAVAIL_FIRSTPAGE; } else { - m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE; - } - if (!bNeedDownLoad && m_docStatus == PDF_DATAAVAIL_FIRSTPAGE_PREPARE) { - m_docStatus = PDF_DATAAVAIL_DONE; - return TRUE; + if (m_docStatus == PDF_DATAAVAIL_ERROR) { + return FALSE; + } + m_docStatus = PDF_DATAAVAIL_END; } - m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE; + return TRUE; + } + pHints->AddSegment(0, req_size); + return FALSE; +} +FX_BOOL CPDF_DataAvail::CheckFirstPage(IFX_DownloadHints* pHints) { + CPDF_Dictionary* pDict = m_pLinearized->GetDict(); + CPDF_Object* pEndOffSet = pDict ? pDict->GetElement(FX_BSTRC("E")) : NULL; + if (!pEndOffSet) { + m_docStatus = PDF_DATAAVAIL_ERROR; + return FALSE; + } + CPDF_Object* pXRefOffset = pDict ? pDict->GetElement(FX_BSTRC("T")) : NULL; + if (!pXRefOffset) { + m_docStatus = PDF_DATAAVAIL_ERROR; + return FALSE; + } + CPDF_Object* pFileLen = pDict ? pDict->GetElement(FX_BSTRC("L")) : NULL; + if (!pFileLen) { + m_docStatus = PDF_DATAAVAIL_ERROR; return FALSE; + } + FX_BOOL bNeedDownLoad = FALSE; + if (pEndOffSet->GetType() == PDFOBJ_NUMBER) { + FX_DWORD dwEnd = pEndOffSet->GetInteger(); + dwEnd += 512; + if ((FX_FILESIZE)dwEnd > m_dwFileLen) { + dwEnd = (FX_DWORD)m_dwFileLen; + } + int32_t iStartPos = (int32_t)(m_dwFileLen > 1024 ? 1024 : m_dwFileLen); + int32_t iSize = dwEnd > 1024 ? dwEnd - 1024 : 0; + if (!m_pFileAvail->IsDataAvail(iStartPos, iSize)) { + pHints->AddSegment(iStartPos, iSize); + bNeedDownLoad = TRUE; + } + } + m_dwLastXRefOffset = 0; + FX_FILESIZE dwFileLen = 0; + if (pXRefOffset->GetType() == PDFOBJ_NUMBER) { + m_dwLastXRefOffset = pXRefOffset->GetInteger(); + } + if (pFileLen->GetType() == PDFOBJ_NUMBER) { + dwFileLen = pFileLen->GetInteger(); + } + if (!m_pFileAvail->IsDataAvail(m_dwLastXRefOffset, + (FX_DWORD)(dwFileLen - m_dwLastXRefOffset))) { + if (m_docStatus == PDF_DATAAVAIL_FIRSTPAGE) { + FX_DWORD dwSize = (FX_DWORD)(dwFileLen - m_dwLastXRefOffset); + FX_FILESIZE offset = m_dwLastXRefOffset; + if (dwSize < 512 && dwFileLen > 512) { + dwSize = 512; + offset = dwFileLen - 512; + } + pHints->AddSegment(offset, dwSize); + } + } else { + m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE; + } + if (!bNeedDownLoad && m_docStatus == PDF_DATAAVAIL_FIRSTPAGE_PREPARE) { + m_docStatus = PDF_DATAAVAIL_DONE; + return TRUE; + } + m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE; + return FALSE; } -CPDF_Object * CPDF_DataAvail::ParseIndirectObjectAt(FX_FILESIZE pos, FX_DWORD objnum) -{ - FX_FILESIZE SavedPos = m_syntaxParser.SavePos(); - m_syntaxParser.RestorePos(pos); - FX_BOOL bIsNumber; - CFX_ByteString word = m_syntaxParser.GetNextWord(bIsNumber); - if (!bIsNumber) { - return NULL; - } - FX_DWORD parser_objnum = FXSYS_atoi(word); - if (objnum && parser_objnum != objnum) { - return NULL; - } - word = m_syntaxParser.GetNextWord(bIsNumber); - if (!bIsNumber) { - return NULL; - } - FX_DWORD gennum = FXSYS_atoi(word); - if (m_syntaxParser.GetKeyword() != FX_BSTRC("obj")) { - m_syntaxParser.RestorePos(SavedPos); - return NULL; - } - CPDF_Object* pObj = m_syntaxParser.GetObject(NULL, objnum, gennum, 0); +CPDF_Object* CPDF_DataAvail::ParseIndirectObjectAt(FX_FILESIZE pos, + FX_DWORD objnum) { + FX_FILESIZE SavedPos = m_syntaxParser.SavePos(); + m_syntaxParser.RestorePos(pos); + FX_BOOL bIsNumber; + CFX_ByteString word = m_syntaxParser.GetNextWord(bIsNumber); + if (!bIsNumber) { + return NULL; + } + FX_DWORD parser_objnum = FXSYS_atoi(word); + if (objnum && parser_objnum != objnum) { + return NULL; + } + word = m_syntaxParser.GetNextWord(bIsNumber); + if (!bIsNumber) { + return NULL; + } + FX_DWORD gennum = FXSYS_atoi(word); + if (m_syntaxParser.GetKeyword() != FX_BSTRC("obj")) { m_syntaxParser.RestorePos(SavedPos); - return pObj; + return NULL; + } + CPDF_Object* pObj = m_syntaxParser.GetObject(NULL, objnum, gennum, 0); + m_syntaxParser.RestorePos(SavedPos); + return pObj; } -int32_t CPDF_DataAvail::IsLinearizedPDF() -{ - FX_DWORD req_size = 1024; - if (!m_pFileAvail->IsDataAvail(0, req_size)) { - return PDF_UNKNOW_LINEARIZED; - } - if (!m_pFileRead) { - return PDF_NOT_LINEARIZED; - } - FX_FILESIZE dwSize = m_pFileRead->GetSize(); - if (dwSize < (FX_FILESIZE)req_size) { - return PDF_UNKNOW_LINEARIZED; - } - uint8_t buffer[1024]; - m_pFileRead->ReadBlock(buffer, 0, req_size); - if (IsLinearizedFile(buffer, req_size)) { - return PDF_IS_LINEARIZED; - } +int32_t CPDF_DataAvail::IsLinearizedPDF() { + FX_DWORD req_size = 1024; + if (!m_pFileAvail->IsDataAvail(0, req_size)) { + return PDF_UNKNOW_LINEARIZED; + } + if (!m_pFileRead) { return PDF_NOT_LINEARIZED; + } + FX_FILESIZE dwSize = m_pFileRead->GetSize(); + if (dwSize < (FX_FILESIZE)req_size) { + return PDF_UNKNOW_LINEARIZED; + } + uint8_t buffer[1024]; + m_pFileRead->ReadBlock(buffer, 0, req_size); + if (IsLinearizedFile(buffer, req_size)) { + return PDF_IS_LINEARIZED; + } + return PDF_NOT_LINEARIZED; } -FX_BOOL CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen) -{ - CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream(pData, (size_t)dwLen, FALSE)); - int32_t offset = GetHeaderOffset(file.Get()); - if (offset == -1) { - m_docStatus = PDF_DATAAVAIL_ERROR; - return FALSE; - } - m_dwHeaderOffset = offset; - m_syntaxParser.InitParser(file.Get(), offset); - m_syntaxParser.RestorePos(m_syntaxParser.m_HeaderOffset + 9); - FX_BOOL bNumber = FALSE; - CFX_ByteString wordObjNum = m_syntaxParser.GetNextWord(bNumber); - if (!bNumber) { - return FALSE; - } - FX_DWORD objnum = FXSYS_atoi(wordObjNum); - if (m_pLinearized) { - m_pLinearized->Release(); - m_pLinearized = NULL; +FX_BOOL CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, FX_DWORD dwLen) { + CFX_SmartPointer<IFX_FileStream> file( + FX_CreateMemoryStream(pData, (size_t)dwLen, FALSE)); + int32_t offset = GetHeaderOffset(file.Get()); + if (offset == -1) { + m_docStatus = PDF_DATAAVAIL_ERROR; + return FALSE; + } + m_dwHeaderOffset = offset; + m_syntaxParser.InitParser(file.Get(), offset); + m_syntaxParser.RestorePos(m_syntaxParser.m_HeaderOffset + 9); + FX_BOOL bNumber = FALSE; + CFX_ByteString wordObjNum = m_syntaxParser.GetNextWord(bNumber); + if (!bNumber) { + return FALSE; + } + FX_DWORD objnum = FXSYS_atoi(wordObjNum); + if (m_pLinearized) { + m_pLinearized->Release(); + m_pLinearized = NULL; + } + m_pLinearized = + ParseIndirectObjectAt(m_syntaxParser.m_HeaderOffset + 9, objnum); + if (!m_pLinearized) { + return FALSE; + } + if (m_pLinearized->GetDict() && + m_pLinearized->GetDict()->GetElement(FX_BSTRC("Linearized"))) { + CPDF_Object* pLen = m_pLinearized->GetDict()->GetElement(FX_BSTRC("L")); + if (!pLen) { + return FALSE; } - m_pLinearized = ParseIndirectObjectAt(m_syntaxParser.m_HeaderOffset + 9, objnum); - if (!m_pLinearized) { - return FALSE; + if ((FX_FILESIZE)pLen->GetInteger() != m_pFileRead->GetSize()) { + return FALSE; } - if (m_pLinearized->GetDict() && m_pLinearized->GetDict()->GetElement(FX_BSTRC("Linearized"))) { - CPDF_Object *pLen = m_pLinearized->GetDict()->GetElement(FX_BSTRC("L")); - if (!pLen) { - return FALSE; - } - if ((FX_FILESIZE)pLen->GetInteger() != m_pFileRead->GetSize()) { - return FALSE; - } - m_bLinearized = TRUE; - CPDF_Object *pNo = m_pLinearized->GetDict()->GetElement(FX_BSTRC("P")); - if (pNo && pNo->GetType() == PDFOBJ_NUMBER) { - m_dwFirstPageNo = pNo->GetInteger(); - } - return TRUE; + m_bLinearized = TRUE; + CPDF_Object* pNo = m_pLinearized->GetDict()->GetElement(FX_BSTRC("P")); + if (pNo && pNo->GetType() == PDFOBJ_NUMBER) { + m_dwFirstPageNo = pNo->GetInteger(); } - return FALSE; + return TRUE; + } + return FALSE; } -FX_BOOL CPDF_DataAvail::CheckEnd(IFX_DownloadHints* pHints) -{ - FX_DWORD req_pos = (FX_DWORD)(m_dwFileLen > 1024 ? m_dwFileLen - 1024 : 0); - FX_DWORD dwSize = (FX_DWORD)(m_dwFileLen - req_pos); - if (m_pFileAvail->IsDataAvail(req_pos, dwSize)) { - uint8_t buffer[1024]; - m_pFileRead->ReadBlock(buffer, req_pos, dwSize); - CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream(buffer, (size_t)dwSize, FALSE)); - m_syntaxParser.InitParser(file.Get(), 0); - m_syntaxParser.RestorePos(dwSize - 1); - if (m_syntaxParser.SearchWord(FX_BSTRC("startxref"), TRUE, FALSE, dwSize)) { - FX_BOOL bNumber; - m_syntaxParser.GetNextWord(bNumber); - CFX_ByteString xrefpos_str = m_syntaxParser.GetNextWord(bNumber); - if (!bNumber) { - m_docStatus = PDF_DATAAVAIL_ERROR; - return FALSE; - } - m_dwXRefOffset = (FX_FILESIZE)FXSYS_atoi64(xrefpos_str); - if (!m_dwXRefOffset || m_dwXRefOffset > m_dwFileLen) { - m_docStatus = PDF_DATAAVAIL_LOADALLFILE; - return TRUE; - } - m_dwLastXRefOffset = m_dwXRefOffset; - SetStartOffset(m_dwXRefOffset); - m_docStatus = PDF_DATAAVAIL_CROSSREF; - return TRUE; - } +FX_BOOL CPDF_DataAvail::CheckEnd(IFX_DownloadHints* pHints) { + FX_DWORD req_pos = (FX_DWORD)(m_dwFileLen > 1024 ? m_dwFileLen - 1024 : 0); + FX_DWORD dwSize = (FX_DWORD)(m_dwFileLen - req_pos); + if (m_pFileAvail->IsDataAvail(req_pos, dwSize)) { + uint8_t buffer[1024]; + m_pFileRead->ReadBlock(buffer, req_pos, dwSize); + CFX_SmartPointer<IFX_FileStream> file( + FX_CreateMemoryStream(buffer, (size_t)dwSize, FALSE)); + m_syntaxParser.InitParser(file.Get(), 0); + m_syntaxParser.RestorePos(dwSize - 1); + if (m_syntaxParser.SearchWord(FX_BSTRC("startxref"), TRUE, FALSE, dwSize)) { + FX_BOOL bNumber; + m_syntaxParser.GetNextWord(bNumber); + CFX_ByteString xrefpos_str = m_syntaxParser.GetNextWord(bNumber); + if (!bNumber) { + m_docStatus = PDF_DATAAVAIL_ERROR; + return FALSE; + } + m_dwXRefOffset = (FX_FILESIZE)FXSYS_atoi64(xrefpos_str); + if (!m_dwXRefOffset || m_dwXRefOffset > m_dwFileLen) { m_docStatus = PDF_DATAAVAIL_LOADALLFILE; return TRUE; + } + m_dwLastXRefOffset = m_dwXRefOffset; + SetStartOffset(m_dwXRefOffset); + m_docStatus = PDF_DATAAVAIL_CROSSREF; + return TRUE; } - pHints->AddSegment(req_pos, dwSize); - return FALSE; + m_docStatus = PDF_DATAAVAIL_LOADALLFILE; + return TRUE; + } + pHints->AddSegment(req_pos, dwSize); + return FALSE; } -int32_t CPDF_DataAvail::CheckCrossRefStream(IFX_DownloadHints* pHints, FX_FILESIZE &xref_offset) -{ - xref_offset = 0; - FX_DWORD req_size = (FX_DWORD)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512); - if (m_pFileAvail->IsDataAvail(m_Pos, req_size)) { - int32_t iSize = (int32_t)(m_Pos + req_size - m_dwCurrentXRefSteam); - CFX_BinaryBuf buf(iSize); - uint8_t* pBuf = buf.GetBuffer(); - m_pFileRead->ReadBlock(pBuf, m_dwCurrentXRefSteam, iSize); - CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream(pBuf, (size_t)iSize, FALSE)); - m_parser.m_Syntax.InitParser(file.Get(), 0); - FX_BOOL bNumber = FALSE; - CFX_ByteString objnum = m_parser.m_Syntax.GetNextWord(bNumber); - if (!bNumber) { - return -1; - } - FX_DWORD objNum = FXSYS_atoi(objnum); - CPDF_Object *pObj = m_parser.ParseIndirectObjectAt(NULL, 0, objNum, NULL); - if (!pObj) { - m_Pos += m_parser.m_Syntax.SavePos(); - return 0; - } - CPDF_Dictionary* pDict = pObj->GetDict(); - CPDF_Object *pName = pDict ? pDict->GetElement(FX_BSTRC("Type")) : NULL; - if (pName && pName->GetType() == PDFOBJ_NAME) { - if (pName->GetString() == FX_BSTRC("XRef")) { - m_Pos += m_parser.m_Syntax.SavePos(); - xref_offset = pObj->GetDict()->GetInteger(FX_BSTRC("Prev")); - pObj->Release(); - return 1; - } - } +int32_t CPDF_DataAvail::CheckCrossRefStream(IFX_DownloadHints* pHints, + FX_FILESIZE& xref_offset) { + xref_offset = 0; + FX_DWORD req_size = + (FX_DWORD)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512); + if (m_pFileAvail->IsDataAvail(m_Pos, req_size)) { + int32_t iSize = (int32_t)(m_Pos + req_size - m_dwCurrentXRefSteam); + CFX_BinaryBuf buf(iSize); + uint8_t* pBuf = buf.GetBuffer(); + m_pFileRead->ReadBlock(pBuf, m_dwCurrentXRefSteam, iSize); + CFX_SmartPointer<IFX_FileStream> file( + FX_CreateMemoryStream(pBuf, (size_t)iSize, FALSE)); + m_parser.m_Syntax.InitParser(file.Get(), 0); + FX_BOOL bNumber = FALSE; + CFX_ByteString objnum = m_parser.m_Syntax.GetNextWord(bNumber); + if (!bNumber) { + return -1; + } + FX_DWORD objNum = FXSYS_atoi(objnum); + CPDF_Object* pObj = m_parser.ParseIndirectObjectAt(NULL, 0, objNum, NULL); + if (!pObj) { + m_Pos += m_parser.m_Syntax.SavePos(); + return 0; + } + CPDF_Dictionary* pDict = pObj->GetDict(); + CPDF_Object* pName = pDict ? pDict->GetElement(FX_BSTRC("Type")) : NULL; + if (pName && pName->GetType() == PDFOBJ_NAME) { + if (pName->GetString() == FX_BSTRC("XRef")) { + m_Pos += m_parser.m_Syntax.SavePos(); + xref_offset = pObj->GetDict()->GetInteger(FX_BSTRC("Prev")); pObj->Release(); - return -1; + return 1; + } } - pHints->AddSegment(m_Pos, req_size); - return 0; + pObj->Release(); + return -1; + } + pHints->AddSegment(m_Pos, req_size); + return 0; } -inline void CPDF_DataAvail::SetStartOffset(FX_FILESIZE dwOffset) -{ - m_Pos = dwOffset; +inline void CPDF_DataAvail::SetStartOffset(FX_FILESIZE dwOffset) { + m_Pos = dwOffset; } #define MAX_WORD_BUFFER 256 -FX_BOOL CPDF_DataAvail::GetNextToken(CFX_ByteString &token) -{ - m_WordSize = 0; - uint8_t ch; - if (!GetNextChar(ch)) { +FX_BOOL CPDF_DataAvail::GetNextToken(CFX_ByteString& token) { + m_WordSize = 0; + uint8_t ch; + if (!GetNextChar(ch)) { + return FALSE; + } + uint8_t type = PDF_CharType[ch]; + while (1) { + while (type == 'W') { + if (!GetNextChar(ch)) { return FALSE; + } + type = PDF_CharType[ch]; } - uint8_t type = PDF_CharType[ch]; - while (1) { - while (type == 'W') { - if (!GetNextChar(ch)) { - return FALSE; - } - type = PDF_CharType[ch]; - } - if (ch != '%') { - break; - } - while (1) { - if (!GetNextChar(ch)) { - return FALSE; - } - if (ch == '\r' || ch == '\n') { - break; - } - } - type = PDF_CharType[ch]; - } - if (type == 'D') { - m_WordBuffer[m_WordSize++] = ch; - if (ch == '/') { - while (1) { - if (!GetNextChar(ch)) { - return FALSE; - } - type = PDF_CharType[ch]; - if (type != 'R' && type != 'N') { - m_Pos --; - CFX_ByteString ret(m_WordBuffer, m_WordSize); - token = ret; - return TRUE; - } - if (m_WordSize < MAX_WORD_BUFFER) { - m_WordBuffer[m_WordSize++] = ch; - } - } - } else if (ch == '<') { - if (!GetNextChar(ch)) { - return FALSE; - } - if (ch == '<') { - m_WordBuffer[m_WordSize++] = ch; - } else { - m_Pos --; - } - } else if (ch == '>') { - if (!GetNextChar(ch)) { - return FALSE; - } - if (ch == '>') { - m_WordBuffer[m_WordSize++] = ch; - } else { - m_Pos --; - } - } - CFX_ByteString ret(m_WordBuffer, m_WordSize); - token = ret; - return TRUE; + if (ch != '%') { + break; } while (1) { - if (m_WordSize < MAX_WORD_BUFFER) { - m_WordBuffer[m_WordSize++] = ch; - } + if (!GetNextChar(ch)) { + return FALSE; + } + if (ch == '\r' || ch == '\n') { + break; + } + } + type = PDF_CharType[ch]; + } + if (type == 'D') { + m_WordBuffer[m_WordSize++] = ch; + if (ch == '/') { + while (1) { if (!GetNextChar(ch)) { - return FALSE; + return FALSE; } type = PDF_CharType[ch]; - if (type == 'D' || type == 'W') { - m_Pos --; - break; + if (type != 'R' && type != 'N') { + m_Pos--; + CFX_ByteString ret(m_WordBuffer, m_WordSize); + token = ret; + return TRUE; + } + if (m_WordSize < MAX_WORD_BUFFER) { + m_WordBuffer[m_WordSize++] = ch; } + } + } else if (ch == '<') { + if (!GetNextChar(ch)) { + return FALSE; + } + if (ch == '<') { + m_WordBuffer[m_WordSize++] = ch; + } else { + m_Pos--; + } + } else if (ch == '>') { + if (!GetNextChar(ch)) { + return FALSE; + } + if (ch == '>') { + m_WordBuffer[m_WordSize++] = ch; + } else { + m_Pos--; + } } CFX_ByteString ret(m_WordBuffer, m_WordSize); token = ret; return TRUE; -} -FX_BOOL CPDF_DataAvail::GetNextChar(uint8_t &ch) -{ - FX_FILESIZE pos = m_Pos; - if (pos >= m_dwFileLen) { - return FALSE; + } + while (1) { + if (m_WordSize < MAX_WORD_BUFFER) { + m_WordBuffer[m_WordSize++] = ch; } - if (m_bufferOffset >= pos || (FX_FILESIZE)(m_bufferOffset + m_bufferSize) <= pos) { - FX_FILESIZE read_pos = pos; - FX_DWORD read_size = 512; - if ((FX_FILESIZE)read_size > m_dwFileLen) { - read_size = (FX_DWORD)m_dwFileLen; - } - if ((FX_FILESIZE)(read_pos + read_size) > m_dwFileLen) { - read_pos = m_dwFileLen - read_size; - } - if (!m_pFileRead->ReadBlock(m_bufferData, read_pos, read_size)) { - return FALSE; - } - m_bufferOffset = read_pos; - m_bufferSize = read_size; + if (!GetNextChar(ch)) { + return FALSE; } - ch = m_bufferData[pos - m_bufferOffset]; - m_Pos ++; - return TRUE; -} -FX_BOOL CPDF_DataAvail::CheckCrossRefItem(IFX_DownloadHints *pHints) -{ - int32_t iSize = 0; - CFX_ByteString token; - while (1) { - if (!GetNextToken(token)) { - iSize = (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512); - pHints->AddSegment(m_Pos, iSize); - return FALSE; - } - if (token == "trailer") { - m_dwTrailerOffset = m_Pos; - m_docStatus = PDF_DATAAVAIL_TRAILER; - return TRUE; - } + type = PDF_CharType[ch]; + if (type == 'D' || type == 'W') { + m_Pos--; + break; } + } + CFX_ByteString ret(m_WordBuffer, m_WordSize); + token = ret; + return TRUE; } -FX_BOOL CPDF_DataAvail::CheckAllCrossRefStream(IFX_DownloadHints *pHints) -{ - FX_FILESIZE xref_offset = 0; - int32_t nRet = CheckCrossRefStream(pHints, xref_offset); - if (nRet == 1) { - if (!xref_offset) { - m_docStatus = PDF_DATAAVAIL_LOADALLCRSOSSREF; - } else { - m_dwCurrentXRefSteam = xref_offset; - m_Pos = xref_offset; - } - return TRUE; - } - if (nRet == -1) { - m_docStatus = PDF_DATAAVAIL_ERROR; - } +FX_BOOL CPDF_DataAvail::GetNextChar(uint8_t& ch) { + FX_FILESIZE pos = m_Pos; + if (pos >= m_dwFileLen) { return FALSE; + } + if (m_bufferOffset >= pos || + (FX_FILESIZE)(m_bufferOffset + m_bufferSize) <= pos) { + FX_FILESIZE read_pos = pos; + FX_DWORD read_size = 512; + if ((FX_FILESIZE)read_size > m_dwFileLen) { + read_size = (FX_DWORD)m_dwFileLen; + } + if ((FX_FILESIZE)(read_pos + read_size) > m_dwFileLen) { + read_pos = m_dwFileLen - read_size; + } + if (!m_pFileRead->ReadBlock(m_bufferData, read_pos, read_size)) { + return FALSE; + } + m_bufferOffset = read_pos; + m_bufferSize = read_size; + } + ch = m_bufferData[pos - m_bufferOffset]; + m_Pos++; + return TRUE; } -FX_BOOL CPDF_DataAvail::CheckCrossRef(IFX_DownloadHints* pHints) -{ - int32_t iSize = 0; - CFX_ByteString token; +FX_BOOL CPDF_DataAvail::CheckCrossRefItem(IFX_DownloadHints* pHints) { + int32_t iSize = 0; + CFX_ByteString token; + while (1) { if (!GetNextToken(token)) { - iSize = (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512); - pHints->AddSegment(m_Pos, iSize); - return FALSE; + iSize = (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512); + pHints->AddSegment(m_Pos, iSize); + return FALSE; } - if (token == "xref") { - m_CrossOffset.InsertAt(0, m_dwXRefOffset); - while (1) { - if (!GetNextToken(token)) { - iSize = (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512); - pHints->AddSegment(m_Pos, iSize); - m_docStatus = PDF_DATAAVAIL_CROSSREF_ITEM; - return FALSE; - } - if (token == "trailer") { - m_dwTrailerOffset = m_Pos; - m_docStatus = PDF_DATAAVAIL_TRAILER; - return TRUE; - } - } - } else { - m_docStatus = PDF_DATAAVAIL_LOADALLFILE; - return TRUE; + if (token == "trailer") { + m_dwTrailerOffset = m_Pos; + m_docStatus = PDF_DATAAVAIL_TRAILER; + return TRUE; } - return FALSE; + } } -FX_BOOL CPDF_DataAvail::CheckTrailerAppend(IFX_DownloadHints* pHints) -{ - if (m_Pos < m_dwFileLen) { - FX_FILESIZE dwAppendPos = m_Pos + m_syntaxParser.SavePos(); - int32_t iSize = (int32_t)(dwAppendPos + 512 > m_dwFileLen ? m_dwFileLen - dwAppendPos : 512); - if (!m_pFileAvail->IsDataAvail(dwAppendPos, iSize)) { - pHints->AddSegment(dwAppendPos, iSize); - return FALSE; - } - } - if (m_dwPrevXRefOffset) { - SetStartOffset(m_dwPrevXRefOffset); - m_docStatus = PDF_DATAAVAIL_CROSSREF; +FX_BOOL CPDF_DataAvail::CheckAllCrossRefStream(IFX_DownloadHints* pHints) { + FX_FILESIZE xref_offset = 0; + int32_t nRet = CheckCrossRefStream(pHints, xref_offset); + if (nRet == 1) { + if (!xref_offset) { + m_docStatus = PDF_DATAAVAIL_LOADALLCRSOSSREF; } else { - m_docStatus = PDF_DATAAVAIL_LOADALLCRSOSSREF; + m_dwCurrentXRefSteam = xref_offset; + m_Pos = xref_offset; } return TRUE; + } + if (nRet == -1) { + m_docStatus = PDF_DATAAVAIL_ERROR; + } + return FALSE; } -FX_BOOL CPDF_DataAvail::CheckTrailer(IFX_DownloadHints* pHints) -{ - int32_t iTrailerSize = (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512); - if (m_pFileAvail->IsDataAvail(m_Pos, iTrailerSize)) { - int32_t iSize = (int32_t)(m_Pos + iTrailerSize - m_dwTrailerOffset); - CFX_BinaryBuf buf(iSize); - uint8_t* pBuf = buf.GetBuffer(); - if (!pBuf) { - m_docStatus = PDF_DATAAVAIL_ERROR; - return FALSE; - } - if (!m_pFileRead->ReadBlock(pBuf, m_dwTrailerOffset, iSize)) { - return FALSE; - } - CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream(pBuf, (size_t)iSize, FALSE)); - m_syntaxParser.InitParser(file.Get(), 0); - CPDF_Object *pTrailer = m_syntaxParser.GetObject(NULL, 0, 0, 0); - if (!pTrailer) { - m_Pos += m_syntaxParser.SavePos(); - pHints->AddSegment(m_Pos, iTrailerSize); - return FALSE; - } - if (pTrailer->GetType() != PDFOBJ_DICTIONARY) { - return FALSE; - } - CPDF_Dictionary *pTrailerDict = pTrailer->GetDict(); - if (pTrailerDict) { - CPDF_Object *pEncrypt = pTrailerDict->GetElement("Encrypt"); - if (pEncrypt && pEncrypt->GetType() == PDFOBJ_REFERENCE) { - m_docStatus = PDF_DATAAVAIL_LOADALLFILE; - pTrailer->Release(); - return TRUE; - } - } - FX_DWORD xrefpos = GetDirectInteger(pTrailer->GetDict(), FX_BSTRC("Prev")); - if (xrefpos) { - m_dwPrevXRefOffset = GetDirectInteger(pTrailer->GetDict(), FX_BSTRC("XRefStm")); - pTrailer->Release(); - if (m_dwPrevXRefOffset) { - m_docStatus = PDF_DATAAVAIL_LOADALLFILE; - } else { - m_dwPrevXRefOffset = xrefpos; - if (m_dwPrevXRefOffset >= m_dwFileLen) { - m_docStatus = PDF_DATAAVAIL_LOADALLFILE; - } else { - SetStartOffset(m_dwPrevXRefOffset); - m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND; - } - } - return TRUE; - } - m_dwPrevXRefOffset = 0; - m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND; - pTrailer->Release(); +FX_BOOL CPDF_DataAvail::CheckCrossRef(IFX_DownloadHints* pHints) { + int32_t iSize = 0; + CFX_ByteString token; + if (!GetNextToken(token)) { + iSize = (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512); + pHints->AddSegment(m_Pos, iSize); + return FALSE; + } + if (token == "xref") { + m_CrossOffset.InsertAt(0, m_dwXRefOffset); + while (1) { + if (!GetNextToken(token)) { + iSize = + (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512); + pHints->AddSegment(m_Pos, iSize); + m_docStatus = PDF_DATAAVAIL_CROSSREF_ITEM; + return FALSE; + } + if (token == "trailer") { + m_dwTrailerOffset = m_Pos; + m_docStatus = PDF_DATAAVAIL_TRAILER; return TRUE; + } } - pHints->AddSegment(m_Pos, iTrailerSize); - return FALSE; + } else { + m_docStatus = PDF_DATAAVAIL_LOADALLFILE; + return TRUE; + } + return FALSE; } -FX_BOOL CPDF_DataAvail::CheckPage(int32_t iPage, IFX_DownloadHints* pHints) -{ - while (TRUE) { - switch (m_docStatus) { - case PDF_DATAAVAIL_PAGETREE: - if (!LoadDocPages(pHints)) { - return FALSE; - } - break; - case PDF_DATAAVAIL_PAGE: - if (!LoadDocPage(iPage, pHints)) { - return FALSE; - } - break; - case PDF_DATAAVAIL_ERROR: - return LoadAllFile(pHints); - default: - m_bPagesTreeLoad = TRUE; - m_bPagesLoad = TRUE; - m_bCurPageDictLoadOK = TRUE; - m_docStatus = PDF_DATAAVAIL_PAGE; - return TRUE; - } - } +FX_BOOL CPDF_DataAvail::CheckTrailerAppend(IFX_DownloadHints* pHints) { + if (m_Pos < m_dwFileLen) { + FX_FILESIZE dwAppendPos = m_Pos + m_syntaxParser.SavePos(); + int32_t iSize = (int32_t)( + dwAppendPos + 512 > m_dwFileLen ? m_dwFileLen - dwAppendPos : 512); + if (!m_pFileAvail->IsDataAvail(dwAppendPos, iSize)) { + pHints->AddSegment(dwAppendPos, iSize); + return FALSE; + } + } + if (m_dwPrevXRefOffset) { + SetStartOffset(m_dwPrevXRefOffset); + m_docStatus = PDF_DATAAVAIL_CROSSREF; + } else { + m_docStatus = PDF_DATAAVAIL_LOADALLCRSOSSREF; + } + return TRUE; } -FX_BOOL CPDF_DataAvail::CheckArrayPageNode(FX_DWORD dwPageNo, CPDF_PageNode *pPageNode, IFX_DownloadHints* pHints) -{ - FX_BOOL bExist = FALSE; - CPDF_Object *pPages = GetObject(dwPageNo, pHints, &bExist); - if (!bExist) { - m_docStatus = PDF_DATAAVAIL_ERROR; - return FALSE; - } - if (!pPages) { - if (m_docStatus == PDF_DATAAVAIL_ERROR) { - m_docStatus = PDF_DATAAVAIL_ERROR; - return FALSE; - } - return FALSE; - } - if (pPages->GetType() != PDFOBJ_ARRAY) { - pPages->Release(); - m_docStatus = PDF_DATAAVAIL_ERROR; - return FALSE; - } - pPageNode->m_type = PDF_PAGENODE_PAGES; - CPDF_Array* pArray = (CPDF_Array*)pPages; - for (FX_DWORD i = 0; i < pArray->GetCount(); ++i) { - CPDF_Object *pKid = (CPDF_Object *)pArray->GetElement(i); - if (!pKid || pKid->GetType() != PDFOBJ_REFERENCE) { - continue; +FX_BOOL CPDF_DataAvail::CheckTrailer(IFX_DownloadHints* pHints) { + int32_t iTrailerSize = + (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512); + if (m_pFileAvail->IsDataAvail(m_Pos, iTrailerSize)) { + int32_t iSize = (int32_t)(m_Pos + iTrailerSize - m_dwTrailerOffset); + CFX_BinaryBuf buf(iSize); + uint8_t* pBuf = buf.GetBuffer(); + if (!pBuf) { + m_docStatus = PDF_DATAAVAIL_ERROR; + return FALSE; + } + if (!m_pFileRead->ReadBlock(pBuf, m_dwTrailerOffset, iSize)) { + return FALSE; + } + CFX_SmartPointer<IFX_FileStream> file( + FX_CreateMemoryStream(pBuf, (size_t)iSize, FALSE)); + m_syntaxParser.InitParser(file.Get(), 0); + CPDF_Object* pTrailer = m_syntaxParser.GetObject(NULL, 0, 0, 0); + if (!pTrailer) { + m_Pos += m_syntaxParser.SavePos(); + pHints->AddSegment(m_Pos, iTrailerSize); + return FALSE; + } + if (pTrailer->GetType() != PDFOBJ_DICTIONARY) { + return FALSE; + } + CPDF_Dictionary* pTrailerDict = pTrailer->GetDict(); + if (pTrailerDict) { + CPDF_Object* pEncrypt = pTrailerDict->GetElement("Encrypt"); + if (pEncrypt && pEncrypt->GetType() == PDFOBJ_REFERENCE) { + m_docStatus = PDF_DATAAVAIL_LOADALLFILE; + pTrailer->Release(); + return TRUE; + } + } + FX_DWORD xrefpos = GetDirectInteger(pTrailer->GetDict(), FX_BSTRC("Prev")); + if (xrefpos) { + m_dwPrevXRefOffset = + GetDirectInteger(pTrailer->GetDict(), FX_BSTRC("XRefStm")); + pTrailer->Release(); + if (m_dwPrevXRefOffset) { + m_docStatus = PDF_DATAAVAIL_LOADALLFILE; + } else { + m_dwPrevXRefOffset = xrefpos; + if (m_dwPrevXRefOffset >= m_dwFileLen) { + m_docStatus = PDF_DATAAVAIL_LOADALLFILE; + } else { + SetStartOffset(m_dwPrevXRefOffset); + m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND; } - CPDF_PageNode *pNode = new CPDF_PageNode(); - pPageNode->m_childNode.Add(pNode); - pNode->m_dwPageNo = ((CPDF_Reference*)pKid)->GetRefObjNum(); + } + return TRUE; } - pPages->Release(); + m_dwPrevXRefOffset = 0; + m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND; + pTrailer->Release(); return TRUE; + } + pHints->AddSegment(m_Pos, iTrailerSize); + return FALSE; } -FX_BOOL CPDF_DataAvail::CheckUnkownPageNode(FX_DWORD dwPageNo, CPDF_PageNode *pPageNode, IFX_DownloadHints* pHints) -{ - FX_BOOL bExist = FALSE; - CPDF_Object *pPage = GetObject(dwPageNo, pHints, &bExist); - if (!bExist) { - m_docStatus = PDF_DATAAVAIL_ERROR; - return FALSE; - } - if (!pPage) { - if (m_docStatus == PDF_DATAAVAIL_ERROR) { - m_docStatus = PDF_DATAAVAIL_ERROR; - return FALSE; - } - return FALSE; - } - if (pPage->GetType() == PDFOBJ_ARRAY) { - pPageNode->m_dwPageNo = dwPageNo; - pPageNode->m_type = PDF_PAGENODE_ARRAY; - pPage->Release(); +FX_BOOL CPDF_DataAvail::CheckPage(int32_t iPage, IFX_DownloadHints* pHints) { + while (TRUE) { + switch (m_docStatus) { + case PDF_DATAAVAIL_PAGETREE: + if (!LoadDocPages(pHints)) { + return FALSE; + } + break; + case PDF_DATAAVAIL_PAGE: + if (!LoadDocPage(iPage, pHints)) { + return FALSE; + } + break; + case PDF_DATAAVAIL_ERROR: + return LoadAllFile(pHints); + default: + m_bPagesTreeLoad = TRUE; + m_bPagesLoad = TRUE; + m_bCurPageDictLoadOK = TRUE; + m_docStatus = PDF_DATAAVAIL_PAGE; return TRUE; } - if (pPage->GetType() != PDFOBJ_DICTIONARY) { - pPage->Release(); - m_docStatus = PDF_DATAAVAIL_ERROR; - return FALSE; + } +} +FX_BOOL CPDF_DataAvail::CheckArrayPageNode(FX_DWORD dwPageNo, + CPDF_PageNode* pPageNode, + IFX_DownloadHints* pHints) { + FX_BOOL bExist = FALSE; + CPDF_Object* pPages = GetObject(dwPageNo, pHints, &bExist); + if (!bExist) { + m_docStatus = PDF_DATAAVAIL_ERROR; + return FALSE; + } + if (!pPages) { + if (m_docStatus == PDF_DATAAVAIL_ERROR) { + m_docStatus = PDF_DATAAVAIL_ERROR; + return FALSE; } - pPageNode->m_dwPageNo = dwPageNo; - CPDF_Dictionary* pDict = pPage->GetDict(); - CFX_ByteString type = pDict ? pDict->GetString(FX_BSTRC("Type")) : CFX_ByteString(); - if (type == FX_BSTRC("Pages")) { - pPageNode->m_type = PDF_PAGENODE_PAGES; - CPDF_Object *pKids = pDict->GetElement(FX_BSTRC("Kids")); - if (!pKids) { - m_docStatus = PDF_DATAAVAIL_PAGE; - return TRUE; - } - switch (pKids->GetType()) { - case PDFOBJ_REFERENCE: { - CPDF_Reference *pKid = (CPDF_Reference *)pKids; - CPDF_PageNode *pNode = new CPDF_PageNode(); - pPageNode->m_childNode.Add(pNode); - pNode->m_dwPageNo = pKid->GetRefObjNum(); - } - break; - case PDFOBJ_ARRAY: { - CPDF_Array *pKidsArray = (CPDF_Array *)pKids; - for (FX_DWORD i = 0; i < pKidsArray->GetCount(); ++i) { - CPDF_Object *pKid = (CPDF_Object *)pKidsArray->GetElement(i); - if (!pKid || pKid->GetType() != PDFOBJ_REFERENCE) { - continue; - } - CPDF_PageNode *pNode = new CPDF_PageNode(); - pPageNode->m_childNode.Add(pNode); - pNode->m_dwPageNo = ((CPDF_Reference*)pKid)->GetRefObjNum(); - } - } - break; - default: - break; - } - } else if (type == FX_BSTRC("Page")) { - pPageNode->m_type = PDF_PAGENODE_PAGE; - } else { - pPage->Release(); - m_docStatus = PDF_DATAAVAIL_ERROR; - return FALSE; + return FALSE; + } + if (pPages->GetType() != PDFOBJ_ARRAY) { + pPages->Release(); + m_docStatus = PDF_DATAAVAIL_ERROR; + return FALSE; + } + pPageNode->m_type = PDF_PAGENODE_PAGES; + CPDF_Array* pArray = (CPDF_Array*)pPages; + for (FX_DWORD i = 0; i < pArray->GetCount(); ++i) { + CPDF_Object* pKid = (CPDF_Object*)pArray->GetElement(i); + if (!pKid || pKid->GetType() != PDFOBJ_REFERENCE) { + continue; + } + CPDF_PageNode* pNode = new CPDF_PageNode(); + pPageNode->m_childNode.Add(pNode); + pNode->m_dwPageNo = ((CPDF_Reference*)pKid)->GetRefObjNum(); + } + pPages->Release(); + return TRUE; +} +FX_BOOL CPDF_DataAvail::CheckUnkownPageNode(FX_DWORD dwPageNo, + CPDF_PageNode* pPageNode, + IFX_DownloadHints* pHints) { + FX_BOOL bExist = FALSE; + CPDF_Object* pPage = GetObject(dwPageNo, pHints, &bExist); + if (!bExist) { + m_docStatus = PDF_DATAAVAIL_ERROR; + return FALSE; + } + if (!pPage) { + if (m_docStatus == PDF_DATAAVAIL_ERROR) { + m_docStatus = PDF_DATAAVAIL_ERROR; + return FALSE; } + return FALSE; + } + if (pPage->GetType() == PDFOBJ_ARRAY) { + pPageNode->m_dwPageNo = dwPageNo; + pPageNode->m_type = PDF_PAGENODE_ARRAY; pPage->Release(); return TRUE; -} -FX_BOOL CPDF_DataAvail::CheckPageNode(CPDF_PageNode &pageNodes, int32_t iPage, int32_t &iCount, IFX_DownloadHints* pHints) -{ - int32_t iSize = pageNodes.m_childNode.GetSize(); - if (iSize <= 0 || iPage >= iSize) { - m_docStatus = PDF_DATAAVAIL_ERROR; - return FALSE; + } + if (pPage->GetType() != PDFOBJ_DICTIONARY) { + pPage->Release(); + m_docStatus = PDF_DATAAVAIL_ERROR; + return FALSE; + } + pPageNode->m_dwPageNo = dwPageNo; + CPDF_Dictionary* pDict = pPage->GetDict(); + CFX_ByteString type = + pDict ? pDict->GetString(FX_BSTRC("Type")) : CFX_ByteString(); + if (type == FX_BSTRC("Pages")) { + pPageNode->m_type = PDF_PAGENODE_PAGES; + CPDF_Object* pKids = pDict->GetElement(FX_BSTRC("Kids")); + if (!pKids) { + m_docStatus = PDF_DATAAVAIL_PAGE; + return TRUE; } - for (int32_t i = 0; i < iSize; ++i) { - CPDF_PageNode *pNode = (CPDF_PageNode*)pageNodes.m_childNode.GetAt(i); - if (!pNode) { + switch (pKids->GetType()) { + case PDFOBJ_REFERENCE: { + CPDF_Reference* pKid = (CPDF_Reference*)pKids; + CPDF_PageNode* pNode = new CPDF_PageNode(); + pPageNode->m_childNode.Add(pNode); + pNode->m_dwPageNo = pKid->GetRefObjNum(); + } break; + case PDFOBJ_ARRAY: { + CPDF_Array* pKidsArray = (CPDF_Array*)pKids; + for (FX_DWORD i = 0; i < pKidsArray->GetCount(); ++i) { + CPDF_Object* pKid = (CPDF_Object*)pKidsArray->GetElement(i); + if (!pKid || pKid->GetType() != PDFOBJ_REFERENCE) { continue; - } - switch (pNode->m_type) { - case PDF_PAGENODE_UNKOWN: - if (!CheckUnkownPageNode(pNode->m_dwPageNo, pNode, pHints)) { - return FALSE; - } - --i; - break; - case PDF_PAGENODE_PAGE: - iCount++; - if (iPage == iCount && m_pDocument) { - m_pDocument->m_PageList.SetAt(iPage, pNode->m_dwPageNo); - } - break; - case PDF_PAGENODE_PAGES: - if (!CheckPageNode(*pNode, iPage, iCount, pHints)) { - return FALSE; - } - break; - case PDF_PAGENODE_ARRAY: - if (!CheckArrayPageNode(pNode->m_dwPageNo, pNode, pHints)) { - return FALSE; - } - --i; - break; - } - if (iPage == iCount) { - m_docStatus = PDF_DATAAVAIL_DONE; - return TRUE; - } - } - return TRUE; + } + CPDF_PageNode* pNode = new CPDF_PageNode(); + pPageNode->m_childNode.Add(pNode); + pNode->m_dwPageNo = ((CPDF_Reference*)pKid)->GetRefObjNum(); + } + } break; + default: + break; + } + } else if (type == FX_BSTRC("Page")) { + pPageNode->m_type = PDF_PAGENODE_PAGE; + } else { + pPage->Release(); + m_docStatus = PDF_DATAAVAIL_ERROR; + return FALSE; + } + pPage->Release(); + return TRUE; } -FX_BOOL CPDF_DataAvail::LoadDocPage(int32_t iPage, IFX_DownloadHints* pHints) -{ - if (m_pDocument->GetPageCount() <= iPage || m_pDocument->m_PageList.GetAt(iPage)) { - m_docStatus = PDF_DATAAVAIL_DONE; - return TRUE; - } - if (m_pageNodes.m_type == PDF_PAGENODE_PAGE) { - if (iPage == 0) { - m_docStatus = PDF_DATAAVAIL_DONE; - return TRUE; - } - m_docStatus = PDF_DATAAVAIL_ERROR; - return TRUE; - } - int32_t iCount = -1; - return CheckPageNode(m_pageNodes, iPage, iCount, pHints); +FX_BOOL CPDF_DataAvail::CheckPageNode(CPDF_PageNode& pageNodes, + int32_t iPage, + int32_t& iCount, + IFX_DownloadHints* pHints) { + int32_t iSize = pageNodes.m_childNode.GetSize(); + if (iSize <= 0 || iPage >= iSize) { + m_docStatus = PDF_DATAAVAIL_ERROR; + return FALSE; + } + for (int32_t i = 0; i < iSize; ++i) { + CPDF_PageNode* pNode = (CPDF_PageNode*)pageNodes.m_childNode.GetAt(i); + if (!pNode) { + continue; + } + switch (pNode->m_type) { + case PDF_PAGENODE_UNKOWN: + if (!CheckUnkownPageNode(pNode->m_dwPageNo, pNode, pHints)) { + return FALSE; + } + --i; + break; + case PDF_PAGENODE_PAGE: + iCount++; + if (iPage == iCount && m_pDocument) { + m_pDocument->m_PageList.SetAt(iPage, pNode->m_dwPageNo); + } + break; + case PDF_PAGENODE_PAGES: + if (!CheckPageNode(*pNode, iPage, iCount, pHints)) { + return FALSE; + } + break; + case PDF_PAGENODE_ARRAY: + if (!CheckArrayPageNode(pNode->m_dwPageNo, pNode, pHints)) { + return FALSE; + } + --i; + break; + } + if (iPage == iCount) { + m_docStatus = PDF_DATAAVAIL_DONE; + return TRUE; + } + } + return TRUE; } -FX_BOOL CPDF_DataAvail::CheckPageCount(IFX_DownloadHints* pHints) -{ - FX_BOOL bExist = FALSE; - CPDF_Object *pPages = GetObject(m_PagesObjNum, pHints, &bExist); - if (!bExist) { - m_docStatus = PDF_DATAAVAIL_ERROR; - return FALSE; - } - if (!pPages) { - return FALSE; - } - CPDF_Dictionary* pPagesDict = pPages->GetDict(); - if (!pPagesDict) { - pPages->Release(); - m_docStatus = PDF_DATAAVAIL_ERROR; - return FALSE; - } - if (!pPagesDict->KeyExist(FX_BSTRC("Kids"))) { - pPages->Release(); - return TRUE; - } - int count = pPagesDict->GetInteger(FX_BSTRC("Count")); - if (count > 0) { - pPages->Release(); - return TRUE; +FX_BOOL CPDF_DataAvail::LoadDocPage(int32_t iPage, IFX_DownloadHints* pHints) { + if (m_pDocument->GetPageCount() <= iPage || + m_pDocument->m_PageList.GetAt(iPage)) { + m_docStatus = PDF_DATAAVAIL_DONE; + return TRUE; + } + if (m_pageNodes.m_type == PDF_PAGENODE_PAGE) { + if (iPage == 0) { + m_docStatus = PDF_DATAAVAIL_DONE; + return TRUE; } + m_docStatus = PDF_DATAAVAIL_ERROR; + return TRUE; + } + int32_t iCount = -1; + return CheckPageNode(m_pageNodes, iPage, iCount, pHints); +} +FX_BOOL CPDF_DataAvail::CheckPageCount(IFX_DownloadHints* pHints) { + FX_BOOL bExist = FALSE; + CPDF_Object* pPages = GetObject(m_PagesObjNum, pHints, &bExist); + if (!bExist) { + m_docStatus = PDF_DATAAVAIL_ERROR; + return FALSE; + } + if (!pPages) { + return FALSE; + } + CPDF_Dictionary* pPagesDict = pPages->GetDict(); + if (!pPagesDict) { pPages->Release(); + m_docStatus = PDF_DATAAVAIL_ERROR; return FALSE; + } + if (!pPagesDict->KeyExist(FX_BSTRC("Kids"))) { + pPages->Release(); + return TRUE; + } + int count = pPagesDict->GetInteger(FX_BSTRC("Count")); + if (count > 0) { + pPages->Release(); + return TRUE; + } + pPages->Release(); + return FALSE; } -FX_BOOL CPDF_DataAvail::LoadDocPages(IFX_DownloadHints* pHints) -{ - if (!CheckUnkownPageNode(m_PagesObjNum, &m_pageNodes, pHints)) { - return FALSE; - } - if (CheckPageCount(pHints)) { - m_docStatus = PDF_DATAAVAIL_PAGE; - return TRUE; - } - m_bTotalLoadPageTree = TRUE; +FX_BOOL CPDF_DataAvail::LoadDocPages(IFX_DownloadHints* pHints) { + if (!CheckUnkownPageNode(m_PagesObjNum, &m_pageNodes, pHints)) { return FALSE; + } + if (CheckPageCount(pHints)) { + m_docStatus = PDF_DATAAVAIL_PAGE; + return TRUE; + } + m_bTotalLoadPageTree = TRUE; + return FALSE; } -FX_BOOL CPDF_DataAvail::LoadPages(IFX_DownloadHints* pHints) -{ - while (!m_bPagesTreeLoad) { - if (!CheckPageStatus(pHints)) { - return FALSE; - } - } - if (m_bPagesLoad) { - return TRUE; +FX_BOOL CPDF_DataAvail::LoadPages(IFX_DownloadHints* pHints) { + while (!m_bPagesTreeLoad) { + if (!CheckPageStatus(pHints)) { + return FALSE; } - m_pDocument->LoadPages(); - return FALSE; + } + if (m_bPagesLoad) { + return TRUE; + } + m_pDocument->LoadPages(); + return FALSE; } -FX_BOOL CPDF_DataAvail::CheckLinearizedData(IFX_DownloadHints* pHints) -{ - if (m_bLinearedDataOK) { - return TRUE; - } +FX_BOOL CPDF_DataAvail::CheckLinearizedData(IFX_DownloadHints* pHints) { + if (m_bLinearedDataOK) { + return TRUE; + } - if (!m_bMainXRefLoadTried) { - FX_SAFE_DWORD data_size = m_dwFileLen; - data_size -= m_dwLastXRefOffset; - if (!data_size.IsValid()) { - return FALSE; - } - if (!m_pFileAvail->IsDataAvail(m_dwLastXRefOffset, data_size.ValueOrDie())) { - pHints->AddSegment(m_dwLastXRefOffset, data_size.ValueOrDie()); - return FALSE; - } - FX_DWORD dwRet = ((CPDF_Parser *)m_pDocument->GetParser())->LoadLinearizedMainXRefTable(); - m_bMainXRefLoadTried = TRUE; - if (dwRet != PDFPARSE_ERROR_SUCCESS) { - return FALSE; - } - if (!PreparePageItem()) { - return FALSE; - } - m_bMainXRefLoadedOK = TRUE; - m_bLinearedDataOK = TRUE; + if (!m_bMainXRefLoadTried) { + FX_SAFE_DWORD data_size = m_dwFileLen; + data_size -= m_dwLastXRefOffset; + if (!data_size.IsValid()) { + return FALSE; + } + if (!m_pFileAvail->IsDataAvail(m_dwLastXRefOffset, + data_size.ValueOrDie())) { + pHints->AddSegment(m_dwLastXRefOffset, data_size.ValueOrDie()); + return FALSE; + } + FX_DWORD dwRet = + ((CPDF_Parser*)m_pDocument->GetParser())->LoadLinearizedMainXRefTable(); + m_bMainXRefLoadTried = TRUE; + if (dwRet != PDFPARSE_ERROR_SUCCESS) { + return FALSE; } + if (!PreparePageItem()) { + return FALSE; + } + m_bMainXRefLoadedOK = TRUE; + m_bLinearedDataOK = TRUE; + } - return m_bLinearedDataOK; + return m_bLinearedDataOK; } -FX_BOOL CPDF_DataAvail::CheckPageAnnots(int32_t iPage, IFX_DownloadHints* pHints) -{ - if (!m_objs_array.GetSize()) { - m_objs_array.RemoveAll(); - m_objnum_array.RemoveAll(); - CPDF_Dictionary *pPageDict = m_pDocument->GetPage(iPage); - if (!pPageDict) { - return TRUE; - } - CPDF_Object *pAnnots = pPageDict->GetElement(FX_BSTRC("Annots")); - if (!pAnnots) { - return TRUE; - } - CFX_PtrArray obj_array; - obj_array.Add(pAnnots); - FX_BOOL bRet = IsObjectsAvail(obj_array, FALSE, pHints, m_objs_array); - if (bRet) { - m_objs_array.RemoveAll(); - } - return bRet; - } - CFX_PtrArray new_objs_array; - FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); +FX_BOOL CPDF_DataAvail::CheckPageAnnots(int32_t iPage, + IFX_DownloadHints* pHints) { + if (!m_objs_array.GetSize()) { m_objs_array.RemoveAll(); - if (!bRet) { - m_objs_array.Append(new_objs_array); + m_objnum_array.RemoveAll(); + CPDF_Dictionary* pPageDict = m_pDocument->GetPage(iPage); + if (!pPageDict) { + return TRUE; + } + CPDF_Object* pAnnots = pPageDict->GetElement(FX_BSTRC("Annots")); + if (!pAnnots) { + return TRUE; + } + CFX_PtrArray obj_array; + obj_array.Add(pAnnots); + FX_BOOL bRet = IsObjectsAvail(obj_array, FALSE, pHints, m_objs_array); + if (bRet) { + m_objs_array.RemoveAll(); } return bRet; + } + CFX_PtrArray new_objs_array; + FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); + m_objs_array.RemoveAll(); + if (!bRet) { + m_objs_array.Append(new_objs_array); + } + return bRet; } -FX_BOOL CPDF_DataAvail::CheckLinearizedFirstPage(int32_t iPage, IFX_DownloadHints* pHints) -{ - if (!m_bAnnotsLoad) { - if (!CheckPageAnnots(iPage, pHints)) { - return FALSE; - } - m_bAnnotsLoad = TRUE; - } - if (m_bAnnotsLoad) { - if (!CheckLinearizedData(pHints)) - return FALSE; - } - m_bPageLoadedOK = FALSE; +FX_BOOL CPDF_DataAvail::CheckLinearizedFirstPage(int32_t iPage, + IFX_DownloadHints* pHints) { + if (!m_bAnnotsLoad) { + if (!CheckPageAnnots(iPage, pHints)) { + return FALSE; + } + m_bAnnotsLoad = TRUE; + } + if (m_bAnnotsLoad) { + if (!CheckLinearizedData(pHints)) + return FALSE; + } + m_bPageLoadedOK = FALSE; + return TRUE; +} +FX_BOOL CPDF_DataAvail::HaveResourceAncestor(CPDF_Dictionary* pDict) { + CFX_AutoRestorer<int> restorer(&s_CurrentDataAvailRecursionDepth); + if (++s_CurrentDataAvailRecursionDepth > kMaxDataAvailRecursionDepth) { + return FALSE; + } + CPDF_Object* pParent = pDict->GetElement("Parent"); + if (!pParent) { + return FALSE; + } + CPDF_Dictionary* pParentDict = pParent->GetDict(); + if (!pParentDict) { + return FALSE; + } + CPDF_Object* pRet = pParentDict->GetElement("Resources"); + if (pRet) { + m_pPageResource = pRet; return TRUE; + } + return HaveResourceAncestor(pParentDict); } -FX_BOOL CPDF_DataAvail::HaveResourceAncestor(CPDF_Dictionary *pDict) -{ - CFX_AutoRestorer<int> restorer(&s_CurrentDataAvailRecursionDepth); - if (++s_CurrentDataAvailRecursionDepth > kMaxDataAvailRecursionDepth) { - return FALSE; +FX_BOOL CPDF_DataAvail::IsPageAvail(int32_t iPage, IFX_DownloadHints* pHints) { + if (!m_pDocument) { + return FALSE; + } + if (IsFirstCheck(iPage)) { + m_bCurPageDictLoadOK = FALSE; + m_bPageLoadedOK = FALSE; + m_bAnnotsLoad = FALSE; + m_bNeedDownLoadResource = FALSE; + m_objs_array.RemoveAll(); + m_objnum_array.RemoveAll(); + } + if (m_pagesLoadState == NULL) { + m_pagesLoadState = new CFX_CMapDWordToDWord(); + } + FX_DWORD dwPageLoad = 0; + if (m_pagesLoadState->Lookup(iPage, dwPageLoad) && dwPageLoad != 0) { + return TRUE; + } + if (m_bLinearized) { + if ((FX_DWORD)iPage == m_dwFirstPageNo) { + m_pagesLoadState->SetAt(iPage, TRUE); + return TRUE; } - CPDF_Object *pParent = pDict->GetElement("Parent"); - if (!pParent) { - return FALSE; + if (!CheckLinearizedData(pHints)) { + return FALSE; } - CPDF_Dictionary *pParentDict = pParent->GetDict(); - if (!pParentDict) { + if (m_bMainXRefLoadedOK) { + if (m_bTotalLoadPageTree) { + if (!LoadPages(pHints)) { + return FALSE; + } + } else { + if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) { + return FALSE; + } + } + } else { + if (!LoadAllFile(pHints)) { return FALSE; - } - CPDF_Object *pRet = pParentDict->GetElement("Resources"); - if (pRet) { - m_pPageResource = pRet; - return TRUE; - } - return HaveResourceAncestor(pParentDict); -} -FX_BOOL CPDF_DataAvail::IsPageAvail(int32_t iPage, IFX_DownloadHints* pHints) -{ - if (!m_pDocument) { + } + ((CPDF_Parser*)m_pDocument->GetParser())->RebuildCrossRef(); + ResetFirstCheck(iPage); + return TRUE; + } + } else { + if (!m_bTotalLoadPageTree) { + if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) { return FALSE; + } } - if (IsFirstCheck(iPage)) { - m_bCurPageDictLoadOK = FALSE; - m_bPageLoadedOK = FALSE; - m_bAnnotsLoad = FALSE; - m_bNeedDownLoadResource = FALSE; - m_objs_array.RemoveAll(); - m_objnum_array.RemoveAll(); - } - if (m_pagesLoadState == NULL) { - m_pagesLoadState = new CFX_CMapDWordToDWord(); + } + if (m_bHaveAcroForm && !m_bAcroFormLoad) { + if (!CheckAcroFormSubObject(pHints)) { + return FALSE; } - FX_DWORD dwPageLoad = 0; - if (m_pagesLoadState->Lookup(iPage, dwPageLoad) && dwPageLoad != 0) { + m_bAcroFormLoad = TRUE; + } + if (!m_bPageLoadedOK) { + if (!m_objs_array.GetSize()) { + m_objs_array.RemoveAll(); + m_objnum_array.RemoveAll(); + m_pPageDict = m_pDocument->GetPage(iPage); + if (!m_pPageDict) { + ResetFirstCheck(iPage); return TRUE; - } - if (m_bLinearized) { - if ((FX_DWORD)iPage == m_dwFirstPageNo) { - m_pagesLoadState->SetAt(iPage, TRUE); - return TRUE; - } - if (!CheckLinearizedData(pHints)) { - return FALSE; - } - if (m_bMainXRefLoadedOK) { - if (m_bTotalLoadPageTree) { - if (!LoadPages(pHints)) { - return FALSE; - } - } else { - if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) { - return FALSE; - } - } - } else { - if (!LoadAllFile(pHints)) { - return FALSE; - } - ((CPDF_Parser *)m_pDocument->GetParser())->RebuildCrossRef(); - ResetFirstCheck(iPage); - return TRUE; - } + } + CFX_PtrArray obj_array; + obj_array.Add(m_pPageDict); + FX_BOOL bRet = IsObjectsAvail(obj_array, TRUE, pHints, m_objs_array); + if (bRet) { + m_objs_array.RemoveAll(); + m_bPageLoadedOK = TRUE; + } else { + return bRet; + } } else { - if (!m_bTotalLoadPageTree) { - if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) { - return FALSE; - } - } - } - if (m_bHaveAcroForm && !m_bAcroFormLoad) { - if (!CheckAcroFormSubObject(pHints)) { - return FALSE; - } - m_bAcroFormLoad = TRUE; - } - if (!m_bPageLoadedOK) { - if (!m_objs_array.GetSize()) { - m_objs_array.RemoveAll(); - m_objnum_array.RemoveAll(); - m_pPageDict = m_pDocument->GetPage(iPage); - if (!m_pPageDict) { - ResetFirstCheck(iPage); - return TRUE; - } - CFX_PtrArray obj_array; - obj_array.Add(m_pPageDict); - FX_BOOL bRet = IsObjectsAvail(obj_array, TRUE, pHints, m_objs_array); - if (bRet) { - m_objs_array.RemoveAll(); - m_bPageLoadedOK = TRUE; - } else { - return bRet; - } - } else { - CFX_PtrArray new_objs_array; - FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); - m_objs_array.RemoveAll(); - if (bRet) { - m_bPageLoadedOK = TRUE; - } else { - m_objs_array.Append(new_objs_array); - return bRet; - } - } - } - if (m_bPageLoadedOK) { - if (!m_bAnnotsLoad) { - if (!CheckPageAnnots(iPage, pHints)) { - return FALSE; - } - m_bAnnotsLoad = TRUE; - } + CFX_PtrArray new_objs_array; + FX_BOOL bRet = + IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); + m_objs_array.RemoveAll(); + if (bRet) { + m_bPageLoadedOK = TRUE; + } else { + m_objs_array.Append(new_objs_array); + return bRet; + } } - if (m_pPageDict && !m_bNeedDownLoadResource) { - m_pPageResource = m_pPageDict->GetElement("Resources"); - if (!m_pPageResource) { - m_bNeedDownLoadResource = HaveResourceAncestor(m_pPageDict); - } else { - m_bNeedDownLoadResource = TRUE; - } + } + if (m_bPageLoadedOK) { + if (!m_bAnnotsLoad) { + if (!CheckPageAnnots(iPage, pHints)) { + return FALSE; + } + m_bAnnotsLoad = TRUE; + } + } + if (m_pPageDict && !m_bNeedDownLoadResource) { + m_pPageResource = m_pPageDict->GetElement("Resources"); + if (!m_pPageResource) { + m_bNeedDownLoadResource = HaveResourceAncestor(m_pPageDict); + } else { + m_bNeedDownLoadResource = TRUE; } - if (m_bNeedDownLoadResource) { - FX_BOOL bRet = CheckResources(pHints); - if (!bRet) { - return FALSE; - } - m_bNeedDownLoadResource = FALSE; + } + if (m_bNeedDownLoadResource) { + FX_BOOL bRet = CheckResources(pHints); + if (!bRet) { + return FALSE; } - m_bPageLoadedOK = FALSE; - m_bAnnotsLoad = FALSE; - m_bCurPageDictLoadOK = FALSE; - ResetFirstCheck(iPage); - m_pagesLoadState->SetAt(iPage, TRUE); - return TRUE; + m_bNeedDownLoadResource = FALSE; + } + m_bPageLoadedOK = FALSE; + m_bAnnotsLoad = FALSE; + m_bCurPageDictLoadOK = FALSE; + ResetFirstCheck(iPage); + m_pagesLoadState->SetAt(iPage, TRUE); + return TRUE; } -FX_BOOL CPDF_DataAvail::CheckResources(IFX_DownloadHints* pHints) -{ - if (!m_objs_array.GetSize()) { - m_objs_array.RemoveAll(); - CFX_PtrArray obj_array; - obj_array.Add(m_pPageResource); - FX_BOOL bRet = IsObjectsAvail(obj_array, TRUE, pHints, m_objs_array); - if (bRet) { - m_objs_array.RemoveAll(); - } - return bRet; - } - CFX_PtrArray new_objs_array; - FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); +FX_BOOL CPDF_DataAvail::CheckResources(IFX_DownloadHints* pHints) { + if (!m_objs_array.GetSize()) { m_objs_array.RemoveAll(); - if (!bRet) { - m_objs_array.Append(new_objs_array); + CFX_PtrArray obj_array; + obj_array.Add(m_pPageResource); + FX_BOOL bRet = IsObjectsAvail(obj_array, TRUE, pHints, m_objs_array); + if (bRet) { + m_objs_array.RemoveAll(); } return bRet; + } + CFX_PtrArray new_objs_array; + FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); + m_objs_array.RemoveAll(); + if (!bRet) { + m_objs_array.Append(new_objs_array); + } + return bRet; } -void CPDF_DataAvail::GetLinearizedMainXRefInfo(FX_FILESIZE *pPos, FX_DWORD *pSize) -{ - if (pPos) { - *pPos = m_dwLastXRefOffset; - } - if (pSize) { - *pSize = (FX_DWORD)(m_dwFileLen - m_dwLastXRefOffset); - } +void CPDF_DataAvail::GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, + FX_DWORD* pSize) { + if (pPos) { + *pPos = m_dwLastXRefOffset; + } + if (pSize) { + *pSize = (FX_DWORD)(m_dwFileLen - m_dwLastXRefOffset); + } } -int32_t CPDF_DataAvail::IsFormAvail(IFX_DownloadHints *pHints) -{ - if (!m_pDocument) { - return PDFFORM_AVAIL; - } - if (!m_bLinearizedFormParamLoad) { - CPDF_Dictionary *pRoot = m_pDocument->GetRoot(); - if (!pRoot) { - return PDFFORM_AVAIL; - } - CPDF_Object *pAcroForm = pRoot->GetElement(FX_BSTRC("AcroForm")); - if (!pAcroForm) { - return PDFFORM_NOTEXIST; - } - if (!CheckLinearizedData(pHints)) { - return PDFFORM_NOTAVAIL; - } - if (!m_objs_array.GetSize()) { - m_objs_array.Add(pAcroForm->GetDict()); - } - m_bLinearizedFormParamLoad = TRUE; +int32_t CPDF_DataAvail::IsFormAvail(IFX_DownloadHints* pHints) { + if (!m_pDocument) { + return PDFFORM_AVAIL; + } + if (!m_bLinearizedFormParamLoad) { + CPDF_Dictionary* pRoot = m_pDocument->GetRoot(); + if (!pRoot) { + return PDFFORM_AVAIL; } - CFX_PtrArray new_objs_array; - FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); - m_objs_array.RemoveAll(); - if (!bRet) { - m_objs_array.Append(new_objs_array); - return PDFFORM_NOTAVAIL; + CPDF_Object* pAcroForm = pRoot->GetElement(FX_BSTRC("AcroForm")); + if (!pAcroForm) { + return PDFFORM_NOTEXIST; } - return PDFFORM_AVAIL; -} -void CPDF_SortObjNumArray::AddObjNum(FX_DWORD dwObjNum) -{ - int32_t iNext = 0; - if (BinarySearch(dwObjNum, iNext)) { - return; + if (!CheckLinearizedData(pHints)) { + return PDFFORM_NOTAVAIL; } - m_number_array.InsertAt(iNext, dwObjNum); + if (!m_objs_array.GetSize()) { + m_objs_array.Add(pAcroForm->GetDict()); + } + m_bLinearizedFormParamLoad = TRUE; + } + CFX_PtrArray new_objs_array; + FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array); + m_objs_array.RemoveAll(); + if (!bRet) { + m_objs_array.Append(new_objs_array); + return PDFFORM_NOTAVAIL; + } + return PDFFORM_AVAIL; } -FX_BOOL CPDF_SortObjNumArray::Find(FX_DWORD dwObjNum) -{ - int32_t iNext = 0; - return BinarySearch(dwObjNum, iNext); +void CPDF_SortObjNumArray::AddObjNum(FX_DWORD dwObjNum) { + int32_t iNext = 0; + if (BinarySearch(dwObjNum, iNext)) { + return; + } + m_number_array.InsertAt(iNext, dwObjNum); } -FX_BOOL CPDF_SortObjNumArray::BinarySearch(FX_DWORD value, int32_t &iNext) -{ - int32_t iLow = 0; - int32_t iHigh = m_number_array.GetSize() - 1; - while (iLow <= iHigh) { - int32_t iMid = (iLow + iHigh) / 2; - if (m_number_array.GetAt(iMid) == value) { - iNext = iMid; - return TRUE; - } - if (m_number_array.GetAt(iMid) > value) { - iHigh = iMid - 1; - } else if (m_number_array.GetAt(iMid) < value) { - iLow = iMid + 1; - } - } - iNext = iLow; - return FALSE; +FX_BOOL CPDF_SortObjNumArray::Find(FX_DWORD dwObjNum) { + int32_t iNext = 0; + return BinarySearch(dwObjNum, iNext); } -CPDF_PageNode::~CPDF_PageNode() -{ - int32_t iSize = m_childNode.GetSize(); - for (int32_t i = 0; i < iSize; ++i) { - CPDF_PageNode* pNode = (CPDF_PageNode*)m_childNode[i]; - delete pNode; - } - m_childNode.RemoveAll(); +FX_BOOL CPDF_SortObjNumArray::BinarySearch(FX_DWORD value, int32_t& iNext) { + int32_t iLow = 0; + int32_t iHigh = m_number_array.GetSize() - 1; + while (iLow <= iHigh) { + int32_t iMid = (iLow + iHigh) / 2; + if (m_number_array.GetAt(iMid) == value) { + iNext = iMid; + return TRUE; + } + if (m_number_array.GetAt(iMid) > value) { + iHigh = iMid - 1; + } else if (m_number_array.GetAt(iMid) < value) { + iLow = iMid + 1; + } + } + iNext = iLow; + return FALSE; +} +CPDF_PageNode::~CPDF_PageNode() { + int32_t iSize = m_childNode.GetSize(); + for (int32_t i = 0; i < iSize; ++i) { + CPDF_PageNode* pNode = (CPDF_PageNode*)m_childNode[i]; + delete pNode; + } + m_childNode.RemoveAll(); } diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser_embeddertest.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser_embeddertest.cpp index 882a915edd..96ea766d4d 100644 --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser_embeddertest.cpp +++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser_embeddertest.cpp @@ -5,8 +5,7 @@ #include "../../../testing/embedder_test.h" #include "testing/gtest/include/gtest/gtest.h" -class FPDFParserEmbeddertest : public EmbedderTest { -}; +class FPDFParserEmbeddertest : public EmbedderTest {}; TEST_F(FPDFParserEmbeddertest, LoadError_454695) { // Test trailer dictionary with $$ze instead of Size. diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_utility.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_utility.cpp index 4903312645..9e1434139c 100644 --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_utility.cpp +++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_utility.cpp @@ -6,475 +6,479 @@ #include "../../../include/fpdfapi/fpdf_parser.h" const char PDF_CharType[256] = { - //NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI - 'W', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'W', 'W', 'R', 'W', 'W', 'R', 'R', + // NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO + // SI + 'W', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'W', 'W', 'R', 'W', 'W', 'R', + 'R', - //DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US - 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', + // DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS + // US + 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', + 'R', - //SP ! " # $ % & ´ ( ) * + , - . / - 'W', 'R', 'R', 'R', 'R', 'D', 'R', 'R', 'D', 'D', 'R', 'N', 'R', 'N', 'N', 'D', + // SP ! " # $ % & ´ ( ) * + , - . + // / + 'W', 'R', 'R', 'R', 'R', 'D', 'R', 'R', 'D', 'D', 'R', 'N', 'R', 'N', 'N', + 'D', - // 0 1 2 3 4 5 6 7 8 9 : ; < = > ? - 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'R', 'R', 'D', 'R', 'D', 'R', + // 0 1 2 3 4 5 6 7 8 9 : ; < = > ? + 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'R', 'R', 'D', 'R', 'D', + 'R', - // @ A B C D E F G H I J K L M N O - 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', + // @ A B C D E F G H I J K L M N O + 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', + 'R', - // P Q R S T U V W X Y Z [ \ ] ^ _ - 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'D', 'R', 'D', 'R', 'R', + // P Q R S T U V W X Y Z [ \ ] ^ _ + 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'D', 'R', 'D', 'R', + 'R', - // ` a b c d e f g h i j k l m n o - 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', + // ` a b c d e f g h i j k l m n o + 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', + 'R', - // p q r s t u v w x y z { | } ~ DEL - 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'D', 'R', 'D', 'R', 'R', + // p q r s t u v w x y z { | } ~ + // DEL + 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'D', 'R', 'D', 'R', + 'R', - 'W', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', - 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', - 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', - 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', - 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', - 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', - 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', - 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'W' -}; + 'W', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', + 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', + 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', + 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', + 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', + 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', + 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', + 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', + 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'W'}; #ifndef MAX_PATH #define MAX_PATH 4096 #endif -CPDF_SimpleParser::CPDF_SimpleParser(const uint8_t* pData, FX_DWORD dwSize) -{ - m_pData = pData; - m_dwSize = dwSize; - m_dwCurPos = 0; +CPDF_SimpleParser::CPDF_SimpleParser(const uint8_t* pData, FX_DWORD dwSize) { + m_pData = pData; + m_dwSize = dwSize; + m_dwCurPos = 0; } -CPDF_SimpleParser::CPDF_SimpleParser(const CFX_ByteStringC& str) -{ - m_pData = str.GetPtr(); - m_dwSize = str.GetLength(); - m_dwCurPos = 0; +CPDF_SimpleParser::CPDF_SimpleParser(const CFX_ByteStringC& str) { + m_pData = str.GetPtr(); + m_dwSize = str.GetLength(); + m_dwCurPos = 0; } -void CPDF_SimpleParser::ParseWord(const uint8_t*& pStart, FX_DWORD& dwSize, int& type) -{ - pStart = NULL; - dwSize = 0; - type = PDFWORD_EOF; - uint8_t ch; - char chartype; +void CPDF_SimpleParser::ParseWord(const uint8_t*& pStart, + FX_DWORD& dwSize, + int& type) { + pStart = NULL; + dwSize = 0; + type = PDFWORD_EOF; + uint8_t ch; + char chartype; + while (1) { + if (m_dwSize <= m_dwCurPos) { + return; + } + ch = m_pData[m_dwCurPos++]; + chartype = PDF_CharType[ch]; + while (chartype == 'W') { + if (m_dwSize <= m_dwCurPos) { + return; + } + ch = m_pData[m_dwCurPos++]; + chartype = PDF_CharType[ch]; + } + if (ch != '%') { + break; + } while (1) { + if (m_dwSize <= m_dwCurPos) { + return; + } + ch = m_pData[m_dwCurPos++]; + if (ch == '\r' || ch == '\n') { + break; + } + } + chartype = PDF_CharType[ch]; + } + FX_DWORD start_pos = m_dwCurPos - 1; + pStart = m_pData + start_pos; + if (chartype == 'D') { + if (ch == '/') { + while (1) { if (m_dwSize <= m_dwCurPos) { - return; + return; } ch = m_pData[m_dwCurPos++]; chartype = PDF_CharType[ch]; - while (chartype == 'W') { - if (m_dwSize <= m_dwCurPos) { - return; - } - ch = m_pData[m_dwCurPos++]; - chartype = PDF_CharType[ch]; - } - if (ch != '%') { - break; + if (chartype != 'R' && chartype != 'N') { + m_dwCurPos--; + dwSize = m_dwCurPos - start_pos; + type = PDFWORD_NAME; + return; } - while (1) { - if (m_dwSize <= m_dwCurPos) { - return; - } - ch = m_pData[m_dwCurPos++]; - if (ch == '\r' || ch == '\n') { - break; - } + } + } else { + type = PDFWORD_DELIMITER; + dwSize = 1; + if (ch == '<') { + if (m_dwSize <= m_dwCurPos) { + return; } - chartype = PDF_CharType[ch]; - } - FX_DWORD start_pos = m_dwCurPos - 1; - pStart = m_pData + start_pos; - if (chartype == 'D') { - if (ch == '/') { - while (1) { - if (m_dwSize <= m_dwCurPos) { - return; - } - ch = m_pData[m_dwCurPos++]; - chartype = PDF_CharType[ch]; - if (chartype != 'R' && chartype != 'N') { - m_dwCurPos --; - dwSize = m_dwCurPos - start_pos; - type = PDFWORD_NAME; - return; - } - } + ch = m_pData[m_dwCurPos++]; + if (ch == '<') { + dwSize = 2; } else { - type = PDFWORD_DELIMITER; - dwSize = 1; - if (ch == '<') { - if (m_dwSize <= m_dwCurPos) { - return; - } - ch = m_pData[m_dwCurPos++]; - if (ch == '<') { - dwSize = 2; - } else { - m_dwCurPos --; - } - } else if (ch == '>') { - if (m_dwSize <= m_dwCurPos) { - return; - } - ch = m_pData[m_dwCurPos++]; - if (ch == '>') { - dwSize = 2; - } else { - m_dwCurPos --; - } - } - } - return; - } - type = PDFWORD_NUMBER; - dwSize = 1; - while (1) { - if (chartype != 'N') { - type = PDFWORD_TEXT; + m_dwCurPos--; } + } else if (ch == '>') { if (m_dwSize <= m_dwCurPos) { - return; + return; } ch = m_pData[m_dwCurPos++]; - chartype = PDF_CharType[ch]; - if (chartype == 'D' || chartype == 'W') { - m_dwCurPos --; - break; + if (ch == '>') { + dwSize = 2; + } else { + m_dwCurPos--; } - dwSize ++; + } } -} -CFX_ByteStringC CPDF_SimpleParser::GetWord() -{ - const uint8_t* pStart; - FX_DWORD dwSize; - int type; - ParseWord(pStart, dwSize, type); - if (dwSize == 1 && pStart[0] == '<') { - while (m_dwCurPos < m_dwSize && m_pData[m_dwCurPos] != '>') { - m_dwCurPos ++; - } - if (m_dwCurPos < m_dwSize) { - m_dwCurPos ++; - } - return CFX_ByteStringC(pStart, (FX_STRSIZE)(m_dwCurPos - (pStart - m_pData))); - } - if (dwSize == 1 && pStart[0] == '(') { - int level = 1; - while (m_dwCurPos < m_dwSize) { - if (m_pData[m_dwCurPos] == ')') { - level --; - if (level == 0) { - break; - } - } - if (m_pData[m_dwCurPos] == '\\') { - if (m_dwSize <= m_dwCurPos) { - break; - } - m_dwCurPos ++; - } else if (m_pData[m_dwCurPos] == '(') { - level ++; - } - if (m_dwSize <= m_dwCurPos) { - break; - } - m_dwCurPos ++; - } - if (m_dwCurPos < m_dwSize) { - m_dwCurPos ++; - } - return CFX_ByteStringC(pStart, (FX_STRSIZE)(m_dwCurPos - (pStart - m_pData))); + return; + } + type = PDFWORD_NUMBER; + dwSize = 1; + while (1) { + if (chartype != 'N') { + type = PDFWORD_TEXT; } - return CFX_ByteStringC(pStart, dwSize); -} -FX_BOOL CPDF_SimpleParser::SearchToken(const CFX_ByteStringC& token) -{ - int token_len = token.GetLength(); - while (m_dwCurPos < m_dwSize - token_len) { - if (FXSYS_memcmp(m_pData + m_dwCurPos, token.GetPtr(), token_len) == 0) { - break; - } - m_dwCurPos ++; + if (m_dwSize <= m_dwCurPos) { + return; } - if (m_dwCurPos == m_dwSize - token_len) { - return FALSE; + ch = m_pData[m_dwCurPos++]; + chartype = PDF_CharType[ch]; + if (chartype == 'D' || chartype == 'W') { + m_dwCurPos--; + break; } - m_dwCurPos += token_len; - return TRUE; + dwSize++; + } } -FX_BOOL CPDF_SimpleParser::SkipWord(const CFX_ByteStringC& token) -{ - while (1) { - CFX_ByteStringC word = GetWord(); - if (word.IsEmpty()) { - return FALSE; +CFX_ByteStringC CPDF_SimpleParser::GetWord() { + const uint8_t* pStart; + FX_DWORD dwSize; + int type; + ParseWord(pStart, dwSize, type); + if (dwSize == 1 && pStart[0] == '<') { + while (m_dwCurPos < m_dwSize && m_pData[m_dwCurPos] != '>') { + m_dwCurPos++; + } + if (m_dwCurPos < m_dwSize) { + m_dwCurPos++; + } + return CFX_ByteStringC(pStart, + (FX_STRSIZE)(m_dwCurPos - (pStart - m_pData))); + } + if (dwSize == 1 && pStart[0] == '(') { + int level = 1; + while (m_dwCurPos < m_dwSize) { + if (m_pData[m_dwCurPos] == ')') { + level--; + if (level == 0) { + break; } - if (word == token) { - return TRUE; + } + if (m_pData[m_dwCurPos] == '\\') { + if (m_dwSize <= m_dwCurPos) { + break; } + m_dwCurPos++; + } else if (m_pData[m_dwCurPos] == '(') { + level++; + } + if (m_dwSize <= m_dwCurPos) { + break; + } + m_dwCurPos++; + } + if (m_dwCurPos < m_dwSize) { + m_dwCurPos++; + } + return CFX_ByteStringC(pStart, + (FX_STRSIZE)(m_dwCurPos - (pStart - m_pData))); + } + return CFX_ByteStringC(pStart, dwSize); +} +FX_BOOL CPDF_SimpleParser::SearchToken(const CFX_ByteStringC& token) { + int token_len = token.GetLength(); + while (m_dwCurPos < m_dwSize - token_len) { + if (FXSYS_memcmp(m_pData + m_dwCurPos, token.GetPtr(), token_len) == 0) { + break; } + m_dwCurPos++; + } + if (m_dwCurPos == m_dwSize - token_len) { return FALSE; + } + m_dwCurPos += token_len; + return TRUE; } -FX_BOOL CPDF_SimpleParser::FindTagPair(const CFX_ByteStringC& start_token, const CFX_ByteStringC& end_token, - FX_DWORD& start_pos, FX_DWORD& end_pos) -{ - if (!start_token.IsEmpty()) { - if (!SkipWord(start_token)) { - return FALSE; - } - start_pos = m_dwCurPos; +FX_BOOL CPDF_SimpleParser::SkipWord(const CFX_ByteStringC& token) { + while (1) { + CFX_ByteStringC word = GetWord(); + if (word.IsEmpty()) { + return FALSE; } - while (1) { - end_pos = m_dwCurPos; - CFX_ByteStringC word = GetWord(); - if (word.IsEmpty()) { - return FALSE; - } - if (word == end_token) { - return TRUE; - } + if (word == token) { + return TRUE; } - return FALSE; + } + return FALSE; } -FX_BOOL CPDF_SimpleParser::FindTagParam(const CFX_ByteStringC& token, int nParams) -{ - nParams ++; - FX_DWORD* pBuf = FX_Alloc(FX_DWORD, nParams); - int buf_index = 0; - int buf_count = 0; - while (1) { - pBuf[buf_index++] = m_dwCurPos; - if (buf_index == nParams) { - buf_index = 0; - } - buf_count ++; - if (buf_count > nParams) { - buf_count = nParams; - } - CFX_ByteStringC word = GetWord(); - if (word.IsEmpty()) { - FX_Free(pBuf); - return FALSE; - } - if (word == token) { - if (buf_count < nParams) { - continue; - } - m_dwCurPos = pBuf[buf_index]; - FX_Free(pBuf); - return TRUE; - } +FX_BOOL CPDF_SimpleParser::FindTagPair(const CFX_ByteStringC& start_token, + const CFX_ByteStringC& end_token, + FX_DWORD& start_pos, + FX_DWORD& end_pos) { + if (!start_token.IsEmpty()) { + if (!SkipWord(start_token)) { + return FALSE; } - return FALSE; + start_pos = m_dwCurPos; + } + while (1) { + end_pos = m_dwCurPos; + CFX_ByteStringC word = GetWord(); + if (word.IsEmpty()) { + return FALSE; + } + if (word == end_token) { + return TRUE; + } + } + return FALSE; } -static int _hex2dec(char ch) -{ - if (ch >= '0' && ch <= '9') { - return ch - '0'; +FX_BOOL CPDF_SimpleParser::FindTagParam(const CFX_ByteStringC& token, + int nParams) { + nParams++; + FX_DWORD* pBuf = FX_Alloc(FX_DWORD, nParams); + int buf_index = 0; + int buf_count = 0; + while (1) { + pBuf[buf_index++] = m_dwCurPos; + if (buf_index == nParams) { + buf_index = 0; } - if (ch >= 'a' && ch <= 'f') { - return ch - 'a' + 10; + buf_count++; + if (buf_count > nParams) { + buf_count = nParams; } - if (ch >= 'A' && ch <= 'F') { - return ch - 'A' + 10; + CFX_ByteStringC word = GetWord(); + if (word.IsEmpty()) { + FX_Free(pBuf); + return FALSE; } - return 0; + if (word == token) { + if (buf_count < nParams) { + continue; + } + m_dwCurPos = pBuf[buf_index]; + FX_Free(pBuf); + return TRUE; + } + } + return FALSE; } -CFX_ByteString PDF_NameDecode(const CFX_ByteStringC& bstr) -{ - int size = bstr.GetLength(); - const FX_CHAR* pSrc = bstr.GetCStr(); - if (FXSYS_memchr(pSrc, '#', size) == NULL) { - return bstr; - } - CFX_ByteString result; - FX_CHAR* pDestStart = result.GetBuffer(size); - FX_CHAR* pDest = pDestStart; - for (int i = 0; i < size; i ++) { - if (pSrc[i] == '#' && i < size - 2) { - *pDest ++ = _hex2dec(pSrc[i + 1]) * 16 + _hex2dec(pSrc[i + 2]); - i += 2; - } else { - *pDest ++ = pSrc[i]; - } +static int _hex2dec(char ch) { + if (ch >= '0' && ch <= '9') { + return ch - '0'; + } + if (ch >= 'a' && ch <= 'f') { + return ch - 'a' + 10; + } + if (ch >= 'A' && ch <= 'F') { + return ch - 'A' + 10; + } + return 0; +} +CFX_ByteString PDF_NameDecode(const CFX_ByteStringC& bstr) { + int size = bstr.GetLength(); + const FX_CHAR* pSrc = bstr.GetCStr(); + if (FXSYS_memchr(pSrc, '#', size) == NULL) { + return bstr; + } + CFX_ByteString result; + FX_CHAR* pDestStart = result.GetBuffer(size); + FX_CHAR* pDest = pDestStart; + for (int i = 0; i < size; i++) { + if (pSrc[i] == '#' && i < size - 2) { + *pDest++ = _hex2dec(pSrc[i + 1]) * 16 + _hex2dec(pSrc[i + 2]); + i += 2; + } else { + *pDest++ = pSrc[i]; } - result.ReleaseBuffer((FX_STRSIZE)(pDest - pDestStart)); - return result; + } + result.ReleaseBuffer((FX_STRSIZE)(pDest - pDestStart)); + return result; } -CFX_ByteString PDF_NameDecode(const CFX_ByteString& orig) -{ - if (FXSYS_memchr(orig.c_str(), '#', orig.GetLength()) == NULL) { - return orig; +CFX_ByteString PDF_NameDecode(const CFX_ByteString& orig) { + if (FXSYS_memchr(orig.c_str(), '#', orig.GetLength()) == NULL) { + return orig; + } + return PDF_NameDecode(CFX_ByteStringC(orig)); +} +CFX_ByteString PDF_NameEncode(const CFX_ByteString& orig) { + uint8_t* src_buf = (uint8_t*)orig.c_str(); + int src_len = orig.GetLength(); + int dest_len = 0; + int i; + for (i = 0; i < src_len; i++) { + uint8_t ch = src_buf[i]; + if (ch >= 0x80 || PDF_CharType[ch] == 'W' || ch == '#' || + PDF_CharType[ch] == 'D') { + dest_len += 3; + } else { + dest_len++; + } + } + if (dest_len == src_len) { + return orig; + } + CFX_ByteString res; + FX_CHAR* dest_buf = res.GetBuffer(dest_len); + dest_len = 0; + for (i = 0; i < src_len; i++) { + uint8_t ch = src_buf[i]; + if (ch >= 0x80 || PDF_CharType[ch] == 'W' || ch == '#' || + PDF_CharType[ch] == 'D') { + dest_buf[dest_len++] = '#'; + dest_buf[dest_len++] = "0123456789ABCDEF"[ch / 16]; + dest_buf[dest_len++] = "0123456789ABCDEF"[ch % 16]; + } else { + dest_buf[dest_len++] = ch; } - return PDF_NameDecode(CFX_ByteStringC(orig)); + } + dest_buf[dest_len] = 0; + res.ReleaseBuffer(); + return res; } -CFX_ByteString PDF_NameEncode(const CFX_ByteString& orig) -{ - uint8_t* src_buf = (uint8_t*)orig.c_str(); - int src_len = orig.GetLength(); - int dest_len = 0; - int i; - for (i = 0; i < src_len; i ++) { - uint8_t ch = src_buf[i]; - if (ch >= 0x80 || PDF_CharType[ch] == 'W' || ch == '#' || - PDF_CharType[ch] == 'D') { - dest_len += 3; +CFX_ByteTextBuf& operator<<(CFX_ByteTextBuf& buf, const CPDF_Object* pObj) { + if (pObj == NULL) { + buf << FX_BSTRC(" null"); + return buf; + } + switch (pObj->GetType()) { + case PDFOBJ_NULL: + buf << FX_BSTRC(" null"); + break; + case PDFOBJ_BOOLEAN: + case PDFOBJ_NUMBER: + buf << " " << pObj->GetString(); + break; + case PDFOBJ_STRING: { + CFX_ByteString str = pObj->GetString(); + FX_BOOL bHex = ((CPDF_String*)pObj)->IsHex(); + buf << PDF_EncodeString(str, bHex); + break; + } + case PDFOBJ_NAME: { + CFX_ByteString str = pObj->GetString(); + buf << FX_BSTRC("/") << PDF_NameEncode(str); + break; + } + case PDFOBJ_REFERENCE: { + CPDF_Reference* p = (CPDF_Reference*)pObj; + buf << " " << p->GetRefObjNum() << FX_BSTRC(" 0 R "); + break; + } + case PDFOBJ_ARRAY: { + CPDF_Array* p = (CPDF_Array*)pObj; + buf << FX_BSTRC("["); + for (FX_DWORD i = 0; i < p->GetCount(); i++) { + CPDF_Object* pElement = p->GetElement(i); + if (pElement->GetObjNum()) { + buf << " " << pElement->GetObjNum() << FX_BSTRC(" 0 R"); } else { - dest_len ++; + buf << pElement; } + } + buf << FX_BSTRC("]"); + break; } - if (dest_len == src_len) { - return orig; - } - CFX_ByteString res; - FX_CHAR* dest_buf = res.GetBuffer(dest_len); - dest_len = 0; - for (i = 0; i < src_len; i ++) { - uint8_t ch = src_buf[i]; - if (ch >= 0x80 || PDF_CharType[ch] == 'W' || ch == '#' || - PDF_CharType[ch] == 'D') { - dest_buf[dest_len++] = '#'; - dest_buf[dest_len++] = "0123456789ABCDEF"[ch / 16]; - dest_buf[dest_len++] = "0123456789ABCDEF"[ch % 16]; + case PDFOBJ_DICTIONARY: { + CPDF_Dictionary* p = (CPDF_Dictionary*)pObj; + buf << FX_BSTRC("<<"); + FX_POSITION pos = p->GetStartPos(); + while (pos) { + CFX_ByteString key; + CPDF_Object* pValue = p->GetNextElement(pos, key); + buf << FX_BSTRC("/") << PDF_NameEncode(key); + if (pValue->GetObjNum()) { + buf << " " << pValue->GetObjNum() << FX_BSTRC(" 0 R "); } else { - dest_buf[dest_len++] = ch; + buf << pValue; } + } + buf << FX_BSTRC(">>"); + break; } - dest_buf[dest_len] = 0; - res.ReleaseBuffer(); - return res; -} -CFX_ByteTextBuf& operator << (CFX_ByteTextBuf& buf, const CPDF_Object* pObj) -{ - if (pObj == NULL) { - buf << FX_BSTRC(" null"); - return buf; - } - switch (pObj->GetType()) { - case PDFOBJ_NULL: - buf << FX_BSTRC(" null"); - break; - case PDFOBJ_BOOLEAN: - case PDFOBJ_NUMBER: - buf << " " << pObj->GetString(); - break; - case PDFOBJ_STRING: { - CFX_ByteString str = pObj->GetString(); - FX_BOOL bHex = ((CPDF_String*)pObj)->IsHex(); - buf << PDF_EncodeString(str, bHex); - break; - } - case PDFOBJ_NAME: { - CFX_ByteString str = pObj->GetString(); - buf << FX_BSTRC("/") << PDF_NameEncode(str); - break; - } - case PDFOBJ_REFERENCE: { - CPDF_Reference* p = (CPDF_Reference*)pObj; - buf << " " << p->GetRefObjNum() << FX_BSTRC(" 0 R "); - break; - } - case PDFOBJ_ARRAY: { - CPDF_Array* p = (CPDF_Array*)pObj; - buf << FX_BSTRC("["); - for (FX_DWORD i = 0; i < p->GetCount(); i ++) { - CPDF_Object* pElement = p->GetElement(i); - if (pElement->GetObjNum()) { - buf << " " << pElement->GetObjNum() << FX_BSTRC(" 0 R"); - } else { - buf << pElement; - } - } - buf << FX_BSTRC("]"); - break; - } - case PDFOBJ_DICTIONARY: { - CPDF_Dictionary* p = (CPDF_Dictionary*)pObj; - buf << FX_BSTRC("<<"); - FX_POSITION pos = p->GetStartPos(); - while (pos) { - CFX_ByteString key; - CPDF_Object* pValue = p->GetNextElement(pos, key); - buf << FX_BSTRC("/") << PDF_NameEncode(key); - if (pValue->GetObjNum()) { - buf << " " << pValue->GetObjNum() << FX_BSTRC(" 0 R "); - } else { - buf << pValue; - } - } - buf << FX_BSTRC(">>"); - break; - } - case PDFOBJ_STREAM: { - CPDF_Stream* p = (CPDF_Stream*)pObj; - buf << p->GetDict() << FX_BSTRC("stream\r\n"); - CPDF_StreamAcc acc; - acc.LoadAllData(p, TRUE); - buf.AppendBlock(acc.GetData(), acc.GetSize()); - buf << FX_BSTRC("\r\nendstream"); - break; - } - default: - ASSERT(FALSE); - break; + case PDFOBJ_STREAM: { + CPDF_Stream* p = (CPDF_Stream*)pObj; + buf << p->GetDict() << FX_BSTRC("stream\r\n"); + CPDF_StreamAcc acc; + acc.LoadAllData(p, TRUE); + buf.AppendBlock(acc.GetData(), acc.GetSize()); + buf << FX_BSTRC("\r\nendstream"); + break; } - return buf; + default: + ASSERT(FALSE); + break; + } + return buf; } -FX_FLOAT PDF_ClipFloat(FX_FLOAT f) -{ - if (f < 0) { - return 0; - } - if (f > 1.0f) { - return 1.0f; - } - return f; +FX_FLOAT PDF_ClipFloat(FX_FLOAT f) { + if (f < 0) { + return 0; + } + if (f > 1.0f) { + return 1.0f; + } + return f; } -static CPDF_Object* SearchNumberNode(CPDF_Dictionary* pNode, int num) -{ - CPDF_Array* pLimits = pNode->GetArray("Limits"); - if (pLimits && (num < pLimits->GetInteger(0) || num > pLimits->GetInteger(1))) { - return NULL; - } - CPDF_Array* pNumbers = pNode->GetArray("Nums"); - if (pNumbers) { - FX_DWORD dwCount = pNumbers->GetCount() / 2; - for (FX_DWORD i = 0; i < dwCount; i ++) { - int index = pNumbers->GetInteger(i * 2); - if (num == index) { - return pNumbers->GetElementValue(i * 2 + 1); - } - if (index > num) { - break; - } - } - return NULL; +static CPDF_Object* SearchNumberNode(CPDF_Dictionary* pNode, int num) { + CPDF_Array* pLimits = pNode->GetArray("Limits"); + if (pLimits && + (num < pLimits->GetInteger(0) || num > pLimits->GetInteger(1))) { + return NULL; + } + CPDF_Array* pNumbers = pNode->GetArray("Nums"); + if (pNumbers) { + FX_DWORD dwCount = pNumbers->GetCount() / 2; + for (FX_DWORD i = 0; i < dwCount; i++) { + int index = pNumbers->GetInteger(i * 2); + if (num == index) { + return pNumbers->GetElementValue(i * 2 + 1); + } + if (index > num) { + break; + } } - CPDF_Array* pKids = pNode->GetArray("Kids"); - if (pKids == NULL) { - return NULL; + return NULL; + } + CPDF_Array* pKids = pNode->GetArray("Kids"); + if (pKids == NULL) { + return NULL; + } + for (FX_DWORD i = 0; i < pKids->GetCount(); i++) { + CPDF_Dictionary* pKid = pKids->GetDict(i); + if (pKid == NULL) { + continue; } - for (FX_DWORD i = 0; i < pKids->GetCount(); i ++) { - CPDF_Dictionary* pKid = pKids->GetDict(i); - if (pKid == NULL) { - continue; - } - CPDF_Object* pFound = SearchNumberNode(pKid, num); - if (pFound) { - return pFound; - } + CPDF_Object* pFound = SearchNumberNode(pKid, num); + if (pFound) { + return pFound; } - return NULL; + } + return NULL; } -CPDF_Object* CPDF_NumberTree::LookupValue(int num) -{ - return SearchNumberNode(m_pRoot, num); +CPDF_Object* CPDF_NumberTree::LookupValue(int num) { + return SearchNumberNode(m_pRoot, num); } |