Fix the issue that pdfium swallows 'fi' or 'ff' in some pdf files
[pdfium.git] / core / include / fpdfapi / fpdf_objects.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 CORE_INCLUDE_FPDFAPI_FPDF_OBJECTS_H_
8 #define CORE_INCLUDE_FPDFAPI_FPDF_OBJECTS_H_
9
10 #include "../fxcrt/fx_coordinates.h"
11 #include "../fxcrt/fx_system.h"
12
13 class CPDF_Array;
14 class CPDF_Boolean;
15 class CPDF_CryptoHandler;
16 class CPDF_Dictionary;
17 class CPDF_Document;
18 class CPDF_IndirectObjects;
19 class CPDF_Null;
20 class CPDF_Number;
21 class CPDF_Parser;
22 class CPDF_Reference;
23 class CPDF_Stream;
24 class CPDF_StreamAcc;
25 class CPDF_StreamFilter;
26 class CPDF_String;
27 class IFX_FileRead;
28
29 #define PDFOBJ_INVALID 0
30 #define PDFOBJ_BOOLEAN 1
31 #define PDFOBJ_NUMBER 2
32 #define PDFOBJ_STRING 3
33 #define PDFOBJ_NAME 4
34 #define PDFOBJ_ARRAY 5
35 #define PDFOBJ_DICTIONARY 6
36 #define PDFOBJ_STREAM 7
37 #define PDFOBJ_NULL 8
38 #define PDFOBJ_REFERENCE 9
39
40 class CPDF_Object {
41  public:
42   int GetType() const { return m_Type; }
43
44   FX_DWORD GetObjNum() const { return m_ObjNum; }
45
46   FX_DWORD GetGenNum() const { return m_GenNum; }
47
48   FX_BOOL IsIdentical(CPDF_Object* pObj) const;
49
50   CPDF_Object* Clone(FX_BOOL bDirect = FALSE) const;
51
52   CPDF_Object* CloneRef(CPDF_IndirectObjects* pObjs) const;
53
54   CPDF_Object* GetDirect() const;
55
56   void Release();
57
58   CFX_ByteString GetString() const;
59
60   CFX_ByteStringC GetConstString() const;
61
62   CFX_WideString GetUnicodeText(CFX_CharMap* pCharMap = NULL) const;
63   FX_FLOAT GetNumber() const;
64
65   FX_FLOAT GetNumber16() const;
66
67   int GetInteger() const;
68
69   CPDF_Dictionary* GetDict() const;
70
71   CPDF_Array* GetArray() const;
72
73   void SetString(const CFX_ByteString& str);
74
75   void SetUnicodeText(const FX_WCHAR* pUnicodes, int len = -1);
76
77   int GetDirectType() const;
78
79   FX_BOOL IsModified() const { return FALSE; }
80
81  protected:
82   CPDF_Object(FX_DWORD type) : m_Type(type), m_ObjNum(0), m_GenNum(0) {}
83   ~CPDF_Object() {}
84   void Destroy();
85
86   static const int OBJECT_REF_MAX_DEPTH = 128;
87   static int s_nCurRefDepth;
88   FX_DWORD m_Type;
89   FX_DWORD m_ObjNum;
90   FX_DWORD m_GenNum;
91
92   friend class CPDF_IndirectObjects;
93   friend class CPDF_Parser;
94   friend class CPDF_SyntaxParser;
95
96  private:
97   CPDF_Object(const CPDF_Object& src) {}
98   CPDF_Object* CloneInternal(FX_BOOL bDirect, CFX_MapPtrToPtr* visited) const;
99 };
100 class CPDF_Boolean : public CPDF_Object {
101  public:
102   static CPDF_Boolean* Create(FX_BOOL value) { return new CPDF_Boolean(value); }
103
104   CPDF_Boolean() : CPDF_Object(PDFOBJ_BOOLEAN), m_bValue(false) {}
105   CPDF_Boolean(FX_BOOL value) : CPDF_Object(PDFOBJ_BOOLEAN), m_bValue(value) {}
106
107   FX_BOOL Identical(CPDF_Boolean* pOther) const {
108     return m_bValue == pOther->m_bValue;
109   }
110
111  protected:
112   FX_BOOL m_bValue;
113   friend class CPDF_Object;
114 };
115 class CPDF_Number : public CPDF_Object {
116  public:
117   static CPDF_Number* Create(int value) { return new CPDF_Number(value); }
118
119   static CPDF_Number* Create(FX_FLOAT value) { return new CPDF_Number(value); }
120
121   static CPDF_Number* Create(const CFX_ByteStringC& str) {
122     return new CPDF_Number(str);
123   }
124
125   static CPDF_Number* Create(FX_BOOL bInteger, void* pData) {
126     return new CPDF_Number(bInteger, pData);
127   }
128
129   CPDF_Number() : CPDF_Object(PDFOBJ_NUMBER), m_bInteger(false), m_Integer(0) {}
130
131   CPDF_Number(FX_BOOL bInteger, void* pData);
132
133   CPDF_Number(int value);
134
135   CPDF_Number(FX_FLOAT value);
136
137   CPDF_Number(const CFX_ByteStringC& str);
138
139   FX_BOOL Identical(CPDF_Number* pOther) const;
140
141   CFX_ByteString GetString() const;
142
143   void SetString(const CFX_ByteStringC& str);
144
145   FX_BOOL IsInteger() const { return m_bInteger; }
146
147   int GetInteger() const { return m_bInteger ? m_Integer : (int)m_Float; }
148
149   FX_FLOAT GetNumber() const {
150     return m_bInteger ? (FX_FLOAT)m_Integer : m_Float;
151   }
152
153   void SetNumber(FX_FLOAT value);
154
155   FX_FLOAT GetNumber16() const { return GetNumber(); }
156
157   FX_FLOAT GetFloat() const {
158     return m_bInteger ? (FX_FLOAT)m_Integer : m_Float;
159   }
160
161  protected:
162   FX_BOOL m_bInteger;
163
164   union {
165     int m_Integer;
166
167     FX_FLOAT m_Float;
168   };
169   friend class CPDF_Object;
170 };
171 class CPDF_String : public CPDF_Object {
172  public:
173   static CPDF_String* Create(const CFX_ByteString& str, FX_BOOL bHex = FALSE) {
174     return new CPDF_String(str, bHex);
175   }
176
177   static CPDF_String* Create(const CFX_WideString& str) {
178     return new CPDF_String(str);
179   }
180
181   CPDF_String() : CPDF_Object(PDFOBJ_STRING), m_bHex(FALSE) {}
182
183   CPDF_String(const CFX_ByteString& str, FX_BOOL bHex = FALSE)
184       : CPDF_Object(PDFOBJ_STRING), m_String(str), m_bHex(bHex) {}
185
186   CPDF_String(const CFX_WideString& str);
187
188   CFX_ByteString& GetString() { return m_String; }
189
190   FX_BOOL Identical(CPDF_String* pOther) const {
191     return m_String == pOther->m_String;
192   }
193
194   FX_BOOL IsHex() const { return m_bHex; }
195
196  protected:
197   CFX_ByteString m_String;
198
199   FX_BOOL m_bHex;
200   friend class CPDF_Object;
201 };
202 class CPDF_Name : public CPDF_Object {
203  public:
204   static CPDF_Name* Create(const CFX_ByteString& str) {
205     return new CPDF_Name(str);
206   }
207
208   static CPDF_Name* Create(const CFX_ByteStringC& str) {
209     return new CPDF_Name(str);
210   }
211
212   static CPDF_Name* Create(const FX_CHAR* str) { return new CPDF_Name(str); }
213
214   CPDF_Name(const CFX_ByteString& str)
215       : CPDF_Object(PDFOBJ_NAME), m_Name(str) {}
216   CPDF_Name(const CFX_ByteStringC& str)
217       : CPDF_Object(PDFOBJ_NAME), m_Name(str) {}
218   CPDF_Name(const FX_CHAR* str) : CPDF_Object(PDFOBJ_NAME), m_Name(str) {}
219
220   CFX_ByteString& GetString() { return m_Name; }
221
222   FX_BOOL Identical(CPDF_Name* pOther) const {
223     return m_Name == pOther->m_Name;
224   }
225
226  protected:
227   CFX_ByteString m_Name;
228   friend class CPDF_Object;
229 };
230 class CPDF_Array : public CPDF_Object {
231  public:
232   static CPDF_Array* Create() { return new CPDF_Array(); }
233
234   CPDF_Array() : CPDF_Object(PDFOBJ_ARRAY) {}
235
236   FX_DWORD GetCount() const { return m_Objects.GetSize(); }
237
238   CPDF_Object* GetElement(FX_DWORD index) const;
239
240   CPDF_Object* GetElementValue(FX_DWORD index) const;
241
242   CFX_AffineMatrix GetMatrix();
243
244   CFX_FloatRect GetRect();
245
246   CFX_ByteString GetString(FX_DWORD index) const;
247
248   CFX_ByteStringC GetConstString(FX_DWORD index) const;
249
250   int GetInteger(FX_DWORD index) const;
251
252   FX_FLOAT GetNumber(FX_DWORD index) const;
253
254   CPDF_Dictionary* GetDict(FX_DWORD index) const;
255
256   CPDF_Stream* GetStream(FX_DWORD index) const;
257
258   CPDF_Array* GetArray(FX_DWORD index) const;
259
260   FX_FLOAT GetFloat(FX_DWORD index) const { return GetNumber(index); }
261
262   void SetAt(FX_DWORD index,
263              CPDF_Object* pObj,
264              CPDF_IndirectObjects* pObjs = NULL);
265
266   void InsertAt(FX_DWORD index,
267                 CPDF_Object* pObj,
268                 CPDF_IndirectObjects* pObjs = NULL);
269
270   void RemoveAt(FX_DWORD index);
271
272   void Add(CPDF_Object* pObj, CPDF_IndirectObjects* pObjs = NULL);
273
274   void AddNumber(FX_FLOAT f);
275
276   void AddInteger(int i);
277
278   void AddString(const CFX_ByteString& str);
279
280   void AddName(const CFX_ByteString& str);
281
282   void AddReference(CPDF_IndirectObjects* pDoc, FX_DWORD objnum);
283
284   void AddReference(CPDF_IndirectObjects* pDoc, CPDF_Object* obj) {
285     AddReference(pDoc, obj->GetObjNum());
286   }
287
288   FX_FLOAT GetNumber16(FX_DWORD index) const { return GetNumber(index); }
289
290   void AddNumber16(FX_FLOAT value) { AddNumber(value); }
291
292   FX_BOOL Identical(CPDF_Array* pOther) const;
293
294  protected:
295   ~CPDF_Array();
296
297   CFX_PtrArray m_Objects;
298   friend class CPDF_Object;
299 };
300 class CPDF_Dictionary : public CPDF_Object {
301  public:
302   static CPDF_Dictionary* Create() { return new CPDF_Dictionary(); }
303
304   CPDF_Dictionary() : CPDF_Object(PDFOBJ_DICTIONARY) {}
305
306   CPDF_Object* GetElement(const CFX_ByteStringC& key) const;
307
308   CPDF_Object* GetElementValue(const CFX_ByteStringC& key) const;
309
310   CFX_ByteString GetString(const CFX_ByteStringC& key) const;
311
312   CFX_ByteStringC GetConstString(const CFX_ByteStringC& key) const;
313
314   CFX_ByteString GetString(const CFX_ByteStringC& key,
315                            const CFX_ByteStringC& default_str) const;
316
317   CFX_ByteStringC GetConstString(const CFX_ByteStringC& key,
318                                  const CFX_ByteStringC& default_str) const;
319
320   CFX_WideString GetUnicodeText(const CFX_ByteStringC& key,
321                                 CFX_CharMap* pCharMap = NULL) const;
322
323   int GetInteger(const CFX_ByteStringC& key) const;
324
325   int GetInteger(const CFX_ByteStringC& key, int default_int) const;
326
327   FX_BOOL GetBoolean(const CFX_ByteStringC& key,
328                      FX_BOOL bDefault = FALSE) const;
329
330   FX_FLOAT GetNumber(const CFX_ByteStringC& key) const;
331
332   CPDF_Dictionary* GetDict(const CFX_ByteStringC& key) const;
333
334   CPDF_Stream* GetStream(const CFX_ByteStringC& key) const;
335
336   CPDF_Array* GetArray(const CFX_ByteStringC& key) const;
337
338   CFX_FloatRect GetRect(const CFX_ByteStringC& key) const;
339
340   CFX_AffineMatrix GetMatrix(const CFX_ByteStringC& key) const;
341
342   FX_FLOAT GetFloat(const CFX_ByteStringC& key) const { return GetNumber(key); }
343
344   FX_BOOL KeyExist(const CFX_ByteStringC& key) const;
345
346   FX_POSITION GetStartPos() const;
347
348   CPDF_Object* GetNextElement(FX_POSITION& pos, CFX_ByteString& key) const;
349
350   void SetAt(const CFX_ByteStringC& key,
351              CPDF_Object* pObj,
352              CPDF_IndirectObjects* pObjs = NULL);
353
354   void SetAtName(const CFX_ByteStringC& key, const CFX_ByteString& name);
355
356   void SetAtString(const CFX_ByteStringC& key, const CFX_ByteString& string);
357
358   void SetAtInteger(const CFX_ByteStringC& key, int i);
359
360   void SetAtNumber(const CFX_ByteStringC& key, FX_FLOAT f);
361
362   void SetAtReference(const CFX_ByteStringC& key,
363                       CPDF_IndirectObjects* pDoc,
364                       FX_DWORD objnum);
365
366   void SetAtReference(const CFX_ByteStringC& key,
367                       CPDF_IndirectObjects* pDoc,
368                       CPDF_Object* obj) {
369     SetAtReference(key, pDoc, obj->GetObjNum());
370   }
371
372   void AddReference(const CFX_ByteStringC& key,
373                     CPDF_IndirectObjects* pDoc,
374                     FX_DWORD objnum);
375
376   void AddReference(const CFX_ByteStringC& key,
377                     CPDF_IndirectObjects* pDoc,
378                     CPDF_Object* obj) {
379     AddReference(key, pDoc, obj->GetObjNum());
380   }
381
382   void SetAtRect(const CFX_ByteStringC& key, const CFX_FloatRect& rect);
383
384   void SetAtMatrix(const CFX_ByteStringC& key, const CFX_AffineMatrix& matrix);
385
386   void SetAtBoolean(const CFX_ByteStringC& key, FX_BOOL bValue);
387
388   void RemoveAt(const CFX_ByteStringC& key);
389
390   void ReplaceKey(const CFX_ByteStringC& oldkey, const CFX_ByteStringC& newkey);
391
392   FX_BOOL Identical(CPDF_Dictionary* pDict) const;
393
394   int GetCount() const { return m_Map.GetCount(); }
395
396   void AddValue(const CFX_ByteStringC& key, CPDF_Object* pObj);
397
398  protected:
399   ~CPDF_Dictionary();
400
401   CFX_CMapByteStringToPtr m_Map;
402
403   friend class CPDF_Object;
404 };
405 class CPDF_Stream : public CPDF_Object {
406  public:
407   static CPDF_Stream* Create(uint8_t* pData,
408                              FX_DWORD size,
409                              CPDF_Dictionary* pDict) {
410     return new CPDF_Stream(pData, size, pDict);
411   }
412
413   CPDF_Stream(uint8_t* pData, FX_DWORD size, CPDF_Dictionary* pDict);
414
415   CPDF_Dictionary* GetDict() const { return m_pDict; }
416
417   void SetData(const uint8_t* pData,
418                FX_DWORD size,
419                FX_BOOL bCompressed,
420                FX_BOOL bKeepBuf);
421
422   void InitStream(uint8_t* pData, FX_DWORD size, CPDF_Dictionary* pDict);
423
424   void InitStream(IFX_FileRead* pFile, CPDF_Dictionary* pDict);
425
426   FX_BOOL Identical(CPDF_Stream* pOther) const;
427
428   FX_DWORD GetRawSize() const { return m_dwSize; }
429
430   FX_BOOL ReadRawData(FX_FILESIZE start_pos,
431                       uint8_t* pBuf,
432                       FX_DWORD buf_size) const;
433
434   FX_BOOL IsMemoryBased() const { return m_GenNum == (FX_DWORD)-1; }
435
436  protected:
437   ~CPDF_Stream();
438
439   CPDF_Dictionary* m_pDict;
440
441   FX_DWORD m_dwSize;
442
443   FX_DWORD m_GenNum;
444
445   union {
446     uint8_t* m_pDataBuf;
447
448     IFX_FileRead* m_pFile;
449   };
450
451   FX_FILESIZE m_FileOffset;
452
453   CPDF_CryptoHandler* m_pCryptoHandler;
454
455   void InitStream(CPDF_Dictionary* pDict);
456   friend class CPDF_Object;
457   friend class CPDF_StreamAcc;
458   friend class CPDF_AttachmentAcc;
459 };
460 class CPDF_StreamAcc {
461  public:
462   CPDF_StreamAcc();
463
464   ~CPDF_StreamAcc();
465
466   void LoadAllData(const CPDF_Stream* pStream,
467                    FX_BOOL bRawAccess = FALSE,
468                    FX_DWORD estimated_size = 0,
469                    FX_BOOL bImageAcc = FALSE);
470
471   const CPDF_Stream* GetStream() const { return m_pStream; }
472
473   CPDF_Dictionary* GetDict() const {
474     return m_pStream ? m_pStream->GetDict() : NULL;
475   }
476
477   const uint8_t* GetData() const;
478
479   FX_DWORD GetSize() const;
480
481   uint8_t* DetachData();
482
483   const CFX_ByteString& GetImageDecoder() { return m_ImageDecoder; }
484
485   const CPDF_Dictionary* GetImageParam() { return m_pImageParam; }
486
487  protected:
488   uint8_t* m_pData;
489
490   FX_DWORD m_dwSize;
491
492   FX_BOOL m_bNewBuf;
493
494   CFX_ByteString m_ImageDecoder;
495
496   CPDF_Dictionary* m_pImageParam;
497
498   const CPDF_Stream* m_pStream;
499
500   uint8_t* m_pSrcData;
501 };
502
503 class CPDF_Null : public CPDF_Object {
504  public:
505   static CPDF_Null* Create() { return new CPDF_Null(); }
506
507   CPDF_Null() : CPDF_Object(PDFOBJ_NULL) {}
508 };
509 class CPDF_Reference : public CPDF_Object {
510  public:
511   CPDF_Reference(CPDF_IndirectObjects* pDoc, int objnum)
512       : CPDF_Object(PDFOBJ_REFERENCE), m_pObjList(pDoc), m_RefObjNum(objnum) {}
513
514   CPDF_IndirectObjects* GetObjList() const { return m_pObjList; }
515
516   FX_DWORD GetRefObjNum() const { return m_RefObjNum; }
517
518   void SetRef(CPDF_IndirectObjects* pDoc, FX_DWORD objnum);
519
520   FX_BOOL Identical(CPDF_Reference* pOther) const {
521     return m_RefObjNum == pOther->m_RefObjNum;
522   }
523
524  protected:
525   CPDF_IndirectObjects* m_pObjList;
526
527   FX_DWORD m_RefObjNum;
528   friend class CPDF_Object;
529 };
530 class CPDF_IndirectObjects {
531  public:
532   CPDF_IndirectObjects(CPDF_Parser* pParser);
533
534   ~CPDF_IndirectObjects();
535
536   CPDF_Object* GetIndirectObject(FX_DWORD objnum,
537                                  struct PARSE_CONTEXT* pContext = NULL);
538
539   int GetIndirectType(FX_DWORD objnum);
540
541   FX_DWORD AddIndirectObject(CPDF_Object* pObj);
542
543   void ReleaseIndirectObject(FX_DWORD objnum);
544
545   void InsertIndirectObject(FX_DWORD objnum, CPDF_Object* pObj);
546
547   FX_DWORD GetLastObjNum() const;
548
549   FX_POSITION GetStartPosition() const {
550     return m_IndirectObjs.GetStartPosition();
551   }
552
553   void GetNextAssoc(FX_POSITION& rPos,
554                     FX_DWORD& objnum,
555                     CPDF_Object*& pObject) const {
556     m_IndirectObjs.GetNextAssoc(rPos, (void*&)objnum, (void*&)pObject);
557   }
558
559  protected:
560   CFX_MapPtrToPtr m_IndirectObjs;
561
562   CPDF_Parser* m_pParser;
563
564   FX_DWORD m_LastObjNum;
565 };
566
567 #endif  // CORE_INCLUDE_FPDFAPI_FPDF_OBJECTS_H_