Fix infinite recursion in CPDF_Parser::ParseIndirectObjectAt().
[pdfium.git] / core / include / fpdfapi / fpdf_parser.h
1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4  
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #ifndef _FPDF_PARSER_
8 #define _FPDF_PARSER_
9 #ifndef _FX_BASIC_H_
10 #include "../fxcrt/fx_ext.h"
11 #endif
12 #ifndef _FPDF_OBJECTS_
13 #include "fpdf_objects.h"
14 #endif
15 class CPDF_Document;
16 class IPDF_DocParser;
17 class CPDF_Parser;
18 class CPDF_SecurityHandler;
19 class CPDF_StandardSecurityHandler;
20 class CPDF_CryptoHandler;
21 class CPDF_Object;
22 class IFX_FileRead;
23 class CFDF_Document;
24 class CFDF_Parser;
25 class CFX_Font;
26 class CFX_AffineMatrix;
27 class CFX_FloatRect;
28 class CPDF_Point;
29 class CPDF_DocPageData;
30 class CPDF_DocRenderData;
31 class CPDF_ModuleMgr;
32 class CFX_DIBSource;
33 class CPDF_Font;
34 class CPDF_Image;
35 class CPDF_ColorSpace;
36 class CPDF_Pattern;
37 class CPDF_FontEncoding;
38 class CPDF_IccProfile;
39 class CFX_PrivateData;
40 #define FPDFPERM_PRINT                  0x0004
41 #define FPDFPERM_MODIFY                 0x0008
42 #define FPDFPERM_EXTRACT                0x0010
43 #define FPDFPERM_ANNOT_FORM             0x0020
44 #define FPDFPERM_FILL_FORM              0x0100
45 #define FPDFPERM_EXTRACT_ACCESS 0x0200
46 #define FPDFPERM_ASSEMBLE               0x0400
47 #define FPDFPERM_PRINT_HIGH             0x0800
48 #define FPDF_PAGE_MAX_NUM               0xFFFFF
49 class IPDF_EnumPageHandler
50 {
51 public:
52     virtual ~IPDF_EnumPageHandler() { }
53     virtual FX_BOOL EnumPage(CPDF_Dictionary* pPageDict) = 0;
54 };
55 class CPDF_Document : public CFX_PrivateData, public CPDF_IndirectObjects
56 {
57 public:
58
59     CPDF_Document(IPDF_DocParser* pParser);
60
61     CPDF_Document();
62
63     ~CPDF_Document();
64
65     IPDF_DocParser*                     GetParser() const
66     {
67         return m_pParser;
68     }
69
70     CPDF_Dictionary*            GetRoot() const
71     {
72         return m_pRootDict;
73     }
74
75     CPDF_Dictionary*            GetInfo() const
76     {
77         return m_pInfoDict;
78     }
79
80     void                                        GetID(CFX_ByteString& id1, CFX_ByteString& id2) const
81     {
82         id1 = m_ID1;
83         id2 = m_ID2;
84     }
85
86     int                                         GetPageCount() const;
87
88     CPDF_Dictionary*            GetPage(int iPage);
89
90     int                                         GetPageIndex(FX_DWORD objnum);
91
92     void                                        EnumPages(IPDF_EnumPageHandler* pHandler);
93
94     FX_DWORD                            GetUserPermissions(FX_BOOL bCheckRevision = FALSE) const;
95
96     FX_BOOL                                     IsOwner() const;
97
98
99
100     CPDF_DocPageData*           GetPageData()
101     {
102         return GetValidatePageData();
103     }
104
105     void                                        ClearPageData();
106
107     void                                        RemoveColorSpaceFromPageData(CPDF_Object* pObject);
108
109
110     CPDF_DocRenderData*         GetRenderData()
111     {
112         return GetValidateRenderData();
113     }
114
115     void                                        ClearRenderData();
116
117     void                                        ClearRenderFont();
118
119
120     FX_BOOL                                     IsFormStream(FX_DWORD objnum, FX_BOOL& bForm) const;
121
122
123
124
125     CPDF_Font*                          LoadFont(CPDF_Dictionary* pFontDict);
126
127     CPDF_Font*                          FindFont(CPDF_Dictionary* pFontDict);
128
129     CPDF_ColorSpace*            LoadColorSpace(CPDF_Object* pCSObj, CPDF_Dictionary* pResources = NULL);
130
131     CPDF_Pattern*                       LoadPattern(CPDF_Object* pObj, FX_BOOL bShading, const CFX_AffineMatrix* matrix = NULL);
132
133     CPDF_Image*                         LoadImageF(CPDF_Object* pObj);
134
135     CPDF_StreamAcc*                     LoadFontFile(CPDF_Stream* pStream);
136
137     CPDF_IccProfile*            LoadIccProfile(CPDF_Stream* pStream);
138
139 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
140
141     CPDF_Font*                          AddWindowsFont(LOGFONTA* pLogFont, FX_BOOL bVert, FX_BOOL bTranslateName = FALSE);
142     CPDF_Font*                          AddWindowsFont(LOGFONTW* pLogFont, FX_BOOL bVert, FX_BOOL bTranslateName = FALSE);
143 #endif
144 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
145     CPDF_Font*              AddMacFont(CTFontRef pFont, FX_BOOL bVert, FX_BOOL bTranslateName = FALSE);
146 #endif
147
148     CPDF_Font*                          AddStandardFont(const FX_CHAR* font, CPDF_FontEncoding* pEncoding);
149
150
151     CPDF_Font*                          AddFont(CFX_Font* pFont, int charset, FX_BOOL bVert);
152
153     void                                        CreateNewDoc();
154
155     CPDF_Dictionary*            CreateNewPage(int iPage);
156
157     void                                        DeletePage(int iPage);
158
159     void                                        LoadDoc();
160     void                                        LoadAsynDoc(CPDF_Dictionary *pLinearized);
161     void                                        LoadPages();
162 protected:
163
164     CPDF_Dictionary*            m_pRootDict;
165
166     CPDF_Dictionary*            m_pInfoDict;
167
168     CFX_ByteString                      m_ID1;
169
170     CFX_ByteString                      m_ID2;
171
172
173     FX_BOOL                                     m_bLinearized;
174
175     FX_DWORD                            m_dwFirstPageNo;
176
177     FX_DWORD                            m_dwFirstPageObjNum;
178
179     CFX_DWordArray                      m_PageList;
180
181     int                                         _GetPageCount() const;
182     CPDF_Dictionary*            _FindPDFPage(CPDF_Dictionary* pPages, int iPage, int nPagesToGo, int level);
183     int                                         _FindPageIndex(CPDF_Dictionary* pNode, FX_DWORD& skip_count, FX_DWORD objnum, int& index, int level = 0);
184     FX_BOOL                                     IsContentUsedElsewhere(FX_DWORD objnum, CPDF_Dictionary* pPageDict);
185     FX_BOOL                                     CheckOCGVisible(CPDF_Dictionary* pOCG, FX_BOOL bPrinting);
186     CPDF_DocPageData*           GetValidatePageData();
187     CPDF_DocRenderData*         GetValidateRenderData();
188     friend class                        CPDF_Creator;
189     friend class                        CPDF_Parser;
190     friend class                        CPDF_DataAvail;
191     friend class                        CPDF_OCContext;
192
193
194
195     CPDF_DocPageData*           m_pDocPage;
196
197     CPDF_DocRenderData*         m_pDocRender;
198
199 };
200
201 #define PDFWORD_EOF                     0
202 #define PDFWORD_NUMBER          1
203 #define PDFWORD_TEXT            2
204 #define PDFWORD_DELIMITER       3
205 #define PDFWORD_NAME            4
206 class CPDF_SimpleParser : public CFX_Object
207 {
208 public:
209
210     CPDF_SimpleParser(FX_LPCBYTE pData, FX_DWORD dwSize);
211
212     CPDF_SimpleParser(FX_BSTR str);
213
214     CFX_ByteStringC             GetWord();
215
216     FX_BOOL                             SearchToken(FX_BSTR token);
217
218     FX_BOOL                             SkipWord(FX_BSTR token);
219
220     FX_BOOL                             FindTagPair(FX_BSTR start_token, FX_BSTR end_token,
221                                     FX_DWORD& start_pos, FX_DWORD& end_pos);
222
223     FX_BOOL                             FindTagParam(FX_BSTR token, int nParams);
224
225     FX_DWORD                    GetPos()
226     {
227         return m_dwCurPos;
228     }
229
230     void                                SetPos(FX_DWORD pos)
231     {
232         ASSERT(pos <= m_dwSize);
233         m_dwCurPos = pos;
234     }
235 private:
236
237     void                                ParseWord(FX_LPCBYTE& pStart, FX_DWORD& dwSize, int& type);
238
239     FX_LPCBYTE                  m_pData;
240
241     FX_DWORD                    m_dwSize;
242
243     FX_DWORD                    m_dwCurPos;
244 };
245 class CPDF_SyntaxParser : public CFX_Object
246 {
247 public:
248
249     CPDF_SyntaxParser();
250     virtual ~CPDF_SyntaxParser();
251
252     void                                InitParser(IFX_FileRead* pFileAccess, FX_DWORD HeaderOffset);
253
254     FX_FILESIZE                 SavePos()
255     {
256         return m_Pos;
257     }
258
259     void                                RestorePos(FX_FILESIZE pos)
260     {
261         m_Pos = pos;
262     }
263
264     CPDF_Object*                GetObject(CPDF_IndirectObjects* pObjList, FX_DWORD objnum, FX_DWORD gennum, struct PARSE_CONTEXT* pContext = NULL, FX_BOOL bDecrypt = TRUE);
265
266
267     CPDF_Object*                GetObjectByStrict(CPDF_IndirectObjects* pObjList, FX_DWORD objnum, FX_DWORD gennum, struct PARSE_CONTEXT* pContext = NULL);
268
269     int                                 GetDirectNum();
270
271     CFX_ByteString              GetString(FX_DWORD objnum, FX_DWORD gennum);
272
273     CFX_ByteString              GetName();
274
275     CFX_ByteString              GetKeyword();
276
277     void                                GetBinary(FX_BYTE* buffer, FX_DWORD size);
278
279     void                                ToNextLine();
280
281     void                                ToNextWord();
282
283     FX_BOOL                             SearchWord(FX_BSTR word, FX_BOOL bWholeWord, FX_BOOL bForward, FX_FILESIZE limit);
284
285     int                                 SearchMultiWord(FX_BSTR words, FX_BOOL bWholeWord, FX_FILESIZE limit);
286
287     FX_FILESIZE                 FindTag(FX_BSTR tag, FX_FILESIZE limit);
288
289     void                                SetEncrypt(CPDF_CryptoHandler* pCryptoHandler)
290     {
291         m_pCryptoHandler = pCryptoHandler;
292     }
293
294     FX_BOOL                             IsEncrypted()
295     {
296         return m_pCryptoHandler != NULL;
297     }
298
299     FX_BOOL                             GetCharAt(FX_FILESIZE pos, FX_BYTE& ch);
300
301     FX_BOOL                             ReadBlock(FX_BYTE* pBuf, FX_DWORD size);
302
303     CFX_ByteString              GetNextWord(FX_BOOL& bIsNumber);
304 protected:
305     static const int kParserMaxRecursionDepth = 64;
306     static int s_CurrentRecursionDepth;
307
308     virtual FX_BOOL                             GetNextChar(FX_BYTE& ch);
309
310     FX_BOOL                             GetCharAtBackward(FX_FILESIZE pos, FX_BYTE& ch);
311
312     void                                GetNextWord();
313
314     FX_BOOL                             IsWholeWord(FX_FILESIZE startpos, FX_FILESIZE limit, FX_LPCBYTE tag, FX_DWORD taglen);
315
316     CFX_ByteString              ReadString();
317
318     CFX_ByteString              ReadHexString();
319
320     CPDF_Stream*                ReadStream(CPDF_Dictionary* pDict, PARSE_CONTEXT* pContext, FX_DWORD objnum, FX_DWORD gennum);
321
322     FX_FILESIZE                 m_Pos;
323
324     FX_BOOL                             m_bFileStream;
325
326     int                                 m_MetadataObjnum;
327
328     IFX_FileRead*               m_pFileAccess;
329
330     FX_DWORD                    m_HeaderOffset;
331
332     FX_FILESIZE                 m_FileLen;
333
334     FX_BYTE*                    m_pFileBuf;
335
336     FX_DWORD                    m_BufSize;
337
338     FX_FILESIZE                 m_BufOffset;
339
340     CPDF_CryptoHandler* m_pCryptoHandler;
341
342     FX_BYTE                             m_WordBuffer[257];
343
344     FX_DWORD                    m_WordSize;
345
346     FX_BOOL                             m_bIsNumber;
347
348     FX_FILESIZE                 m_dwWordPos;
349     friend class                CPDF_Parser;
350     friend class                CPDF_DataAvail;
351 };
352
353 #define PDFPARSE_TYPEONLY       1
354 #define PDFPARSE_NOSTREAM       2
355 struct PARSE_CONTEXT {
356
357     FX_BOOL             m_Flags;
358
359     FX_FILESIZE m_DictStart;
360
361     FX_FILESIZE m_DictEnd;
362
363     FX_FILESIZE m_DataStart;
364
365     FX_FILESIZE m_DataEnd;
366 };
367 class IPDF_DocParser : public CFX_Object
368 {
369 public:
370     virtual ~IPDF_DocParser() { }
371     virtual FX_DWORD    GetRootObjNum() = 0;
372
373     virtual FX_DWORD    GetInfoObjNum() = 0;
374
375     virtual CPDF_Object*        ParseIndirectObject(CPDF_IndirectObjects* pObjList, FX_DWORD objnum, PARSE_CONTEXT* pContext = NULL) = 0;
376
377     virtual FX_DWORD    GetLastObjNum() = 0;
378
379     virtual CPDF_Array* GetIDArray() = 0;
380
381     virtual CPDF_Dictionary*    GetEncryptDict() = 0;
382
383     FX_BOOL                             IsEncrypted()
384     {
385         return GetEncryptDict() != NULL;
386     }
387
388     virtual FX_DWORD    GetPermissions(FX_BOOL bCheckRevision = FALSE) = 0;
389
390     virtual FX_BOOL             IsOwner() = 0;
391
392     virtual FX_BOOL             IsFormStream(FX_DWORD objnum, FX_BOOL& bForm) = 0;
393 };
394
395 #define PDFPARSE_ERROR_SUCCESS          0
396 #define PDFPARSE_ERROR_FILE                     1
397 #define PDFPARSE_ERROR_FORMAT           2
398 #define PDFPARSE_ERROR_PASSWORD         3
399 #define PDFPARSE_ERROR_HANDLER          4
400 #define PDFPARSE_ERROR_CERT                     5
401 class CPDF_Parser FX_FINAL : public IPDF_DocParser
402 {
403 public:
404
405     CPDF_Parser();
406     ~CPDF_Parser() override;
407
408     FX_DWORD                    StartParse(FX_LPCSTR filename, FX_BOOL bReParse = FALSE);
409
410     FX_DWORD                    StartParse(FX_LPCWSTR filename, FX_BOOL bReParse = FALSE);
411
412     FX_DWORD                    StartParse(IFX_FileRead* pFile, FX_BOOL bReParse = FALSE, FX_BOOL bOwnFileRead = TRUE);
413
414     void                                CloseParser(FX_BOOL bReParse = FALSE);
415
416     virtual FX_DWORD    GetPermissions(FX_BOOL bCheckRevision = FALSE) FX_OVERRIDE;
417
418     virtual FX_BOOL             IsOwner() FX_OVERRIDE;
419
420     void                                SetPassword(const FX_CHAR* password)
421     {
422         m_Password = password;
423     }
424
425     CFX_ByteString              GetPassword()
426     {
427         return m_Password;
428     }
429
430     CPDF_SecurityHandler* GetSecurityHandler()
431     {
432         return m_pSecurityHandler;
433     }
434
435     CPDF_CryptoHandler* GetCryptoHandler()
436     {
437         return m_Syntax.m_pCryptoHandler;
438     }
439
440     void                                SetSecurityHandler(CPDF_SecurityHandler* pSecurityHandler, FX_BOOL bForced = FALSE);
441
442     CFX_ByteString              GetRecipient()
443     {
444         return m_bsRecipient;
445     }
446
447     CPDF_Dictionary*    GetTrailer()
448     {
449         return m_pTrailer;
450     }
451
452     FX_FILESIZE                 GetLastXRefOffset()
453     {
454         return m_LastXRefOffset;
455     }
456
457     CPDF_Document*              GetDocument()
458     {
459         return m_pDocument;
460     }
461     CFX_ArrayTemplate<CPDF_Dictionary *> * GetOtherTrailers()
462     {
463         return &m_Trailers;
464     }
465
466     virtual FX_DWORD    GetRootObjNum() FX_OVERRIDE;
467     virtual FX_DWORD    GetInfoObjNum()  FX_OVERRIDE;
468     virtual CPDF_Array* GetIDArray()  FX_OVERRIDE;
469     virtual CPDF_Dictionary*    GetEncryptDict()  FX_OVERRIDE
470     {
471         return m_pEncryptDict;
472     }
473     virtual CPDF_Object*                ParseIndirectObject(CPDF_IndirectObjects* pObjList, FX_DWORD objnum, PARSE_CONTEXT* pContext = NULL)  FX_OVERRIDE;
474     virtual FX_DWORD    GetLastObjNum() FX_OVERRIDE;
475     virtual FX_BOOL             IsFormStream(FX_DWORD objnum, FX_BOOL& bForm)  FX_OVERRIDE;
476
477     FX_FILESIZE                 GetObjectOffset(FX_DWORD objnum);
478
479     FX_FILESIZE                 GetObjectSize(FX_DWORD objnum);
480
481     int                                 GetObjectVersion(FX_DWORD objnum)
482     {
483         return m_ObjVersion[objnum];
484     }
485
486     void                                GetIndirectBinary(FX_DWORD objnum, FX_BYTE*& pBuffer, FX_DWORD& size);
487
488     FX_BOOL                             GetFileStreamOption()
489     {
490         return m_Syntax.m_bFileStream;
491     }
492
493     void                                SetFileStreamOption(FX_BOOL b)
494     {
495         m_Syntax.m_bFileStream = b;
496     }
497
498     IFX_FileRead*               GetFileAccess() const
499     {
500         return m_Syntax.m_pFileAccess;
501     }
502
503     int                                 GetFileVersion() const
504     {
505         return m_FileVersion;
506     }
507
508     FX_BOOL                             IsXRefStream() const
509     {
510         return m_bXRefStream;
511     }
512     CPDF_Object*                ParseIndirectObjectAt(CPDF_IndirectObjects* pObjList, FX_FILESIZE pos, FX_DWORD objnum,
513             struct PARSE_CONTEXT* pContext);
514
515     CPDF_Object*                ParseIndirectObjectAtByStrict(CPDF_IndirectObjects* pObjList, FX_FILESIZE pos, FX_DWORD objnum,
516             struct PARSE_CONTEXT* pContext, FX_FILESIZE *pResultPos);
517
518     FX_DWORD                    StartAsynParse(IFX_FileRead* pFile, FX_BOOL bReParse = FALSE, FX_BOOL bOwnFileRead = TRUE);
519
520     FX_DWORD                    GetFirstPageNo()
521     {
522         return m_dwFirstPageNo;
523     }
524 protected:
525     CPDF_Document*              m_pDocument;
526
527     CPDF_SyntaxParser   m_Syntax;
528     FX_BOOL                             m_bOwnFileRead;
529     CPDF_Object*                ParseDirect(CPDF_Object* pObj);
530
531     FX_BOOL                             LoadAllCrossRefV4(FX_FILESIZE pos);
532
533     FX_BOOL                             LoadAllCrossRefV5(FX_FILESIZE pos);
534
535     FX_BOOL                             LoadCrossRefV4(FX_FILESIZE pos, FX_FILESIZE streampos, FX_BOOL bSkip, FX_BOOL bFirst);
536
537     FX_BOOL                             LoadCrossRefV5(FX_FILESIZE pos, FX_FILESIZE& prev, FX_BOOL bMainXRef);
538
539     CPDF_Dictionary*    LoadTrailerV4();
540
541     FX_BOOL                             RebuildCrossRef();
542
543     FX_DWORD                    SetEncryptHandler();
544
545     void                                ReleaseEncryptHandler();
546
547     FX_BOOL                             LoadLinearizedAllCrossRefV4(FX_FILESIZE pos, FX_DWORD dwObjCount);
548
549     FX_BOOL                             LoadLinearizedCrossRefV4(FX_FILESIZE pos, FX_DWORD dwObjCount);
550
551     FX_BOOL                             LoadLinearizedAllCrossRefV5(FX_FILESIZE pos);
552
553     FX_DWORD                    LoadLinearizedMainXRefTable();
554
555     CFX_MapPtrToPtr             m_ObjectStreamMap;
556
557     CPDF_StreamAcc*             GetObjectStream(FX_DWORD number);
558
559     FX_BOOL                             IsLinearizedFile(IFX_FileRead* pFileAccess, FX_DWORD offset);
560
561
562
563     int                                 m_FileVersion;
564
565     CPDF_Dictionary*    m_pTrailer;
566
567     CPDF_Dictionary*    m_pEncryptDict;
568     void SetEncryptDictionary(CPDF_Dictionary* pDict);
569
570     FX_FILESIZE                 m_LastXRefOffset;
571
572     FX_BOOL                             m_bXRefStream;
573
574
575     CPDF_SecurityHandler*       m_pSecurityHandler;
576
577     FX_BOOL                                     m_bForceUseSecurityHandler;
578
579     CFX_ByteString                      m_bsRecipient;
580
581     CFX_ByteString              m_FilePath;
582
583     CFX_ByteString              m_Password;
584
585     CFX_FileSizeArray   m_CrossRef;
586
587     CFX_ByteArray               m_V5Type;
588
589     CFX_FileSizeArray   m_SortedOffset;
590
591     CFX_WordArray               m_ObjVersion;
592     CFX_ArrayTemplate<CPDF_Dictionary *>        m_Trailers;
593
594     FX_BOOL                             m_bVersionUpdated;
595
596     CPDF_Object*                m_pLinearized;
597
598     FX_DWORD                    m_dwFirstPageNo;
599
600     FX_DWORD                    m_dwXrefStartObjNum;
601     friend class                CPDF_Creator;
602     friend class                CPDF_DataAvail;
603 };
604 #define FXCIPHER_NONE   0
605 #define FXCIPHER_RC4    1
606 #define FXCIPHER_AES    2
607 #define FXCIPHER_AES2   3
608 class CPDF_SecurityHandler : public CFX_Object
609 {
610 public:
611
612     virtual ~CPDF_SecurityHandler() {}
613
614     virtual FX_BOOL             OnInit(CPDF_Parser* pParser, CPDF_Dictionary* pEncryptDict) = 0;
615
616     virtual FX_DWORD    GetPermissions() = 0;
617
618     virtual FX_BOOL             IsOwner() = 0;
619
620     virtual FX_BOOL             GetCryptInfo(int& cipher, FX_LPCBYTE& buffer, int& keylen) = 0;
621
622     virtual FX_BOOL             IsMetadataEncrypted()
623     {
624         return TRUE;
625     }
626
627     virtual CPDF_CryptoHandler* CreateCryptoHandler() = 0;
628
629     virtual CPDF_StandardSecurityHandler* GetStandardHandler()
630     {
631         return NULL;
632     }
633 };
634 #define PDF_ENCRYPT_CONTENT                             0
635 class CPDF_StandardSecurityHandler : public CPDF_SecurityHandler
636 {
637 public:
638     CPDF_StandardSecurityHandler();
639
640     virtual ~CPDF_StandardSecurityHandler();
641     virtual FX_BOOL             OnInit(CPDF_Parser* pParser, CPDF_Dictionary* pEncryptDict);
642     virtual FX_DWORD    GetPermissions();
643     virtual FX_BOOL             IsOwner()
644     {
645         return m_bOwner;
646     }
647     virtual FX_BOOL             GetCryptInfo(int& cipher, FX_LPCBYTE& buffer, int& keylen);
648     virtual FX_BOOL             IsMetadataEncrypted();
649     virtual CPDF_CryptoHandler* CreateCryptoHandler();
650     virtual CPDF_StandardSecurityHandler* GetStandardHandler()
651     {
652         return this;
653     }
654
655     void                                OnCreate(CPDF_Dictionary* pEncryptDict, CPDF_Array* pIdArray,
656                                  FX_LPCBYTE user_pass, FX_DWORD user_size,
657                                  FX_LPCBYTE owner_pass, FX_DWORD owner_size, FX_DWORD type = PDF_ENCRYPT_CONTENT);
658
659     void                                OnCreate(CPDF_Dictionary* pEncryptDict, CPDF_Array* pIdArray,
660                                  FX_LPCBYTE user_pass, FX_DWORD user_size, FX_DWORD type = PDF_ENCRYPT_CONTENT);
661
662     CFX_ByteString              GetUserPassword(FX_LPCBYTE owner_pass, FX_DWORD pass_size);
663     CFX_ByteString              GetUserPassword(FX_LPCBYTE owner_pass, FX_DWORD pass_size, FX_INT32 key_len);
664     int                                 GetVersion()
665     {
666         return m_Version;
667     }
668     int                                 GetRevision()
669     {
670         return m_Revision;
671     }
672
673     int                                 CheckPassword(FX_LPCBYTE password, FX_DWORD pass_size, FX_BOOL bOwner, FX_LPBYTE key);
674     int                                 CheckPassword(FX_LPCBYTE password, FX_DWORD pass_size, FX_BOOL bOwner, FX_LPBYTE key, int key_len);
675 private:
676
677     int                                 m_Version;
678
679     int                                 m_Revision;
680
681     CPDF_Parser*                m_pParser;
682
683     CPDF_Dictionary*    m_pEncryptDict;
684
685     FX_BOOL                             LoadDict(CPDF_Dictionary* pEncryptDict);
686     FX_BOOL                             LoadDict(CPDF_Dictionary* pEncryptDict, FX_DWORD type, int& cipher, int& key_len);
687
688     FX_BOOL                             CheckUserPassword(FX_LPCBYTE password, FX_DWORD pass_size,
689                                           FX_BOOL bIgnoreEncryptMeta, FX_LPBYTE key, FX_INT32 key_len);
690
691     FX_BOOL                             CheckOwnerPassword(FX_LPCBYTE password, FX_DWORD pass_size, FX_LPBYTE key, FX_INT32 key_len);
692     FX_BOOL                             AES256_CheckPassword(FX_LPCBYTE password, FX_DWORD size, FX_BOOL bOwner, FX_LPBYTE key);
693     void                                AES256_SetPassword(CPDF_Dictionary* pEncryptDict, FX_LPCBYTE password, FX_DWORD size, FX_BOOL bOwner, FX_LPCBYTE key);
694     void                                AES256_SetPerms(CPDF_Dictionary* pEncryptDict, FX_DWORD permission, FX_BOOL bEncryptMetadata, FX_LPCBYTE key);
695     void                                OnCreate(CPDF_Dictionary* pEncryptDict, CPDF_Array* pIdArray,
696                                  FX_LPCBYTE user_pass, FX_DWORD user_size,
697                                  FX_LPCBYTE owner_pass, FX_DWORD owner_size, FX_BOOL bDefault, FX_DWORD type);
698     FX_BOOL                             CheckSecurity(FX_INT32 key_len);
699
700     FX_BOOL                             m_bOwner;
701
702     FX_DWORD                    m_Permissions;
703
704     int                                 m_Cipher;
705
706     FX_BYTE                             m_EncryptKey[32];
707
708     int                                 m_KeyLen;
709 };
710 class CPDF_CryptoHandler : public CFX_Object
711 {
712 public:
713
714     virtual ~CPDF_CryptoHandler() {}
715
716     virtual FX_BOOL             Init(CPDF_Dictionary* pEncryptDict, CPDF_SecurityHandler* pSecurityHandler) = 0;
717
718     virtual FX_DWORD    DecryptGetSize(FX_DWORD src_size) = 0;
719
720     virtual FX_LPVOID   DecryptStart(FX_DWORD objnum, FX_DWORD gennum) = 0;
721
722     virtual FX_BOOL             DecryptStream(FX_LPVOID context, FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf) = 0;
723
724     virtual FX_BOOL             DecryptFinish(FX_LPVOID context, CFX_BinaryBuf& dest_buf) = 0;
725
726
727     virtual FX_DWORD    EncryptGetSize(FX_DWORD objnum, FX_DWORD version, FX_LPCBYTE src_buf, FX_DWORD src_size) = 0;
728
729     virtual FX_BOOL             EncryptContent(FX_DWORD objnum, FX_DWORD version, FX_LPCBYTE src_buf, FX_DWORD src_size,
730                                        FX_LPBYTE dest_buf, FX_DWORD& dest_size) = 0;
731
732     void                                Decrypt(FX_DWORD objnum, FX_DWORD version, CFX_ByteString& str);
733 };
734 class CPDF_StandardCryptoHandler : public CPDF_CryptoHandler
735 {
736 public:
737
738     CPDF_StandardCryptoHandler();
739
740     virtual ~CPDF_StandardCryptoHandler();
741
742     FX_BOOL                             Init(int cipher, FX_LPCBYTE key, int keylen);
743     virtual FX_BOOL             Init(CPDF_Dictionary* pEncryptDict, CPDF_SecurityHandler* pSecurityHandler);
744     virtual FX_DWORD    DecryptGetSize(FX_DWORD src_size);
745     virtual FX_LPVOID   DecryptStart(FX_DWORD objnum, FX_DWORD gennum);
746     virtual FX_BOOL             DecryptStream(FX_LPVOID context, FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf);
747     virtual FX_BOOL             DecryptFinish(FX_LPVOID context, CFX_BinaryBuf& dest_buf);
748     virtual FX_DWORD    EncryptGetSize(FX_DWORD objnum, FX_DWORD version, FX_LPCBYTE src_buf, FX_DWORD src_size);
749     virtual FX_BOOL             EncryptContent(FX_DWORD objnum, FX_DWORD version, FX_LPCBYTE src_buf, FX_DWORD src_size,
750                                        FX_LPBYTE dest_buf, FX_DWORD& dest_size);
751 protected:
752
753     virtual void                CryptBlock(FX_BOOL bEncrypt, FX_DWORD objnum, FX_DWORD gennum, FX_LPCBYTE src_buf, FX_DWORD src_size,
754                                    FX_LPBYTE dest_buf, FX_DWORD& dest_size);
755     virtual FX_LPVOID   CryptStart(FX_DWORD objnum, FX_DWORD gennum, FX_BOOL bEncrypt);
756     virtual FX_BOOL             CryptStream(FX_LPVOID context, FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf, FX_BOOL bEncrypt);
757     virtual FX_BOOL             CryptFinish(FX_LPVOID context, CFX_BinaryBuf& dest_buf, FX_BOOL bEncrypt);
758
759     FX_BYTE                             m_EncryptKey[32];
760
761     int                                 m_KeyLen;
762
763     int                                 m_Cipher;
764
765     FX_LPBYTE                   m_pAESContext;
766 };
767 class CPDF_Point : public CFX_Object
768 {
769 public:
770
771     CPDF_Point(FX_FLOAT xx, FX_FLOAT yy)
772     {
773         x = xx;
774         y = yy;
775     }
776
777     FX_FLOAT                    x;
778
779     FX_FLOAT                    y;
780 };
781
782 #define CPDF_Rect               CFX_FloatRect
783 #define CPDF_Matrix             CFX_AffineMatrix
784 CFX_ByteString PDF_NameDecode(FX_BSTR orig);
785 CFX_ByteString PDF_NameDecode(const CFX_ByteString& orig);
786 CFX_ByteString PDF_NameEncode(const CFX_ByteString& orig);
787 CFX_ByteString PDF_EncodeString(const CFX_ByteString& src, FX_BOOL bHex = FALSE);
788 CFX_WideString PDF_DecodeText(const CFX_ByteString& str, CFX_CharMap* pCharMap = NULL);
789 CFX_WideString PDF_DecodeText(FX_LPCBYTE pData, FX_DWORD size, CFX_CharMap* pCharMap = NULL);
790 CFX_ByteString PDF_EncodeText(FX_LPCWSTR pString, int len = -1, CFX_CharMap* pCharMap = NULL);
791 FX_FLOAT PDF_ClipFloat(FX_FLOAT f);
792 class CFDF_Document : public CPDF_IndirectObjects
793 {
794 public:
795
796     static CFDF_Document*       CreateNewDoc();
797
798     static CFDF_Document*       ParseFile(FX_LPCSTR file_path);
799
800     static CFDF_Document*       ParseFile(FX_LPCWSTR file_path);
801
802     static CFDF_Document*       ParseFile(IFX_FileRead *pFile, FX_BOOL bOwnFile = FALSE);
803
804     static CFDF_Document*       ParseMemory(FX_LPCBYTE pData, FX_DWORD size);
805
806     ~CFDF_Document();
807
808     FX_BOOL                                     WriteFile(FX_LPCSTR file_path) const;
809
810     FX_BOOL                                     WriteFile(FX_LPCWSTR file_path) const;
811
812     FX_BOOL                                     WriteFile(IFX_FileWrite *pFile) const;
813
814     FX_BOOL                                     WriteBuf(CFX_ByteTextBuf& buf) const;
815
816     CPDF_Dictionary*            GetRoot() const
817     {
818         return m_pRootDict;
819     }
820
821     CFX_WideString                      GetWin32Path() const;
822 protected:
823
824     CFDF_Document();
825     void        ParseStream(IFX_FileRead *pFile, FX_BOOL bOwnFile);
826     CPDF_Dictionary*            m_pRootDict;
827     IFX_FileRead*                       m_pFile;
828     FX_BOOL                                     m_bOwnFile;
829 };
830
831 CFX_WideString  FPDF_FileSpec_GetWin32Path(const CPDF_Object* pFileSpec);
832 void                    FPDF_FileSpec_SetWin32Path(CPDF_Object* pFileSpec, const CFX_WideString& fullpath);
833
834 void FlateEncode(const FX_BYTE* src_buf, FX_DWORD src_size, FX_LPBYTE& dest_buf, FX_DWORD& dest_size);
835 FX_DWORD FlateDecode(const FX_BYTE* src_buf, FX_DWORD src_size, FX_LPBYTE& dest_buf, FX_DWORD& dest_size);
836 FX_DWORD RunLengthDecode(const FX_BYTE* src_buf, FX_DWORD src_size, FX_LPBYTE& dest_buf, FX_DWORD& dest_size);
837 class CPDF_NumberTree : public CFX_Object
838 {
839 public:
840
841     CPDF_NumberTree(CPDF_Dictionary* pRoot)
842     {
843         m_pRoot = pRoot;
844     }
845
846     CPDF_Object*                LookupValue(int num);
847 protected:
848
849     CPDF_Dictionary*    m_pRoot;
850 };
851
852 class IFX_FileAvail
853 {
854 public:
855     virtual ~IFX_FileAvail() { }
856     virtual FX_BOOL                     IsDataAvail( FX_FILESIZE offset, FX_DWORD size) = 0;
857 };
858 class IFX_DownloadHints
859 {
860 public:
861     virtual ~IFX_DownloadHints() { }
862     virtual void                        AddSegment(FX_FILESIZE offset, FX_DWORD size) = 0;
863 };
864 #define PDF_IS_LINEARIZED                       1
865 #define PDF_NOT_LINEARIZED                      0
866 #define PDF_UNKNOW_LINEARIZED           -1
867 #define PDFFORM_NOTAVAIL                0
868 #define PDFFORM_AVAIL                   1
869 #define PDFFORM_NOTEXIST                2
870 class IPDF_DataAvail
871 {
872 public:
873     static IPDF_DataAvail* Create(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRead);
874     virtual ~IPDF_DataAvail() { }
875
876     IFX_FileAvail* GetFileAvail() const { return m_pFileAvail; }
877     IFX_FileRead* GetFileRead() const { return m_pFileRead; }
878
879     virtual FX_BOOL                     IsDocAvail(IFX_DownloadHints* pHints) = 0;
880     virtual void                        SetDocument(CPDF_Document* pDoc) = 0;
881     virtual FX_BOOL                     IsPageAvail(int iPage, IFX_DownloadHints* pHints) = 0;
882     virtual FX_BOOL                     IsLinearized() = 0;
883     virtual FX_INT32            IsFormAvail(IFX_DownloadHints *pHints) = 0;
884     virtual FX_INT32            IsLinearizedPDF() = 0;
885     virtual void                                GetLinearizedMainXRefInfo(FX_FILESIZE *pPos, FX_DWORD *pSize) = 0;
886
887 protected:
888     IPDF_DataAvail(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRead);
889
890     IFX_FileAvail* m_pFileAvail;
891     IFX_FileRead* m_pFileRead;
892 };
893 class CPDF_SortObjNumArray : public CFX_Object
894 {
895 public:
896
897     void AddObjNum(FX_DWORD dwObjNum);
898
899     FX_BOOL Find(FX_DWORD dwObjNum);
900
901     void RemoveAll()
902     {
903         m_number_array.RemoveAll();
904     }
905 protected:
906
907     FX_BOOL BinarySearch(FX_DWORD value, int &iNext);
908 protected:
909
910     CFX_DWordArray                      m_number_array;
911 };
912 enum PDF_PAGENODE_TYPE {
913     PDF_PAGENODE_UNKOWN = 0,
914     PDF_PAGENODE_PAGE,
915     PDF_PAGENODE_PAGES,
916     PDF_PAGENODE_ARRAY,
917 };
918 class CPDF_PageNode : public CFX_Object
919 {
920 public:
921     CPDF_PageNode() : m_type(PDF_PAGENODE_UNKOWN) {}
922     ~CPDF_PageNode();
923     PDF_PAGENODE_TYPE   m_type;
924     FX_DWORD                    m_dwPageNo;
925     CFX_PtrArray                m_childNode;
926 };
927 enum PDF_DATAAVAIL_STATUS {
928     PDF_DATAAVAIL_HEADER = 0,
929     PDF_DATAAVAIL_FIRSTPAGE,
930     PDF_DATAAVAIL_FIRSTPAGE_PREPARE,
931     PDF_DATAAVAIL_END,
932     PDF_DATAAVAIL_CROSSREF,
933     PDF_DATAAVAIL_CROSSREF_ITEM,
934     PDF_DATAAVAIL_CROSSREF_STREAM,
935     PDF_DATAAVAIL_TRAILER,
936     PDF_DATAAVAIL_LOADALLCRSOSSREF,
937     PDF_DATAAVAIL_ROOT,
938     PDF_DATAAVAIL_INFO,
939     PDF_DATAAVAIL_ACROFORM,
940     PDF_DATAAVAIL_ACROFORM_SUBOBJECT,
941     PDF_DATAAVAIL_PAGETREE,
942     PDF_DATAAVAIL_PAGE,
943     PDF_DATAAVAIL_PAGE_LATERLOAD,
944     PDF_DATAAVAIL_RESOURCES,
945     PDF_DATAAVAIL_DONE,
946     PDF_DATAAVAIL_ERROR,
947     PDF_DATAAVAIL_LOADALLFILE,
948     PDF_DATAAVAIL_TRAILER_APPEND
949 };
950 #endif