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_SRC_FPDFAPI_FPDF_PAGE_PAGEINT_H_
8 #define CORE_SRC_FPDFAPI_FPDF_PAGE_PAGEINT_H_
9 
10 #include <map>
11 #include <memory>
12 #include <vector>
13 
14 #include "core/include/fpdfapi/fpdf_page.h"
15 #include "core/include/fpdfapi/fpdf_pageobj.h"
16 
17 class CPDF_AllStates;
18 class CPDF_ParseOptions;
19 
20 #define PARSE_STEP_LIMIT 100
21 
22 class CPDF_StreamParser {
23  public:
24   enum SyntaxType { EndOfData, Number, Keyword, Name, Others };
25 
26   CPDF_StreamParser(const uint8_t* pData, FX_DWORD dwSize);
27   ~CPDF_StreamParser();
28 
29   CPDF_Stream* ReadInlineStream(CPDF_Document* pDoc,
30                                 CPDF_Dictionary* pDict,
31                                 CPDF_Object* pCSObj,
32                                 FX_BOOL bDecode);
33   SyntaxType ParseNextElement();
GetWordBuf()34   uint8_t* GetWordBuf() { return m_WordBuffer; }
GetWordSize()35   FX_DWORD GetWordSize() const { return m_WordSize; }
GetObject()36   CPDF_Object* GetObject() {
37     CPDF_Object* pObj = m_pLastObj;
38     m_pLastObj = NULL;
39     return pObj;
40   }
GetPos()41   FX_DWORD GetPos() const { return m_Pos; }
SetPos(FX_DWORD pos)42   void SetPos(FX_DWORD pos) { m_Pos = pos; }
43   CPDF_Object* ReadNextObject(FX_BOOL bAllowNestedArray = FALSE,
44                               FX_BOOL bInArray = FALSE);
45   void SkipPathObject();
46 
47  protected:
48   friend class fpdf_page_parser_old_ReadHexString_Test;
49 
50   void GetNextWord(FX_BOOL& bIsNumber);
51   CFX_ByteString ReadString();
52   CFX_ByteString ReadHexString();
53   const uint8_t* m_pBuf;
54 
55   // Length in bytes of m_pBuf.
56   FX_DWORD m_Size;
57 
58   // Current byte position within m_pBuf.
59   FX_DWORD m_Pos;
60 
61   uint8_t m_WordBuffer[256];
62   FX_DWORD m_WordSize;
63   CPDF_Object* m_pLastObj;
64 
65  private:
66   bool PositionIsInBounds() const;
67 };
68 
69 #define PARAM_BUF_SIZE 16
70 struct ContentParam {
71   int m_Type;
72   union {
73     struct {
74       FX_BOOL m_bInteger;
75       union {
76         int m_Integer;
77         FX_FLOAT m_Float;
78       };
79     } m_Number;
80     CPDF_Object* m_pObject;
81     struct {
82       int m_Len;
83       char m_Buffer[32];
84     } m_Name;
85   };
86 };
87 #define _FPDF_MAX_FORM_LEVEL_ 30
88 #define _FPDF_MAX_TYPE3_FORM_LEVEL_ 4
89 #define _FPDF_MAX_OBJECT_STACK_SIZE_ 512
90 class CPDF_StreamContentParser {
91  public:
92   CPDF_StreamContentParser(CPDF_Document* pDoc,
93                            CPDF_Dictionary* pPageResources,
94                            CPDF_Dictionary* pParentResources,
95                            CFX_Matrix* pmtContentToUser,
96                            CPDF_PageObjects* pObjList,
97                            CPDF_Dictionary* pResources,
98                            CFX_FloatRect* pBBox,
99                            CPDF_ParseOptions* pOptions,
100                            CPDF_AllStates* pAllStates,
101                            int level);
102   ~CPDF_StreamContentParser();
103 
GetObjectList()104   CPDF_PageObjects* GetObjectList() const { return m_pObjectList; }
GetCurStates()105   CPDF_AllStates* GetCurStates() const { return m_pCurStates.get(); }
IsColored()106   FX_BOOL IsColored() const { return m_bColored; }
GetType3Data()107   const FX_FLOAT* GetType3Data() const { return m_Type3Data; }
108 
109   void AddNumberParam(const FX_CHAR* str, int len);
110   void AddObjectParam(CPDF_Object* pObj);
111   void AddNameParam(const FX_CHAR* name, int size);
112   int GetNextParamPos();
113   void ClearAllParams();
114   CPDF_Object* GetObject(FX_DWORD index);
115   CFX_ByteString GetString(FX_DWORD index);
116   FX_FLOAT GetNumber(FX_DWORD index);
117   FX_FLOAT GetNumber16(FX_DWORD index);
GetInteger(FX_DWORD index)118   int GetInteger(FX_DWORD index) { return (int32_t)(GetNumber(index)); }
119   FX_BOOL OnOperator(const FX_CHAR* op);
120   void BigCaseCaller(int index);
GetParsePos()121   FX_DWORD GetParsePos() { return m_pSyntax->GetPos(); }
122   void AddTextObject(CFX_ByteString* pText,
123                      FX_FLOAT fInitKerning,
124                      FX_FLOAT* pKerning,
125                      int count);
126 
127   void ConvertUserSpace(FX_FLOAT& x, FX_FLOAT& y);
128   void ConvertTextSpace(FX_FLOAT& x, FX_FLOAT& y);
129   void OnChangeTextMatrix();
130   FX_DWORD Parse(const uint8_t* pData, FX_DWORD dwSize, FX_DWORD max_cost);
131   void ParsePathObject();
132   void AddPathPoint(FX_FLOAT x, FX_FLOAT y, int flag);
133   void AddPathRect(FX_FLOAT x, FX_FLOAT y, FX_FLOAT w, FX_FLOAT h);
134   void AddPathObject(int FillType, FX_BOOL bStroke);
135   CPDF_ImageObject* AddImage(CPDF_Stream* pStream,
136                              CPDF_Image* pImage,
137                              FX_BOOL bInline);
138   void AddDuplicateImage();
139   void AddForm(CPDF_Stream*);
140   void SetGraphicStates(CPDF_PageObject* pObj,
141                         FX_BOOL bColor,
142                         FX_BOOL bText,
143                         FX_BOOL bGraph);
144   void SaveStates(CPDF_AllStates*);
145   void RestoreStates(CPDF_AllStates*);
146   CPDF_Font* FindFont(const CFX_ByteString& name);
147   CPDF_ColorSpace* FindColorSpace(const CFX_ByteString& name);
148   CPDF_Pattern* FindPattern(const CFX_ByteString& name, FX_BOOL bShading);
149   CPDF_Object* FindResourceObj(const CFX_ByteStringC& type,
150                                const CFX_ByteString& name);
151 
152  protected:
153   struct OpCode {
154     FX_DWORD m_OpId;
155     void (CPDF_StreamContentParser::*m_OpHandler)();
156   };
157   static const OpCode g_OpCodes[];
158 
159   void Handle_CloseFillStrokePath();
160   void Handle_FillStrokePath();
161   void Handle_CloseEOFillStrokePath();
162   void Handle_EOFillStrokePath();
163   void Handle_BeginMarkedContent_Dictionary();
164   void Handle_BeginImage();
165   void Handle_BeginMarkedContent();
166   void Handle_BeginText();
167   void Handle_BeginSectionUndefined();
168   void Handle_CurveTo_123();
169   void Handle_ConcatMatrix();
170   void Handle_SetColorSpace_Fill();
171   void Handle_SetColorSpace_Stroke();
172   void Handle_SetDash();
173   void Handle_SetCharWidth();
174   void Handle_SetCachedDevice();
175   void Handle_ExecuteXObject();
176   void Handle_MarkPlace_Dictionary();
177   void Handle_EndImage();
178   void Handle_EndMarkedContent();
179   void Handle_EndText();
180   void Handle_EndSectionUndefined();
181   void Handle_FillPath();
182   void Handle_FillPathOld();
183   void Handle_EOFillPath();
184   void Handle_SetGray_Fill();
185   void Handle_SetGray_Stroke();
186   void Handle_SetExtendGraphState();
187   void Handle_ClosePath();
188   void Handle_SetFlat();
189   void Handle_BeginImageData();
190   void Handle_SetLineJoin();
191   void Handle_SetLineCap();
192   void Handle_SetCMYKColor_Fill();
193   void Handle_SetCMYKColor_Stroke();
194   void Handle_LineTo();
195   void Handle_MoveTo();
196   void Handle_SetMiterLimit();
197   void Handle_MarkPlace();
198   void Handle_EndPath();
199   void Handle_SaveGraphState();
200   void Handle_RestoreGraphState();
201   void Handle_Rectangle();
202   void Handle_SetRGBColor_Fill();
203   void Handle_SetRGBColor_Stroke();
204   void Handle_SetRenderIntent();
205   void Handle_CloseStrokePath();
206   void Handle_StrokePath();
207   void Handle_SetColor_Fill();
208   void Handle_SetColor_Stroke();
209   void Handle_SetColorPS_Fill();
210   void Handle_SetColorPS_Stroke();
211   void Handle_ShadeFill();
212   void Handle_SetCharSpace();
213   void Handle_MoveTextPoint();
214   void Handle_MoveTextPoint_SetLeading();
215   void Handle_SetFont();
216   void Handle_ShowText();
217   void Handle_ShowText_Positioning();
218   void Handle_SetTextLeading();
219   void Handle_SetTextMatrix();
220   void Handle_SetTextRenderMode();
221   void Handle_SetTextRise();
222   void Handle_SetWordSpace();
223   void Handle_SetHorzScale();
224   void Handle_MoveToNextLine();
225   void Handle_CurveTo_23();
226   void Handle_SetLineWidth();
227   void Handle_Clip();
228   void Handle_EOClip();
229   void Handle_CurveTo_13();
230   void Handle_NextLineShowText();
231   void Handle_NextLineShowText_Space();
232   void Handle_Invalid();
233 
234   CPDF_Document* const m_pDocument;
235   CPDF_Dictionary* m_pPageResources;
236   CPDF_Dictionary* m_pParentResources;
237   CPDF_Dictionary* m_pResources;
238   CPDF_PageObjects* m_pObjectList;
239   int m_Level;
240   CFX_Matrix m_mtContentToUser;
241   CFX_FloatRect m_BBox;
242   CPDF_ParseOptions m_Options;
243   ContentParam m_ParamBuf1[PARAM_BUF_SIZE];
244   FX_DWORD m_ParamStartPos;
245   FX_DWORD m_ParamCount;
246   CPDF_StreamParser* m_pSyntax;
247   std::unique_ptr<CPDF_AllStates> m_pCurStates;
248   CPDF_ContentMark m_CurContentMark;
249   CFX_ArrayTemplate<CPDF_TextObject*> m_ClipTextList;
250   CPDF_TextObject* m_pLastTextObject;
251   FX_FLOAT m_DefFontSize;
252   int m_CompatCount;
253   FX_PATHPOINT* m_pPathPoints;
254   int m_PathPointCount;
255   int m_PathAllocSize;
256   FX_FLOAT m_PathStartX;
257   FX_FLOAT m_PathStartY;
258   FX_FLOAT m_PathCurrentX;
259   FX_FLOAT m_PathCurrentY;
260   int m_PathClipType;
261   CFX_ByteString m_LastImageName;
262   CPDF_Image* m_pLastImage;
263   CFX_BinaryBuf m_LastImageDict;
264   CFX_BinaryBuf m_LastImageData;
265   CPDF_Dictionary* m_pLastImageDict;
266   CPDF_Dictionary* m_pLastCloneImageDict;
267   FX_BOOL m_bReleaseLastDict;
268   FX_BOOL m_bSameLastDict;
269   FX_BOOL m_bColored;
270   FX_FLOAT m_Type3Data[6];
271   FX_BOOL m_bResourceMissing;
272   std::vector<std::unique_ptr<CPDF_AllStates>> m_StateStack;
273 };
274 class CPDF_ContentParser {
275  public:
276   enum ParseStatus { Ready, ToBeContinued, Done };
277 
278   CPDF_ContentParser();
279   ~CPDF_ContentParser();
280 
GetStatus()281   ParseStatus GetStatus() const { return m_Status; }
282   void Start(CPDF_Page* pPage, CPDF_ParseOptions* pOptions);
283   void Start(CPDF_Form* pForm,
284              CPDF_AllStates* pGraphicStates,
285              CFX_Matrix* pParentMatrix,
286              CPDF_Type3Char* pType3Char,
287              CPDF_ParseOptions* pOptions,
288              int level);
289   void Continue(IFX_Pause* pPause);
290 
291  private:
292   enum InternalStage {
293     STAGE_GETCONTENT = 1,
294     STAGE_PARSE,
295     STAGE_CHECKCLIP,
296   };
297 
298   ParseStatus m_Status;
299   InternalStage m_InternalStage;
300   CPDF_PageObjects* m_pObjects;
301   FX_BOOL m_bForm;
302   CPDF_ParseOptions m_Options;
303   CPDF_Type3Char* m_pType3Char;
304   FX_DWORD m_nStreams;
305   std::unique_ptr<CPDF_StreamAcc> m_pSingleStream;
306   std::vector<std::unique_ptr<CPDF_StreamAcc>> m_StreamArray;
307   uint8_t* m_pData;
308   FX_DWORD m_Size;
309   FX_DWORD m_CurrentOffset;
310   std::unique_ptr<CPDF_StreamContentParser> m_pParser;
311 };
312 class CPDF_AllStates : public CPDF_GraphicStates {
313  public:
314   CPDF_AllStates();
315   ~CPDF_AllStates();
316   void Copy(const CPDF_AllStates& src);
317   void ProcessExtGS(CPDF_Dictionary* pGS, CPDF_StreamContentParser* pParser);
318   void SetLineDash(CPDF_Array*, FX_FLOAT, FX_FLOAT scale);
319   CFX_Matrix m_TextMatrix, m_CTM, m_ParentMatrix;
320   FX_FLOAT m_TextX, m_TextY, m_TextLineX, m_TextLineY;
321   FX_FLOAT m_TextLeading, m_TextRise, m_TextHorzScale;
322 };
323 
324 class CPDF_DocPageData {
325  public:
326   explicit CPDF_DocPageData(CPDF_Document* pPDFDoc);
327   ~CPDF_DocPageData();
328 
329   void Clear(FX_BOOL bRelease = FALSE);
330   CPDF_Font* GetFont(CPDF_Dictionary* pFontDict, FX_BOOL findOnly);
331   CPDF_Font* GetStandardFont(const CFX_ByteStringC& fontName,
332                              CPDF_FontEncoding* pEncoding);
333   void ReleaseFont(CPDF_Dictionary* pFontDict);
334   CPDF_ColorSpace* GetColorSpace(CPDF_Object* pCSObj,
335                                  const CPDF_Dictionary* pResources);
336   CPDF_ColorSpace* GetCopiedColorSpace(CPDF_Object* pCSObj);
337   void ReleaseColorSpace(CPDF_Object* pColorSpace);
338   CPDF_Pattern* GetPattern(CPDF_Object* pPatternObj,
339                            FX_BOOL bShading,
340                            const CFX_Matrix* matrix);
341   void ReleasePattern(CPDF_Object* pPatternObj);
342   CPDF_Image* GetImage(CPDF_Object* pImageStream);
343   void ReleaseImage(CPDF_Object* pImageStream);
344   CPDF_IccProfile* GetIccProfile(CPDF_Stream* pIccProfileStream);
345   void ReleaseIccProfile(CPDF_IccProfile* pIccProfile);
346   CPDF_StreamAcc* GetFontFileStreamAcc(CPDF_Stream* pFontStream);
347   void ReleaseFontFileStreamAcc(CPDF_Stream* pFontStream,
348                                 FX_BOOL bForce = FALSE);
IsForceClear()349   FX_BOOL IsForceClear() const { return m_bForceClear; }
350   CPDF_CountedColorSpace* FindColorSpacePtr(CPDF_Object* pCSObj) const;
351   CPDF_CountedPattern* FindPatternPtr(CPDF_Object* pPatternObj) const;
352 
353  private:
354   using CPDF_CountedFont = CPDF_CountedObject<CPDF_Font>;
355   using CPDF_CountedIccProfile = CPDF_CountedObject<CPDF_IccProfile>;
356   using CPDF_CountedImage = CPDF_CountedObject<CPDF_Image>;
357   using CPDF_CountedStreamAcc = CPDF_CountedObject<CPDF_StreamAcc>;
358 
359   using CPDF_ColorSpaceMap = std::map<CPDF_Object*, CPDF_CountedColorSpace*>;
360   using CPDF_FontFileMap = std::map<CPDF_Stream*, CPDF_CountedStreamAcc*>;
361   using CPDF_FontMap = std::map<CPDF_Dictionary*, CPDF_CountedFont*>;
362   using CPDF_IccProfileMap = std::map<CPDF_Stream*, CPDF_CountedIccProfile*>;
363   using CPDF_ImageMap = std::map<FX_DWORD, CPDF_CountedImage*>;
364   using CPDF_PatternMap = std::map<CPDF_Object*, CPDF_CountedPattern*>;
365 
366   CPDF_Document* const m_pPDFDoc;
367   FX_BOOL m_bForceClear;
368   std::map<CFX_ByteString, CPDF_Stream*> m_HashProfileMap;
369   CPDF_ColorSpaceMap m_ColorSpaceMap;
370   CPDF_FontFileMap m_FontFileMap;
371   CPDF_FontMap m_FontMap;
372   CPDF_IccProfileMap m_IccProfileMap;
373   CPDF_ImageMap m_ImageMap;
374   CPDF_PatternMap m_PatternMap;
375 };
376 
377 class CPDF_Function {
378  public:
379   static CPDF_Function* Load(CPDF_Object* pFuncObj);
380   virtual ~CPDF_Function();
381   FX_BOOL Call(FX_FLOAT* inputs,
382                int ninputs,
383                FX_FLOAT* results,
384                int& nresults) const;
CountInputs()385   int CountInputs() { return m_nInputs; }
CountOutputs()386   int CountOutputs() { return m_nOutputs; }
387 
388  protected:
389   CPDF_Function();
390   int m_nInputs, m_nOutputs;
391   FX_FLOAT* m_pDomains;
392   FX_FLOAT* m_pRanges;
393   FX_BOOL Init(CPDF_Object* pObj);
394   virtual FX_BOOL v_Init(CPDF_Object* pObj) = 0;
395   virtual FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const = 0;
396 };
397 class CPDF_IccProfile {
398  public:
399   CPDF_IccProfile(const uint8_t* pData, FX_DWORD dwSize);
400   ~CPDF_IccProfile();
GetComponents()401   int32_t GetComponents() const { return m_nSrcComponents; }
402   FX_BOOL m_bsRGB;
403   void* m_pTransform;
404 
405  private:
406   int32_t m_nSrcComponents;
407 };
408 
409 class CPDF_DeviceCS : public CPDF_ColorSpace {
410  public:
411   CPDF_DeviceCS(CPDF_Document* pDoc, int family);
412 
413   FX_BOOL GetRGB(FX_FLOAT* pBuf,
414                  FX_FLOAT& R,
415                  FX_FLOAT& G,
416                  FX_FLOAT& B) const override;
417   FX_BOOL SetRGB(FX_FLOAT* pBuf,
418                  FX_FLOAT R,
419                  FX_FLOAT G,
420                  FX_FLOAT B) const override;
421   FX_BOOL v_GetCMYK(FX_FLOAT* pBuf,
422                     FX_FLOAT& c,
423                     FX_FLOAT& m,
424                     FX_FLOAT& y,
425                     FX_FLOAT& k) const override;
426   FX_BOOL v_SetCMYK(FX_FLOAT* pBuf,
427                     FX_FLOAT c,
428                     FX_FLOAT m,
429                     FX_FLOAT y,
430                     FX_FLOAT k) const override;
431   void TranslateImageLine(uint8_t* pDestBuf,
432                           const uint8_t* pSrcBuf,
433                           int pixels,
434                           int image_width,
435                           int image_height,
436                           FX_BOOL bTransMask = FALSE) const override;
437 };
438 
439 class CPDF_PatternCS : public CPDF_ColorSpace {
440  public:
CPDF_PatternCS(CPDF_Document * pDoc)441   explicit CPDF_PatternCS(CPDF_Document* pDoc)
442       : CPDF_ColorSpace(pDoc, PDFCS_PATTERN, 1),
443         m_pBaseCS(nullptr),
444         m_pCountedBaseCS(nullptr) {}
445   ~CPDF_PatternCS() override;
446   FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
447   FX_BOOL GetRGB(FX_FLOAT* pBuf,
448                  FX_FLOAT& R,
449                  FX_FLOAT& G,
450                  FX_FLOAT& B) const override;
451   CPDF_ColorSpace* GetBaseCS() const override;
452 
453  private:
454   CPDF_ColorSpace* m_pBaseCS;
455   CPDF_CountedColorSpace* m_pCountedBaseCS;
456 };
457 
458 void PDF_ReplaceAbbr(CPDF_Object* pObj);
459 
460 #endif  // CORE_SRC_FPDFAPI_FPDF_PAGE_PAGEINT_H_
461