xref: /aosp_15_r20/external/pdfium/testing/embedder_test.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1*3ac0a46fSAndroid Build Coastguard Worker // Copyright 2015 The PDFium Authors
2*3ac0a46fSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*3ac0a46fSAndroid Build Coastguard Worker // found in the LICENSE file.
4*3ac0a46fSAndroid Build Coastguard Worker 
5*3ac0a46fSAndroid Build Coastguard Worker #include "testing/embedder_test.h"
6*3ac0a46fSAndroid Build Coastguard Worker 
7*3ac0a46fSAndroid Build Coastguard Worker #include <algorithm>
8*3ac0a46fSAndroid Build Coastguard Worker #include <memory>
9*3ac0a46fSAndroid Build Coastguard Worker #include <string>
10*3ac0a46fSAndroid Build Coastguard Worker #include <utility>
11*3ac0a46fSAndroid Build Coastguard Worker #include <vector>
12*3ac0a46fSAndroid Build Coastguard Worker 
13*3ac0a46fSAndroid Build Coastguard Worker #include "core/fdrm/fx_crypt.h"
14*3ac0a46fSAndroid Build Coastguard Worker #include "public/cpp/fpdf_scopers.h"
15*3ac0a46fSAndroid Build Coastguard Worker #include "public/fpdf_dataavail.h"
16*3ac0a46fSAndroid Build Coastguard Worker #include "public/fpdf_edit.h"
17*3ac0a46fSAndroid Build Coastguard Worker #include "public/fpdf_text.h"
18*3ac0a46fSAndroid Build Coastguard Worker #include "public/fpdfview.h"
19*3ac0a46fSAndroid Build Coastguard Worker #include "testing/embedder_test_environment.h"
20*3ac0a46fSAndroid Build Coastguard Worker #include "testing/gmock/include/gmock/gmock.h"
21*3ac0a46fSAndroid Build Coastguard Worker #include "testing/test_loader.h"
22*3ac0a46fSAndroid Build Coastguard Worker #include "testing/utils/bitmap_saver.h"
23*3ac0a46fSAndroid Build Coastguard Worker #include "testing/utils/file_util.h"
24*3ac0a46fSAndroid Build Coastguard Worker #include "testing/utils/hash.h"
25*3ac0a46fSAndroid Build Coastguard Worker #include "testing/utils/path_service.h"
26*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/check.h"
27*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/check_op.h"
28*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/containers/contains.h"
29*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/notreached.h"
30*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/numerics/checked_math.h"
31*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/numerics/safe_conversions.h"
32*3ac0a46fSAndroid Build Coastguard Worker 
33*3ac0a46fSAndroid Build Coastguard Worker namespace {
34*3ac0a46fSAndroid Build Coastguard Worker 
GetBitmapBytesPerPixel(FPDF_BITMAP bitmap)35*3ac0a46fSAndroid Build Coastguard Worker int GetBitmapBytesPerPixel(FPDF_BITMAP bitmap) {
36*3ac0a46fSAndroid Build Coastguard Worker   return EmbedderTest::BytesPerPixelForFormat(FPDFBitmap_GetFormat(bitmap));
37*3ac0a46fSAndroid Build Coastguard Worker }
38*3ac0a46fSAndroid Build Coastguard Worker 
39*3ac0a46fSAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
GetRecordProc(HDC hdc,HANDLETABLE * handle_table,const ENHMETARECORD * record,int objects_count,LPARAM param)40*3ac0a46fSAndroid Build Coastguard Worker int CALLBACK GetRecordProc(HDC hdc,
41*3ac0a46fSAndroid Build Coastguard Worker                            HANDLETABLE* handle_table,
42*3ac0a46fSAndroid Build Coastguard Worker                            const ENHMETARECORD* record,
43*3ac0a46fSAndroid Build Coastguard Worker                            int objects_count,
44*3ac0a46fSAndroid Build Coastguard Worker                            LPARAM param) {
45*3ac0a46fSAndroid Build Coastguard Worker   auto& records = *reinterpret_cast<std::vector<const ENHMETARECORD*>*>(param);
46*3ac0a46fSAndroid Build Coastguard Worker   records.push_back(record);
47*3ac0a46fSAndroid Build Coastguard Worker   return 1;
48*3ac0a46fSAndroid Build Coastguard Worker }
49*3ac0a46fSAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_WIN)
50*3ac0a46fSAndroid Build Coastguard Worker 
51*3ac0a46fSAndroid Build Coastguard Worker // These "jump" into the delegate to do actual testing.
UnsupportedHandlerTrampoline(UNSUPPORT_INFO * info,int type)52*3ac0a46fSAndroid Build Coastguard Worker void UnsupportedHandlerTrampoline(UNSUPPORT_INFO* info, int type) {
53*3ac0a46fSAndroid Build Coastguard Worker   auto* delegate = static_cast<EmbedderTest*>(info)->GetDelegate();
54*3ac0a46fSAndroid Build Coastguard Worker   delegate->UnsupportedHandler(type);
55*3ac0a46fSAndroid Build Coastguard Worker }
56*3ac0a46fSAndroid Build Coastguard Worker 
AlertTrampoline(IPDF_JSPLATFORM * platform,FPDF_WIDESTRING message,FPDF_WIDESTRING title,int type,int icon)57*3ac0a46fSAndroid Build Coastguard Worker int AlertTrampoline(IPDF_JSPLATFORM* platform,
58*3ac0a46fSAndroid Build Coastguard Worker                     FPDF_WIDESTRING message,
59*3ac0a46fSAndroid Build Coastguard Worker                     FPDF_WIDESTRING title,
60*3ac0a46fSAndroid Build Coastguard Worker                     int type,
61*3ac0a46fSAndroid Build Coastguard Worker                     int icon) {
62*3ac0a46fSAndroid Build Coastguard Worker   auto* delegate = static_cast<EmbedderTest*>(platform)->GetDelegate();
63*3ac0a46fSAndroid Build Coastguard Worker   return delegate->Alert(message, title, type, icon);
64*3ac0a46fSAndroid Build Coastguard Worker }
65*3ac0a46fSAndroid Build Coastguard Worker 
SetTimerTrampoline(FPDF_FORMFILLINFO * info,int msecs,TimerCallback fn)66*3ac0a46fSAndroid Build Coastguard Worker int SetTimerTrampoline(FPDF_FORMFILLINFO* info, int msecs, TimerCallback fn) {
67*3ac0a46fSAndroid Build Coastguard Worker   auto* delegate = static_cast<EmbedderTest*>(info)->GetDelegate();
68*3ac0a46fSAndroid Build Coastguard Worker   return delegate->SetTimer(msecs, fn);
69*3ac0a46fSAndroid Build Coastguard Worker }
70*3ac0a46fSAndroid Build Coastguard Worker 
KillTimerTrampoline(FPDF_FORMFILLINFO * info,int id)71*3ac0a46fSAndroid Build Coastguard Worker void KillTimerTrampoline(FPDF_FORMFILLINFO* info, int id) {
72*3ac0a46fSAndroid Build Coastguard Worker   auto* delegate = static_cast<EmbedderTest*>(info)->GetDelegate();
73*3ac0a46fSAndroid Build Coastguard Worker   return delegate->KillTimer(id);
74*3ac0a46fSAndroid Build Coastguard Worker }
75*3ac0a46fSAndroid Build Coastguard Worker 
GetPageTrampoline(FPDF_FORMFILLINFO * info,FPDF_DOCUMENT document,int page_index)76*3ac0a46fSAndroid Build Coastguard Worker FPDF_PAGE GetPageTrampoline(FPDF_FORMFILLINFO* info,
77*3ac0a46fSAndroid Build Coastguard Worker                             FPDF_DOCUMENT document,
78*3ac0a46fSAndroid Build Coastguard Worker                             int page_index) {
79*3ac0a46fSAndroid Build Coastguard Worker   auto* delegate = static_cast<EmbedderTest*>(info)->GetDelegate();
80*3ac0a46fSAndroid Build Coastguard Worker   return delegate->GetPage(info, document, page_index);
81*3ac0a46fSAndroid Build Coastguard Worker }
82*3ac0a46fSAndroid Build Coastguard Worker 
DoURIActionTrampoline(FPDF_FORMFILLINFO * info,FPDF_BYTESTRING uri)83*3ac0a46fSAndroid Build Coastguard Worker void DoURIActionTrampoline(FPDF_FORMFILLINFO* info, FPDF_BYTESTRING uri) {
84*3ac0a46fSAndroid Build Coastguard Worker   auto* delegate = static_cast<EmbedderTest*>(info)->GetDelegate();
85*3ac0a46fSAndroid Build Coastguard Worker   return delegate->DoURIAction(uri);
86*3ac0a46fSAndroid Build Coastguard Worker }
87*3ac0a46fSAndroid Build Coastguard Worker 
DoGoToActionTrampoline(FPDF_FORMFILLINFO * info,int page_index,int zoom_mode,float * pos_array,int array_size)88*3ac0a46fSAndroid Build Coastguard Worker void DoGoToActionTrampoline(FPDF_FORMFILLINFO* info,
89*3ac0a46fSAndroid Build Coastguard Worker                             int page_index,
90*3ac0a46fSAndroid Build Coastguard Worker                             int zoom_mode,
91*3ac0a46fSAndroid Build Coastguard Worker                             float* pos_array,
92*3ac0a46fSAndroid Build Coastguard Worker                             int array_size) {
93*3ac0a46fSAndroid Build Coastguard Worker   auto* delegate = static_cast<EmbedderTest*>(info)->GetDelegate();
94*3ac0a46fSAndroid Build Coastguard Worker   return delegate->DoGoToAction(info, page_index, zoom_mode, pos_array,
95*3ac0a46fSAndroid Build Coastguard Worker                                 array_size);
96*3ac0a46fSAndroid Build Coastguard Worker }
97*3ac0a46fSAndroid Build Coastguard Worker 
OnFocusChangeTrampoline(FPDF_FORMFILLINFO * info,FPDF_ANNOTATION annot,int page_index)98*3ac0a46fSAndroid Build Coastguard Worker void OnFocusChangeTrampoline(FPDF_FORMFILLINFO* info,
99*3ac0a46fSAndroid Build Coastguard Worker                              FPDF_ANNOTATION annot,
100*3ac0a46fSAndroid Build Coastguard Worker                              int page_index) {
101*3ac0a46fSAndroid Build Coastguard Worker   auto* delegate = static_cast<EmbedderTest*>(info)->GetDelegate();
102*3ac0a46fSAndroid Build Coastguard Worker   return delegate->OnFocusChange(info, annot, page_index);
103*3ac0a46fSAndroid Build Coastguard Worker }
104*3ac0a46fSAndroid Build Coastguard Worker 
DoURIActionWithKeyboardModifierTrampoline(FPDF_FORMFILLINFO * info,FPDF_BYTESTRING uri,int modifiers)105*3ac0a46fSAndroid Build Coastguard Worker void DoURIActionWithKeyboardModifierTrampoline(FPDF_FORMFILLINFO* info,
106*3ac0a46fSAndroid Build Coastguard Worker                                                FPDF_BYTESTRING uri,
107*3ac0a46fSAndroid Build Coastguard Worker                                                int modifiers) {
108*3ac0a46fSAndroid Build Coastguard Worker   auto* delegate = static_cast<EmbedderTest*>(info)->GetDelegate();
109*3ac0a46fSAndroid Build Coastguard Worker   return delegate->DoURIActionWithKeyboardModifier(info, uri, modifiers);
110*3ac0a46fSAndroid Build Coastguard Worker }
111*3ac0a46fSAndroid Build Coastguard Worker 
112*3ac0a46fSAndroid Build Coastguard Worker // These do nothing (but must return a reasonable default value).
InvalidateStub(FPDF_FORMFILLINFO * pThis,FPDF_PAGE page,double left,double top,double right,double bottom)113*3ac0a46fSAndroid Build Coastguard Worker void InvalidateStub(FPDF_FORMFILLINFO* pThis,
114*3ac0a46fSAndroid Build Coastguard Worker                     FPDF_PAGE page,
115*3ac0a46fSAndroid Build Coastguard Worker                     double left,
116*3ac0a46fSAndroid Build Coastguard Worker                     double top,
117*3ac0a46fSAndroid Build Coastguard Worker                     double right,
118*3ac0a46fSAndroid Build Coastguard Worker                     double bottom) {}
119*3ac0a46fSAndroid Build Coastguard Worker 
OutputSelectedRectStub(FPDF_FORMFILLINFO * pThis,FPDF_PAGE page,double left,double top,double right,double bottom)120*3ac0a46fSAndroid Build Coastguard Worker void OutputSelectedRectStub(FPDF_FORMFILLINFO* pThis,
121*3ac0a46fSAndroid Build Coastguard Worker                             FPDF_PAGE page,
122*3ac0a46fSAndroid Build Coastguard Worker                             double left,
123*3ac0a46fSAndroid Build Coastguard Worker                             double top,
124*3ac0a46fSAndroid Build Coastguard Worker                             double right,
125*3ac0a46fSAndroid Build Coastguard Worker                             double bottom) {}
126*3ac0a46fSAndroid Build Coastguard Worker 
SetCursorStub(FPDF_FORMFILLINFO * pThis,int nCursorType)127*3ac0a46fSAndroid Build Coastguard Worker void SetCursorStub(FPDF_FORMFILLINFO* pThis, int nCursorType) {}
128*3ac0a46fSAndroid Build Coastguard Worker 
GetLocalTimeStub(FPDF_FORMFILLINFO * pThis)129*3ac0a46fSAndroid Build Coastguard Worker FPDF_SYSTEMTIME GetLocalTimeStub(FPDF_FORMFILLINFO* pThis) {
130*3ac0a46fSAndroid Build Coastguard Worker   return {122, 11, 6, 28, 12, 59, 59, 500};
131*3ac0a46fSAndroid Build Coastguard Worker }
132*3ac0a46fSAndroid Build Coastguard Worker 
OnChangeStub(FPDF_FORMFILLINFO * pThis)133*3ac0a46fSAndroid Build Coastguard Worker void OnChangeStub(FPDF_FORMFILLINFO* pThis) {}
134*3ac0a46fSAndroid Build Coastguard Worker 
GetCurrentPageStub(FPDF_FORMFILLINFO * pThis,FPDF_DOCUMENT document)135*3ac0a46fSAndroid Build Coastguard Worker FPDF_PAGE GetCurrentPageStub(FPDF_FORMFILLINFO* pThis, FPDF_DOCUMENT document) {
136*3ac0a46fSAndroid Build Coastguard Worker   return GetPageTrampoline(pThis, document, 0);
137*3ac0a46fSAndroid Build Coastguard Worker }
138*3ac0a46fSAndroid Build Coastguard Worker 
GetRotationStub(FPDF_FORMFILLINFO * pThis,FPDF_PAGE page)139*3ac0a46fSAndroid Build Coastguard Worker int GetRotationStub(FPDF_FORMFILLINFO* pThis, FPDF_PAGE page) {
140*3ac0a46fSAndroid Build Coastguard Worker   return 0;
141*3ac0a46fSAndroid Build Coastguard Worker }
142*3ac0a46fSAndroid Build Coastguard Worker 
ExecuteNamedActionStub(FPDF_FORMFILLINFO * pThis,FPDF_BYTESTRING name)143*3ac0a46fSAndroid Build Coastguard Worker void ExecuteNamedActionStub(FPDF_FORMFILLINFO* pThis, FPDF_BYTESTRING name) {}
144*3ac0a46fSAndroid Build Coastguard Worker 
SetTextFieldFocusStub(FPDF_FORMFILLINFO * pThis,FPDF_WIDESTRING value,FPDF_DWORD valueLen,FPDF_BOOL is_focus)145*3ac0a46fSAndroid Build Coastguard Worker void SetTextFieldFocusStub(FPDF_FORMFILLINFO* pThis,
146*3ac0a46fSAndroid Build Coastguard Worker                            FPDF_WIDESTRING value,
147*3ac0a46fSAndroid Build Coastguard Worker                            FPDF_DWORD valueLen,
148*3ac0a46fSAndroid Build Coastguard Worker                            FPDF_BOOL is_focus) {}
149*3ac0a46fSAndroid Build Coastguard Worker 
150*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_XFA
DisplayCaretStub(FPDF_FORMFILLINFO * pThis,FPDF_PAGE page,FPDF_BOOL bVisible,double left,double top,double right,double bottom)151*3ac0a46fSAndroid Build Coastguard Worker void DisplayCaretStub(FPDF_FORMFILLINFO* pThis,
152*3ac0a46fSAndroid Build Coastguard Worker                       FPDF_PAGE page,
153*3ac0a46fSAndroid Build Coastguard Worker                       FPDF_BOOL bVisible,
154*3ac0a46fSAndroid Build Coastguard Worker                       double left,
155*3ac0a46fSAndroid Build Coastguard Worker                       double top,
156*3ac0a46fSAndroid Build Coastguard Worker                       double right,
157*3ac0a46fSAndroid Build Coastguard Worker                       double bottom) {}
158*3ac0a46fSAndroid Build Coastguard Worker 
GetCurrentPageIndexStub(FPDF_FORMFILLINFO * pThis,FPDF_DOCUMENT document)159*3ac0a46fSAndroid Build Coastguard Worker int GetCurrentPageIndexStub(FPDF_FORMFILLINFO* pThis, FPDF_DOCUMENT document) {
160*3ac0a46fSAndroid Build Coastguard Worker   return 0;
161*3ac0a46fSAndroid Build Coastguard Worker }
162*3ac0a46fSAndroid Build Coastguard Worker 
SetCurrentPageStub(FPDF_FORMFILLINFO * pThis,FPDF_DOCUMENT document,int iCurPage)163*3ac0a46fSAndroid Build Coastguard Worker void SetCurrentPageStub(FPDF_FORMFILLINFO* pThis,
164*3ac0a46fSAndroid Build Coastguard Worker                         FPDF_DOCUMENT document,
165*3ac0a46fSAndroid Build Coastguard Worker                         int iCurPage) {}
166*3ac0a46fSAndroid Build Coastguard Worker 
GotoURLStub(FPDF_FORMFILLINFO * pThis,FPDF_DOCUMENT document,FPDF_WIDESTRING wsURL)167*3ac0a46fSAndroid Build Coastguard Worker void GotoURLStub(FPDF_FORMFILLINFO* pThis,
168*3ac0a46fSAndroid Build Coastguard Worker                  FPDF_DOCUMENT document,
169*3ac0a46fSAndroid Build Coastguard Worker                  FPDF_WIDESTRING wsURL) {}
170*3ac0a46fSAndroid Build Coastguard Worker 
GetPageViewRectStub(FPDF_FORMFILLINFO * pThis,FPDF_PAGE page,double * left,double * top,double * right,double * bottom)171*3ac0a46fSAndroid Build Coastguard Worker void GetPageViewRectStub(FPDF_FORMFILLINFO* pThis,
172*3ac0a46fSAndroid Build Coastguard Worker                          FPDF_PAGE page,
173*3ac0a46fSAndroid Build Coastguard Worker                          double* left,
174*3ac0a46fSAndroid Build Coastguard Worker                          double* top,
175*3ac0a46fSAndroid Build Coastguard Worker                          double* right,
176*3ac0a46fSAndroid Build Coastguard Worker                          double* bottom) {
177*3ac0a46fSAndroid Build Coastguard Worker   *left = 0.0;
178*3ac0a46fSAndroid Build Coastguard Worker   *top = 0.0;
179*3ac0a46fSAndroid Build Coastguard Worker   *right = 512.0;
180*3ac0a46fSAndroid Build Coastguard Worker   *bottom = 512.0;
181*3ac0a46fSAndroid Build Coastguard Worker }
182*3ac0a46fSAndroid Build Coastguard Worker 
PageEventStub(FPDF_FORMFILLINFO * pThis,int page_count,FPDF_DWORD event_type)183*3ac0a46fSAndroid Build Coastguard Worker void PageEventStub(FPDF_FORMFILLINFO* pThis,
184*3ac0a46fSAndroid Build Coastguard Worker                    int page_count,
185*3ac0a46fSAndroid Build Coastguard Worker                    FPDF_DWORD event_type) {}
186*3ac0a46fSAndroid Build Coastguard Worker 
PopupMenuStub(FPDF_FORMFILLINFO * pThis,FPDF_PAGE page,FPDF_WIDGET hWidget,int menuFlag,float x,float y)187*3ac0a46fSAndroid Build Coastguard Worker FPDF_BOOL PopupMenuStub(FPDF_FORMFILLINFO* pThis,
188*3ac0a46fSAndroid Build Coastguard Worker                         FPDF_PAGE page,
189*3ac0a46fSAndroid Build Coastguard Worker                         FPDF_WIDGET hWidget,
190*3ac0a46fSAndroid Build Coastguard Worker                         int menuFlag,
191*3ac0a46fSAndroid Build Coastguard Worker                         float x,
192*3ac0a46fSAndroid Build Coastguard Worker                         float y) {
193*3ac0a46fSAndroid Build Coastguard Worker   return true;
194*3ac0a46fSAndroid Build Coastguard Worker }
195*3ac0a46fSAndroid Build Coastguard Worker 
OpenFileStub(FPDF_FORMFILLINFO * pThis,int fileFlag,FPDF_WIDESTRING wsURL,const char * mode)196*3ac0a46fSAndroid Build Coastguard Worker FPDF_FILEHANDLER* OpenFileStub(FPDF_FORMFILLINFO* pThis,
197*3ac0a46fSAndroid Build Coastguard Worker                                int fileFlag,
198*3ac0a46fSAndroid Build Coastguard Worker                                FPDF_WIDESTRING wsURL,
199*3ac0a46fSAndroid Build Coastguard Worker                                const char* mode) {
200*3ac0a46fSAndroid Build Coastguard Worker   return nullptr;
201*3ac0a46fSAndroid Build Coastguard Worker }
202*3ac0a46fSAndroid Build Coastguard Worker 
EmailToStub(FPDF_FORMFILLINFO * pThis,FPDF_FILEHANDLER * fileHandler,FPDF_WIDESTRING pTo,FPDF_WIDESTRING pSubject,FPDF_WIDESTRING pCC,FPDF_WIDESTRING pBcc,FPDF_WIDESTRING pMsg)203*3ac0a46fSAndroid Build Coastguard Worker void EmailToStub(FPDF_FORMFILLINFO* pThis,
204*3ac0a46fSAndroid Build Coastguard Worker                  FPDF_FILEHANDLER* fileHandler,
205*3ac0a46fSAndroid Build Coastguard Worker                  FPDF_WIDESTRING pTo,
206*3ac0a46fSAndroid Build Coastguard Worker                  FPDF_WIDESTRING pSubject,
207*3ac0a46fSAndroid Build Coastguard Worker                  FPDF_WIDESTRING pCC,
208*3ac0a46fSAndroid Build Coastguard Worker                  FPDF_WIDESTRING pBcc,
209*3ac0a46fSAndroid Build Coastguard Worker                  FPDF_WIDESTRING pMsg) {}
210*3ac0a46fSAndroid Build Coastguard Worker 
UploadToStub(FPDF_FORMFILLINFO * pThis,FPDF_FILEHANDLER * fileHandler,int fileFlag,FPDF_WIDESTRING uploadTo)211*3ac0a46fSAndroid Build Coastguard Worker void UploadToStub(FPDF_FORMFILLINFO* pThis,
212*3ac0a46fSAndroid Build Coastguard Worker                   FPDF_FILEHANDLER* fileHandler,
213*3ac0a46fSAndroid Build Coastguard Worker                   int fileFlag,
214*3ac0a46fSAndroid Build Coastguard Worker                   FPDF_WIDESTRING uploadTo) {}
215*3ac0a46fSAndroid Build Coastguard Worker 
GetPlatformStub(FPDF_FORMFILLINFO * pThis,void * platform,int length)216*3ac0a46fSAndroid Build Coastguard Worker int GetPlatformStub(FPDF_FORMFILLINFO* pThis, void* platform, int length) {
217*3ac0a46fSAndroid Build Coastguard Worker   return 0;
218*3ac0a46fSAndroid Build Coastguard Worker }
219*3ac0a46fSAndroid Build Coastguard Worker 
GetLanguageStub(FPDF_FORMFILLINFO * pThis,void * language,int length)220*3ac0a46fSAndroid Build Coastguard Worker int GetLanguageStub(FPDF_FORMFILLINFO* pThis, void* language, int length) {
221*3ac0a46fSAndroid Build Coastguard Worker   return 0;
222*3ac0a46fSAndroid Build Coastguard Worker }
223*3ac0a46fSAndroid Build Coastguard Worker 
DownloadFromURLStub(FPDF_FORMFILLINFO * pThis,FPDF_WIDESTRING URL)224*3ac0a46fSAndroid Build Coastguard Worker FPDF_FILEHANDLER* DownloadFromURLStub(FPDF_FORMFILLINFO* pThis,
225*3ac0a46fSAndroid Build Coastguard Worker                                       FPDF_WIDESTRING URL) {
226*3ac0a46fSAndroid Build Coastguard Worker   static const char kString[] = "<body>secrets</body>";
227*3ac0a46fSAndroid Build Coastguard Worker   static FPDF_FILEHANDLER kFakeFileHandler = {
228*3ac0a46fSAndroid Build Coastguard Worker       nullptr,
229*3ac0a46fSAndroid Build Coastguard Worker       [](void*) -> void {},
230*3ac0a46fSAndroid Build Coastguard Worker       [](void*) -> FPDF_DWORD { return sizeof(kString); },
231*3ac0a46fSAndroid Build Coastguard Worker       [](void*, FPDF_DWORD off, void* buffer, FPDF_DWORD size) -> FPDF_RESULT {
232*3ac0a46fSAndroid Build Coastguard Worker         memcpy(buffer, kString, std::min<size_t>(size, sizeof(kString)));
233*3ac0a46fSAndroid Build Coastguard Worker         return 0;
234*3ac0a46fSAndroid Build Coastguard Worker       },
235*3ac0a46fSAndroid Build Coastguard Worker       [](void*, FPDF_DWORD, const void*, FPDF_DWORD) -> FPDF_RESULT {
236*3ac0a46fSAndroid Build Coastguard Worker         return -1;
237*3ac0a46fSAndroid Build Coastguard Worker       },
238*3ac0a46fSAndroid Build Coastguard Worker       [](void*) -> FPDF_RESULT { return 0; },
239*3ac0a46fSAndroid Build Coastguard Worker       [](void*, FPDF_DWORD) -> FPDF_RESULT { return 0; }};
240*3ac0a46fSAndroid Build Coastguard Worker   return &kFakeFileHandler;
241*3ac0a46fSAndroid Build Coastguard Worker }
242*3ac0a46fSAndroid Build Coastguard Worker 
PostRequestURLStub(FPDF_FORMFILLINFO * pThis,FPDF_WIDESTRING wsURL,FPDF_WIDESTRING wsData,FPDF_WIDESTRING wsContentType,FPDF_WIDESTRING wsEncode,FPDF_WIDESTRING wsHeader,FPDF_BSTR * response)243*3ac0a46fSAndroid Build Coastguard Worker FPDF_BOOL PostRequestURLStub(FPDF_FORMFILLINFO* pThis,
244*3ac0a46fSAndroid Build Coastguard Worker                              FPDF_WIDESTRING wsURL,
245*3ac0a46fSAndroid Build Coastguard Worker                              FPDF_WIDESTRING wsData,
246*3ac0a46fSAndroid Build Coastguard Worker                              FPDF_WIDESTRING wsContentType,
247*3ac0a46fSAndroid Build Coastguard Worker                              FPDF_WIDESTRING wsEncode,
248*3ac0a46fSAndroid Build Coastguard Worker                              FPDF_WIDESTRING wsHeader,
249*3ac0a46fSAndroid Build Coastguard Worker                              FPDF_BSTR* response) {
250*3ac0a46fSAndroid Build Coastguard Worker   const char kString[] = "p\0o\0s\0t\0e\0d\0";
251*3ac0a46fSAndroid Build Coastguard Worker   FPDF_BStr_Set(response, kString, sizeof(kString) - 1);
252*3ac0a46fSAndroid Build Coastguard Worker   return true;
253*3ac0a46fSAndroid Build Coastguard Worker }
254*3ac0a46fSAndroid Build Coastguard Worker 
PutRequestURLStub(FPDF_FORMFILLINFO * pThis,FPDF_WIDESTRING wsURL,FPDF_WIDESTRING wsData,FPDF_WIDESTRING wsEncode)255*3ac0a46fSAndroid Build Coastguard Worker FPDF_BOOL PutRequestURLStub(FPDF_FORMFILLINFO* pThis,
256*3ac0a46fSAndroid Build Coastguard Worker                             FPDF_WIDESTRING wsURL,
257*3ac0a46fSAndroid Build Coastguard Worker                             FPDF_WIDESTRING wsData,
258*3ac0a46fSAndroid Build Coastguard Worker                             FPDF_WIDESTRING wsEncode) {
259*3ac0a46fSAndroid Build Coastguard Worker   return true;
260*3ac0a46fSAndroid Build Coastguard Worker }
261*3ac0a46fSAndroid Build Coastguard Worker #endif  // PDF_ENABLE_XFA
262*3ac0a46fSAndroid Build Coastguard Worker 
263*3ac0a46fSAndroid Build Coastguard Worker }  // namespace
264*3ac0a46fSAndroid Build Coastguard Worker 
EmbedderTest()265*3ac0a46fSAndroid Build Coastguard Worker EmbedderTest::EmbedderTest()
266*3ac0a46fSAndroid Build Coastguard Worker     : default_delegate_(std::make_unique<EmbedderTest::Delegate>()),
267*3ac0a46fSAndroid Build Coastguard Worker       delegate_(default_delegate_.get()) {
268*3ac0a46fSAndroid Build Coastguard Worker   FPDF_FILEWRITE::version = 1;
269*3ac0a46fSAndroid Build Coastguard Worker   FPDF_FILEWRITE::WriteBlock = WriteBlockCallback;
270*3ac0a46fSAndroid Build Coastguard Worker }
271*3ac0a46fSAndroid Build Coastguard Worker 
272*3ac0a46fSAndroid Build Coastguard Worker EmbedderTest::~EmbedderTest() = default;
273*3ac0a46fSAndroid Build Coastguard Worker 
SetUp()274*3ac0a46fSAndroid Build Coastguard Worker void EmbedderTest::SetUp() {
275*3ac0a46fSAndroid Build Coastguard Worker   UNSUPPORT_INFO* info = static_cast<UNSUPPORT_INFO*>(this);
276*3ac0a46fSAndroid Build Coastguard Worker   memset(info, 0, sizeof(UNSUPPORT_INFO));
277*3ac0a46fSAndroid Build Coastguard Worker   info->version = 1;
278*3ac0a46fSAndroid Build Coastguard Worker   info->FSDK_UnSupport_Handler = UnsupportedHandlerTrampoline;
279*3ac0a46fSAndroid Build Coastguard Worker   FSDK_SetUnSpObjProcessHandler(info);
280*3ac0a46fSAndroid Build Coastguard Worker }
281*3ac0a46fSAndroid Build Coastguard Worker 
TearDown()282*3ac0a46fSAndroid Build Coastguard Worker void EmbedderTest::TearDown() {
283*3ac0a46fSAndroid Build Coastguard Worker   // Use an EXPECT_EQ() here and continue to let TearDown() finish as cleanly as
284*3ac0a46fSAndroid Build Coastguard Worker   // possible. This can fail when an DCHECK test fails in a test case.
285*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, page_map_.size());
286*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, saved_page_map_.size());
287*3ac0a46fSAndroid Build Coastguard Worker   if (document())
288*3ac0a46fSAndroid Build Coastguard Worker     CloseDocument();
289*3ac0a46fSAndroid Build Coastguard Worker }
290*3ac0a46fSAndroid Build Coastguard Worker 
CreateEmptyDocument()291*3ac0a46fSAndroid Build Coastguard Worker void EmbedderTest::CreateEmptyDocument() {
292*3ac0a46fSAndroid Build Coastguard Worker   CreateEmptyDocumentWithoutFormFillEnvironment();
293*3ac0a46fSAndroid Build Coastguard Worker   form_handle_.reset(SetupFormFillEnvironment(
294*3ac0a46fSAndroid Build Coastguard Worker       document(), JavaScriptOption::kEnableJavaScript));
295*3ac0a46fSAndroid Build Coastguard Worker }
296*3ac0a46fSAndroid Build Coastguard Worker 
CreateEmptyDocumentWithoutFormFillEnvironment()297*3ac0a46fSAndroid Build Coastguard Worker void EmbedderTest::CreateEmptyDocumentWithoutFormFillEnvironment() {
298*3ac0a46fSAndroid Build Coastguard Worker   document_.reset(FPDF_CreateNewDocument());
299*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(document_);
300*3ac0a46fSAndroid Build Coastguard Worker }
301*3ac0a46fSAndroid Build Coastguard Worker 
OpenDocument(const std::string & filename)302*3ac0a46fSAndroid Build Coastguard Worker bool EmbedderTest::OpenDocument(const std::string& filename) {
303*3ac0a46fSAndroid Build Coastguard Worker   return OpenDocumentWithOptions(filename, nullptr,
304*3ac0a46fSAndroid Build Coastguard Worker                                  LinearizeOption::kDefaultLinearize,
305*3ac0a46fSAndroid Build Coastguard Worker                                  JavaScriptOption::kEnableJavaScript);
306*3ac0a46fSAndroid Build Coastguard Worker }
307*3ac0a46fSAndroid Build Coastguard Worker 
OpenDocumentLinearized(const std::string & filename)308*3ac0a46fSAndroid Build Coastguard Worker bool EmbedderTest::OpenDocumentLinearized(const std::string& filename) {
309*3ac0a46fSAndroid Build Coastguard Worker   return OpenDocumentWithOptions(filename, nullptr,
310*3ac0a46fSAndroid Build Coastguard Worker                                  LinearizeOption::kMustLinearize,
311*3ac0a46fSAndroid Build Coastguard Worker                                  JavaScriptOption::kEnableJavaScript);
312*3ac0a46fSAndroid Build Coastguard Worker }
313*3ac0a46fSAndroid Build Coastguard Worker 
OpenDocumentWithPassword(const std::string & filename,const char * password)314*3ac0a46fSAndroid Build Coastguard Worker bool EmbedderTest::OpenDocumentWithPassword(const std::string& filename,
315*3ac0a46fSAndroid Build Coastguard Worker                                             const char* password) {
316*3ac0a46fSAndroid Build Coastguard Worker   return OpenDocumentWithOptions(filename, password,
317*3ac0a46fSAndroid Build Coastguard Worker                                  LinearizeOption::kDefaultLinearize,
318*3ac0a46fSAndroid Build Coastguard Worker                                  JavaScriptOption::kEnableJavaScript);
319*3ac0a46fSAndroid Build Coastguard Worker }
320*3ac0a46fSAndroid Build Coastguard Worker 
OpenDocumentWithoutJavaScript(const std::string & filename)321*3ac0a46fSAndroid Build Coastguard Worker bool EmbedderTest::OpenDocumentWithoutJavaScript(const std::string& filename) {
322*3ac0a46fSAndroid Build Coastguard Worker   return OpenDocumentWithOptions(filename, nullptr,
323*3ac0a46fSAndroid Build Coastguard Worker                                  LinearizeOption::kDefaultLinearize,
324*3ac0a46fSAndroid Build Coastguard Worker                                  JavaScriptOption::kDisableJavaScript);
325*3ac0a46fSAndroid Build Coastguard Worker }
326*3ac0a46fSAndroid Build Coastguard Worker 
OpenDocumentWithOptions(const std::string & filename,const char * password,LinearizeOption linearize_option,JavaScriptOption javascript_option)327*3ac0a46fSAndroid Build Coastguard Worker bool EmbedderTest::OpenDocumentWithOptions(const std::string& filename,
328*3ac0a46fSAndroid Build Coastguard Worker                                            const char* password,
329*3ac0a46fSAndroid Build Coastguard Worker                                            LinearizeOption linearize_option,
330*3ac0a46fSAndroid Build Coastguard Worker                                            JavaScriptOption javascript_option) {
331*3ac0a46fSAndroid Build Coastguard Worker   std::string file_path;
332*3ac0a46fSAndroid Build Coastguard Worker   if (!PathService::GetTestFilePath(filename, &file_path))
333*3ac0a46fSAndroid Build Coastguard Worker     return false;
334*3ac0a46fSAndroid Build Coastguard Worker 
335*3ac0a46fSAndroid Build Coastguard Worker   file_contents_ = GetFileContents(file_path.c_str(), &file_length_);
336*3ac0a46fSAndroid Build Coastguard Worker   if (!file_contents_)
337*3ac0a46fSAndroid Build Coastguard Worker     return false;
338*3ac0a46fSAndroid Build Coastguard Worker 
339*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(!loader_);
340*3ac0a46fSAndroid Build Coastguard Worker   loader_ = std::make_unique<TestLoader>(
341*3ac0a46fSAndroid Build Coastguard Worker       pdfium::make_span(file_contents_.get(), file_length_));
342*3ac0a46fSAndroid Build Coastguard Worker 
343*3ac0a46fSAndroid Build Coastguard Worker   memset(&file_access_, 0, sizeof(file_access_));
344*3ac0a46fSAndroid Build Coastguard Worker   file_access_.m_FileLen = static_cast<unsigned long>(file_length_);
345*3ac0a46fSAndroid Build Coastguard Worker   file_access_.m_GetBlock = TestLoader::GetBlock;
346*3ac0a46fSAndroid Build Coastguard Worker   file_access_.m_Param = loader_.get();
347*3ac0a46fSAndroid Build Coastguard Worker 
348*3ac0a46fSAndroid Build Coastguard Worker   fake_file_access_ = std::make_unique<FakeFileAccess>(&file_access_);
349*3ac0a46fSAndroid Build Coastguard Worker   return OpenDocumentHelper(password, linearize_option, javascript_option,
350*3ac0a46fSAndroid Build Coastguard Worker                             fake_file_access_.get(), &document_, &avail_,
351*3ac0a46fSAndroid Build Coastguard Worker                             &form_handle_);
352*3ac0a46fSAndroid Build Coastguard Worker }
353*3ac0a46fSAndroid Build Coastguard Worker 
OpenDocumentHelper(const char * password,LinearizeOption linearize_option,JavaScriptOption javascript_option,FakeFileAccess * network_simulator,ScopedFPDFDocument * document,ScopedFPDFAvail * avail,ScopedFPDFFormHandle * form_handle)354*3ac0a46fSAndroid Build Coastguard Worker bool EmbedderTest::OpenDocumentHelper(const char* password,
355*3ac0a46fSAndroid Build Coastguard Worker                                       LinearizeOption linearize_option,
356*3ac0a46fSAndroid Build Coastguard Worker                                       JavaScriptOption javascript_option,
357*3ac0a46fSAndroid Build Coastguard Worker                                       FakeFileAccess* network_simulator,
358*3ac0a46fSAndroid Build Coastguard Worker                                       ScopedFPDFDocument* document,
359*3ac0a46fSAndroid Build Coastguard Worker                                       ScopedFPDFAvail* avail,
360*3ac0a46fSAndroid Build Coastguard Worker                                       ScopedFPDFFormHandle* form_handle) {
361*3ac0a46fSAndroid Build Coastguard Worker   network_simulator->AddSegment(0, 1024);
362*3ac0a46fSAndroid Build Coastguard Worker   network_simulator->SetRequestedDataAvailable();
363*3ac0a46fSAndroid Build Coastguard Worker   avail->reset(FPDFAvail_Create(network_simulator->GetFileAvail(),
364*3ac0a46fSAndroid Build Coastguard Worker                                 network_simulator->GetFileAccess()));
365*3ac0a46fSAndroid Build Coastguard Worker   FPDF_AVAIL avail_ptr = avail->get();
366*3ac0a46fSAndroid Build Coastguard Worker   FPDF_DOCUMENT document_ptr = nullptr;
367*3ac0a46fSAndroid Build Coastguard Worker   if (FPDFAvail_IsLinearized(avail_ptr) == PDF_LINEARIZED) {
368*3ac0a46fSAndroid Build Coastguard Worker     int32_t nRet = PDF_DATA_NOTAVAIL;
369*3ac0a46fSAndroid Build Coastguard Worker     while (nRet == PDF_DATA_NOTAVAIL) {
370*3ac0a46fSAndroid Build Coastguard Worker       network_simulator->SetRequestedDataAvailable();
371*3ac0a46fSAndroid Build Coastguard Worker       nRet = FPDFAvail_IsDocAvail(avail_ptr,
372*3ac0a46fSAndroid Build Coastguard Worker                                   network_simulator->GetDownloadHints());
373*3ac0a46fSAndroid Build Coastguard Worker     }
374*3ac0a46fSAndroid Build Coastguard Worker     if (nRet == PDF_DATA_ERROR)
375*3ac0a46fSAndroid Build Coastguard Worker       return false;
376*3ac0a46fSAndroid Build Coastguard Worker 
377*3ac0a46fSAndroid Build Coastguard Worker     document->reset(FPDFAvail_GetDocument(avail_ptr, password));
378*3ac0a46fSAndroid Build Coastguard Worker     document_ptr = document->get();
379*3ac0a46fSAndroid Build Coastguard Worker     if (!document_ptr)
380*3ac0a46fSAndroid Build Coastguard Worker       return false;
381*3ac0a46fSAndroid Build Coastguard Worker 
382*3ac0a46fSAndroid Build Coastguard Worker     nRet = PDF_DATA_NOTAVAIL;
383*3ac0a46fSAndroid Build Coastguard Worker     while (nRet == PDF_DATA_NOTAVAIL) {
384*3ac0a46fSAndroid Build Coastguard Worker       network_simulator->SetRequestedDataAvailable();
385*3ac0a46fSAndroid Build Coastguard Worker       nRet = FPDFAvail_IsFormAvail(avail_ptr,
386*3ac0a46fSAndroid Build Coastguard Worker                                    network_simulator->GetDownloadHints());
387*3ac0a46fSAndroid Build Coastguard Worker     }
388*3ac0a46fSAndroid Build Coastguard Worker     if (nRet == PDF_FORM_ERROR)
389*3ac0a46fSAndroid Build Coastguard Worker       return false;
390*3ac0a46fSAndroid Build Coastguard Worker 
391*3ac0a46fSAndroid Build Coastguard Worker     int page_count = FPDF_GetPageCount(document_ptr);
392*3ac0a46fSAndroid Build Coastguard Worker     for (int i = 0; i < page_count; ++i) {
393*3ac0a46fSAndroid Build Coastguard Worker       nRet = PDF_DATA_NOTAVAIL;
394*3ac0a46fSAndroid Build Coastguard Worker       while (nRet == PDF_DATA_NOTAVAIL) {
395*3ac0a46fSAndroid Build Coastguard Worker         network_simulator->SetRequestedDataAvailable();
396*3ac0a46fSAndroid Build Coastguard Worker         nRet = FPDFAvail_IsPageAvail(avail_ptr, i,
397*3ac0a46fSAndroid Build Coastguard Worker                                      network_simulator->GetDownloadHints());
398*3ac0a46fSAndroid Build Coastguard Worker       }
399*3ac0a46fSAndroid Build Coastguard Worker       if (nRet == PDF_DATA_ERROR)
400*3ac0a46fSAndroid Build Coastguard Worker         return false;
401*3ac0a46fSAndroid Build Coastguard Worker     }
402*3ac0a46fSAndroid Build Coastguard Worker   } else {
403*3ac0a46fSAndroid Build Coastguard Worker     if (linearize_option == LinearizeOption::kMustLinearize)
404*3ac0a46fSAndroid Build Coastguard Worker       return false;
405*3ac0a46fSAndroid Build Coastguard Worker     network_simulator->SetWholeFileAvailable();
406*3ac0a46fSAndroid Build Coastguard Worker     document->reset(
407*3ac0a46fSAndroid Build Coastguard Worker         FPDF_LoadCustomDocument(network_simulator->GetFileAccess(), password));
408*3ac0a46fSAndroid Build Coastguard Worker     document_ptr = document->get();
409*3ac0a46fSAndroid Build Coastguard Worker     if (!document_ptr)
410*3ac0a46fSAndroid Build Coastguard Worker       return false;
411*3ac0a46fSAndroid Build Coastguard Worker   }
412*3ac0a46fSAndroid Build Coastguard Worker   form_handle->reset(SetupFormFillEnvironment(document_ptr, javascript_option));
413*3ac0a46fSAndroid Build Coastguard Worker 
414*3ac0a46fSAndroid Build Coastguard Worker   int doc_type = FPDF_GetFormType(document_ptr);
415*3ac0a46fSAndroid Build Coastguard Worker   if (doc_type == FORMTYPE_XFA_FULL || doc_type == FORMTYPE_XFA_FOREGROUND)
416*3ac0a46fSAndroid Build Coastguard Worker     FPDF_LoadXFA(document_ptr);
417*3ac0a46fSAndroid Build Coastguard Worker 
418*3ac0a46fSAndroid Build Coastguard Worker   (void)FPDF_GetDocPermissions(document_ptr);
419*3ac0a46fSAndroid Build Coastguard Worker   return true;
420*3ac0a46fSAndroid Build Coastguard Worker }
421*3ac0a46fSAndroid Build Coastguard Worker 
CloseDocument()422*3ac0a46fSAndroid Build Coastguard Worker void EmbedderTest::CloseDocument() {
423*3ac0a46fSAndroid Build Coastguard Worker   FORM_DoDocumentAAction(form_handle(), FPDFDOC_AACTION_WC);
424*3ac0a46fSAndroid Build Coastguard Worker   form_handle_.reset();
425*3ac0a46fSAndroid Build Coastguard Worker   document_.reset();
426*3ac0a46fSAndroid Build Coastguard Worker   avail_.reset();
427*3ac0a46fSAndroid Build Coastguard Worker   fake_file_access_.reset();
428*3ac0a46fSAndroid Build Coastguard Worker   memset(&file_access_, 0, sizeof(file_access_));
429*3ac0a46fSAndroid Build Coastguard Worker   loader_.reset();
430*3ac0a46fSAndroid Build Coastguard Worker   file_contents_.reset();
431*3ac0a46fSAndroid Build Coastguard Worker }
432*3ac0a46fSAndroid Build Coastguard Worker 
SetupFormFillEnvironment(FPDF_DOCUMENT doc,JavaScriptOption javascript_option)433*3ac0a46fSAndroid Build Coastguard Worker FPDF_FORMHANDLE EmbedderTest::SetupFormFillEnvironment(
434*3ac0a46fSAndroid Build Coastguard Worker     FPDF_DOCUMENT doc,
435*3ac0a46fSAndroid Build Coastguard Worker     JavaScriptOption javascript_option) {
436*3ac0a46fSAndroid Build Coastguard Worker   IPDF_JSPLATFORM* platform = static_cast<IPDF_JSPLATFORM*>(this);
437*3ac0a46fSAndroid Build Coastguard Worker   memset(platform, '\0', sizeof(IPDF_JSPLATFORM));
438*3ac0a46fSAndroid Build Coastguard Worker   platform->version = 3;
439*3ac0a46fSAndroid Build Coastguard Worker   platform->app_alert = AlertTrampoline;
440*3ac0a46fSAndroid Build Coastguard Worker 
441*3ac0a46fSAndroid Build Coastguard Worker   FPDF_FORMFILLINFO* formfillinfo = static_cast<FPDF_FORMFILLINFO*>(this);
442*3ac0a46fSAndroid Build Coastguard Worker   memset(formfillinfo, 0, sizeof(FPDF_FORMFILLINFO));
443*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->version = form_fill_info_version_;
444*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_Invalidate = InvalidateStub;
445*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_OutputSelectedRect = OutputSelectedRectStub;
446*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_SetCursor = SetCursorStub;
447*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_SetTimer = SetTimerTrampoline;
448*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_KillTimer = KillTimerTrampoline;
449*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_GetLocalTime = GetLocalTimeStub;
450*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_OnChange = OnChangeStub;
451*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_GetPage = GetPageTrampoline;
452*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_GetCurrentPage = GetCurrentPageStub;
453*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_GetRotation = GetRotationStub;
454*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_ExecuteNamedAction = ExecuteNamedActionStub;
455*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_SetTextFieldFocus = SetTextFieldFocusStub;
456*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_DoURIAction = DoURIActionTrampoline;
457*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_DoGoToAction = DoGoToActionTrampoline;
458*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_XFA
459*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_DisplayCaret = DisplayCaretStub;
460*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_GetCurrentPageIndex = GetCurrentPageIndexStub;
461*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_SetCurrentPage = SetCurrentPageStub;
462*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_GotoURL = GotoURLStub;
463*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_GetPageViewRect = GetPageViewRectStub;
464*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_PageEvent = PageEventStub;
465*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_PopupMenu = PopupMenuStub;
466*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_OpenFile = OpenFileStub;
467*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_EmailTo = EmailToStub;
468*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_UploadTo = UploadToStub;
469*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_GetPlatform = GetPlatformStub;
470*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_GetLanguage = GetLanguageStub;
471*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_DownloadFromURL = DownloadFromURLStub;
472*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_PostRequestURL = PostRequestURLStub;
473*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_PutRequestURL = PutRequestURLStub;
474*3ac0a46fSAndroid Build Coastguard Worker #endif  // PDF_ENABLE_XFA
475*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_OnFocusChange = OnFocusChangeTrampoline;
476*3ac0a46fSAndroid Build Coastguard Worker   formfillinfo->FFI_DoURIActionWithKeyboardModifier =
477*3ac0a46fSAndroid Build Coastguard Worker       DoURIActionWithKeyboardModifierTrampoline;
478*3ac0a46fSAndroid Build Coastguard Worker 
479*3ac0a46fSAndroid Build Coastguard Worker   if (javascript_option == JavaScriptOption::kEnableJavaScript)
480*3ac0a46fSAndroid Build Coastguard Worker     formfillinfo->m_pJsPlatform = platform;
481*3ac0a46fSAndroid Build Coastguard Worker 
482*3ac0a46fSAndroid Build Coastguard Worker   FPDF_FORMHANDLE form_handle =
483*3ac0a46fSAndroid Build Coastguard Worker       FPDFDOC_InitFormFillEnvironment(doc, formfillinfo);
484*3ac0a46fSAndroid Build Coastguard Worker   SetInitialFormFieldHighlight(form_handle);
485*3ac0a46fSAndroid Build Coastguard Worker   return form_handle;
486*3ac0a46fSAndroid Build Coastguard Worker }
487*3ac0a46fSAndroid Build Coastguard Worker 
DoOpenActions()488*3ac0a46fSAndroid Build Coastguard Worker void EmbedderTest::DoOpenActions() {
489*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(form_handle());
490*3ac0a46fSAndroid Build Coastguard Worker   FORM_DoDocumentJSAction(form_handle());
491*3ac0a46fSAndroid Build Coastguard Worker   FORM_DoDocumentOpenAction(form_handle());
492*3ac0a46fSAndroid Build Coastguard Worker }
493*3ac0a46fSAndroid Build Coastguard Worker 
GetFirstPageNum()494*3ac0a46fSAndroid Build Coastguard Worker int EmbedderTest::GetFirstPageNum() {
495*3ac0a46fSAndroid Build Coastguard Worker   int first_page = FPDFAvail_GetFirstPageNum(document());
496*3ac0a46fSAndroid Build Coastguard Worker   (void)FPDFAvail_IsPageAvail(avail(), first_page,
497*3ac0a46fSAndroid Build Coastguard Worker                               fake_file_access_->GetDownloadHints());
498*3ac0a46fSAndroid Build Coastguard Worker   return first_page;
499*3ac0a46fSAndroid Build Coastguard Worker }
500*3ac0a46fSAndroid Build Coastguard Worker 
GetPageCount()501*3ac0a46fSAndroid Build Coastguard Worker int EmbedderTest::GetPageCount() {
502*3ac0a46fSAndroid Build Coastguard Worker   int page_count = FPDF_GetPageCount(document());
503*3ac0a46fSAndroid Build Coastguard Worker   for (int i = 0; i < page_count; ++i)
504*3ac0a46fSAndroid Build Coastguard Worker     (void)FPDFAvail_IsPageAvail(avail(), i,
505*3ac0a46fSAndroid Build Coastguard Worker                                 fake_file_access_->GetDownloadHints());
506*3ac0a46fSAndroid Build Coastguard Worker   return page_count;
507*3ac0a46fSAndroid Build Coastguard Worker }
508*3ac0a46fSAndroid Build Coastguard Worker 
LoadPage(int page_number)509*3ac0a46fSAndroid Build Coastguard Worker FPDF_PAGE EmbedderTest::LoadPage(int page_number) {
510*3ac0a46fSAndroid Build Coastguard Worker   return LoadPageCommon(page_number, true);
511*3ac0a46fSAndroid Build Coastguard Worker }
512*3ac0a46fSAndroid Build Coastguard Worker 
LoadPageNoEvents(int page_number)513*3ac0a46fSAndroid Build Coastguard Worker FPDF_PAGE EmbedderTest::LoadPageNoEvents(int page_number) {
514*3ac0a46fSAndroid Build Coastguard Worker   return LoadPageCommon(page_number, false);
515*3ac0a46fSAndroid Build Coastguard Worker }
516*3ac0a46fSAndroid Build Coastguard Worker 
LoadPageCommon(int page_number,bool do_events)517*3ac0a46fSAndroid Build Coastguard Worker FPDF_PAGE EmbedderTest::LoadPageCommon(int page_number, bool do_events) {
518*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(form_handle());
519*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(page_number >= 0);
520*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(!pdfium::Contains(page_map_, page_number));
521*3ac0a46fSAndroid Build Coastguard Worker 
522*3ac0a46fSAndroid Build Coastguard Worker   FPDF_PAGE page = FPDF_LoadPage(document(), page_number);
523*3ac0a46fSAndroid Build Coastguard Worker   if (!page)
524*3ac0a46fSAndroid Build Coastguard Worker     return nullptr;
525*3ac0a46fSAndroid Build Coastguard Worker 
526*3ac0a46fSAndroid Build Coastguard Worker   if (do_events) {
527*3ac0a46fSAndroid Build Coastguard Worker     FORM_OnAfterLoadPage(page, form_handle());
528*3ac0a46fSAndroid Build Coastguard Worker     FORM_DoPageAAction(page, form_handle(), FPDFPAGE_AACTION_OPEN);
529*3ac0a46fSAndroid Build Coastguard Worker   }
530*3ac0a46fSAndroid Build Coastguard Worker   page_map_[page_number] = page;
531*3ac0a46fSAndroid Build Coastguard Worker   return page;
532*3ac0a46fSAndroid Build Coastguard Worker }
533*3ac0a46fSAndroid Build Coastguard Worker 
UnloadPage(FPDF_PAGE page)534*3ac0a46fSAndroid Build Coastguard Worker void EmbedderTest::UnloadPage(FPDF_PAGE page) {
535*3ac0a46fSAndroid Build Coastguard Worker   UnloadPageCommon(page, true);
536*3ac0a46fSAndroid Build Coastguard Worker }
537*3ac0a46fSAndroid Build Coastguard Worker 
UnloadPageNoEvents(FPDF_PAGE page)538*3ac0a46fSAndroid Build Coastguard Worker void EmbedderTest::UnloadPageNoEvents(FPDF_PAGE page) {
539*3ac0a46fSAndroid Build Coastguard Worker   UnloadPageCommon(page, false);
540*3ac0a46fSAndroid Build Coastguard Worker }
541*3ac0a46fSAndroid Build Coastguard Worker 
UnloadPageCommon(FPDF_PAGE page,bool do_events)542*3ac0a46fSAndroid Build Coastguard Worker void EmbedderTest::UnloadPageCommon(FPDF_PAGE page, bool do_events) {
543*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(form_handle());
544*3ac0a46fSAndroid Build Coastguard Worker   int page_number = GetPageNumberForLoadedPage(page);
545*3ac0a46fSAndroid Build Coastguard Worker   CHECK_GE(page_number, 0);
546*3ac0a46fSAndroid Build Coastguard Worker 
547*3ac0a46fSAndroid Build Coastguard Worker   if (do_events) {
548*3ac0a46fSAndroid Build Coastguard Worker     FORM_DoPageAAction(page, form_handle(), FPDFPAGE_AACTION_CLOSE);
549*3ac0a46fSAndroid Build Coastguard Worker     FORM_OnBeforeClosePage(page, form_handle());
550*3ac0a46fSAndroid Build Coastguard Worker   }
551*3ac0a46fSAndroid Build Coastguard Worker   FPDF_ClosePage(page);
552*3ac0a46fSAndroid Build Coastguard Worker   page_map_.erase(page_number);
553*3ac0a46fSAndroid Build Coastguard Worker }
554*3ac0a46fSAndroid Build Coastguard Worker 
SetInitialFormFieldHighlight(FPDF_FORMHANDLE form)555*3ac0a46fSAndroid Build Coastguard Worker void EmbedderTest::SetInitialFormFieldHighlight(FPDF_FORMHANDLE form) {
556*3ac0a46fSAndroid Build Coastguard Worker   FPDF_SetFormFieldHighlightColor(form, FPDF_FORMFIELD_UNKNOWN, 0xFFE4DD);
557*3ac0a46fSAndroid Build Coastguard Worker   FPDF_SetFormFieldHighlightAlpha(form, 100);
558*3ac0a46fSAndroid Build Coastguard Worker }
559*3ac0a46fSAndroid Build Coastguard Worker 
RenderLoadedPage(FPDF_PAGE page)560*3ac0a46fSAndroid Build Coastguard Worker ScopedFPDFBitmap EmbedderTest::RenderLoadedPage(FPDF_PAGE page) {
561*3ac0a46fSAndroid Build Coastguard Worker   return RenderLoadedPageWithFlags(page, 0);
562*3ac0a46fSAndroid Build Coastguard Worker }
563*3ac0a46fSAndroid Build Coastguard Worker 
RenderLoadedPageWithFlags(FPDF_PAGE page,int flags)564*3ac0a46fSAndroid Build Coastguard Worker ScopedFPDFBitmap EmbedderTest::RenderLoadedPageWithFlags(FPDF_PAGE page,
565*3ac0a46fSAndroid Build Coastguard Worker                                                          int flags) {
566*3ac0a46fSAndroid Build Coastguard Worker   int page_number = GetPageNumberForLoadedPage(page);
567*3ac0a46fSAndroid Build Coastguard Worker   CHECK_GE(page_number, 0);
568*3ac0a46fSAndroid Build Coastguard Worker   return RenderPageWithFlags(page, form_handle(), flags);
569*3ac0a46fSAndroid Build Coastguard Worker }
570*3ac0a46fSAndroid Build Coastguard Worker 
RenderSavedPage(FPDF_PAGE page)571*3ac0a46fSAndroid Build Coastguard Worker ScopedFPDFBitmap EmbedderTest::RenderSavedPage(FPDF_PAGE page) {
572*3ac0a46fSAndroid Build Coastguard Worker   return RenderSavedPageWithFlags(page, 0);
573*3ac0a46fSAndroid Build Coastguard Worker }
574*3ac0a46fSAndroid Build Coastguard Worker 
RenderSavedPageWithFlags(FPDF_PAGE page,int flags)575*3ac0a46fSAndroid Build Coastguard Worker ScopedFPDFBitmap EmbedderTest::RenderSavedPageWithFlags(FPDF_PAGE page,
576*3ac0a46fSAndroid Build Coastguard Worker                                                         int flags) {
577*3ac0a46fSAndroid Build Coastguard Worker   int page_number = GetPageNumberForSavedPage(page);
578*3ac0a46fSAndroid Build Coastguard Worker   CHECK_GE(page_number, 0);
579*3ac0a46fSAndroid Build Coastguard Worker   return RenderPageWithFlags(page, saved_form_handle(), flags);
580*3ac0a46fSAndroid Build Coastguard Worker }
581*3ac0a46fSAndroid Build Coastguard Worker 
582*3ac0a46fSAndroid Build Coastguard Worker // static
RenderPageWithFlags(FPDF_PAGE page,FPDF_FORMHANDLE handle,int flags)583*3ac0a46fSAndroid Build Coastguard Worker ScopedFPDFBitmap EmbedderTest::RenderPageWithFlags(FPDF_PAGE page,
584*3ac0a46fSAndroid Build Coastguard Worker                                                    FPDF_FORMHANDLE handle,
585*3ac0a46fSAndroid Build Coastguard Worker                                                    int flags) {
586*3ac0a46fSAndroid Build Coastguard Worker   int width = static_cast<int>(FPDF_GetPageWidthF(page));
587*3ac0a46fSAndroid Build Coastguard Worker   int height = static_cast<int>(FPDF_GetPageHeightF(page));
588*3ac0a46fSAndroid Build Coastguard Worker   int alpha = FPDFPage_HasTransparency(page) ? 1 : 0;
589*3ac0a46fSAndroid Build Coastguard Worker   ScopedFPDFBitmap bitmap(FPDFBitmap_Create(width, height, alpha));
590*3ac0a46fSAndroid Build Coastguard Worker   FPDF_DWORD fill_color = alpha ? 0x00000000 : 0xFFFFFFFF;
591*3ac0a46fSAndroid Build Coastguard Worker   FPDFBitmap_FillRect(bitmap.get(), 0, 0, width, height, fill_color);
592*3ac0a46fSAndroid Build Coastguard Worker   FPDF_RenderPageBitmap(bitmap.get(), page, 0, 0, width, height, 0, flags);
593*3ac0a46fSAndroid Build Coastguard Worker   FPDF_FFLDraw(handle, bitmap.get(), page, 0, 0, width, height, 0, flags);
594*3ac0a46fSAndroid Build Coastguard Worker   return bitmap;
595*3ac0a46fSAndroid Build Coastguard Worker }
596*3ac0a46fSAndroid Build Coastguard Worker 
597*3ac0a46fSAndroid Build Coastguard Worker // static
RenderPage(FPDF_PAGE page)598*3ac0a46fSAndroid Build Coastguard Worker ScopedFPDFBitmap EmbedderTest::RenderPage(FPDF_PAGE page) {
599*3ac0a46fSAndroid Build Coastguard Worker   return RenderPageWithFlags(page, nullptr, 0);
600*3ac0a46fSAndroid Build Coastguard Worker }
601*3ac0a46fSAndroid Build Coastguard Worker 
602*3ac0a46fSAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
603*3ac0a46fSAndroid Build Coastguard Worker // static
RenderPageWithFlagsToEmf(FPDF_PAGE page,int flags)604*3ac0a46fSAndroid Build Coastguard Worker std::vector<uint8_t> EmbedderTest::RenderPageWithFlagsToEmf(FPDF_PAGE page,
605*3ac0a46fSAndroid Build Coastguard Worker                                                             int flags) {
606*3ac0a46fSAndroid Build Coastguard Worker   HDC dc = CreateEnhMetaFileA(nullptr, nullptr, nullptr, nullptr);
607*3ac0a46fSAndroid Build Coastguard Worker 
608*3ac0a46fSAndroid Build Coastguard Worker   int width = static_cast<int>(FPDF_GetPageWidthF(page));
609*3ac0a46fSAndroid Build Coastguard Worker   int height = static_cast<int>(FPDF_GetPageHeightF(page));
610*3ac0a46fSAndroid Build Coastguard Worker   HRGN rgn = CreateRectRgn(0, 0, width, height);
611*3ac0a46fSAndroid Build Coastguard Worker   SelectClipRgn(dc, rgn);
612*3ac0a46fSAndroid Build Coastguard Worker   DeleteObject(rgn);
613*3ac0a46fSAndroid Build Coastguard Worker 
614*3ac0a46fSAndroid Build Coastguard Worker   SelectObject(dc, GetStockObject(NULL_PEN));
615*3ac0a46fSAndroid Build Coastguard Worker   SelectObject(dc, GetStockObject(WHITE_BRUSH));
616*3ac0a46fSAndroid Build Coastguard Worker   // If a PS_NULL pen is used, the dimensions of the rectangle are 1 pixel less.
617*3ac0a46fSAndroid Build Coastguard Worker   Rectangle(dc, 0, 0, width + 1, height + 1);
618*3ac0a46fSAndroid Build Coastguard Worker 
619*3ac0a46fSAndroid Build Coastguard Worker   FPDF_RenderPage(dc, page, 0, 0, width, height, 0, flags);
620*3ac0a46fSAndroid Build Coastguard Worker 
621*3ac0a46fSAndroid Build Coastguard Worker   HENHMETAFILE emf = CloseEnhMetaFile(dc);
622*3ac0a46fSAndroid Build Coastguard Worker   UINT size_in_bytes = GetEnhMetaFileBits(emf, 0, nullptr);
623*3ac0a46fSAndroid Build Coastguard Worker   std::vector<uint8_t> buffer(size_in_bytes);
624*3ac0a46fSAndroid Build Coastguard Worker   GetEnhMetaFileBits(emf, size_in_bytes, buffer.data());
625*3ac0a46fSAndroid Build Coastguard Worker   DeleteEnhMetaFile(emf);
626*3ac0a46fSAndroid Build Coastguard Worker   return buffer;
627*3ac0a46fSAndroid Build Coastguard Worker }
628*3ac0a46fSAndroid Build Coastguard Worker 
629*3ac0a46fSAndroid Build Coastguard Worker // static
GetPostScriptFromEmf(pdfium::span<const uint8_t> emf_data)630*3ac0a46fSAndroid Build Coastguard Worker std::string EmbedderTest::GetPostScriptFromEmf(
631*3ac0a46fSAndroid Build Coastguard Worker     pdfium::span<const uint8_t> emf_data) {
632*3ac0a46fSAndroid Build Coastguard Worker   // This comes from Emf::InitFromData() in Chromium.
633*3ac0a46fSAndroid Build Coastguard Worker   HENHMETAFILE emf = SetEnhMetaFileBits(
634*3ac0a46fSAndroid Build Coastguard Worker       pdfium::base::checked_cast<UINT>(emf_data.size()), emf_data.data());
635*3ac0a46fSAndroid Build Coastguard Worker   if (!emf)
636*3ac0a46fSAndroid Build Coastguard Worker     return std::string();
637*3ac0a46fSAndroid Build Coastguard Worker 
638*3ac0a46fSAndroid Build Coastguard Worker   // This comes from Emf::Enumerator::Enumerator() in Chromium.
639*3ac0a46fSAndroid Build Coastguard Worker   std::vector<const ENHMETARECORD*> records;
640*3ac0a46fSAndroid Build Coastguard Worker   if (!EnumEnhMetaFile(nullptr, emf, &GetRecordProc, &records, nullptr)) {
641*3ac0a46fSAndroid Build Coastguard Worker     DeleteEnhMetaFile(emf);
642*3ac0a46fSAndroid Build Coastguard Worker     return std::string();
643*3ac0a46fSAndroid Build Coastguard Worker   }
644*3ac0a46fSAndroid Build Coastguard Worker 
645*3ac0a46fSAndroid Build Coastguard Worker   // This comes from PostScriptMetaFile::SafePlayback() in Chromium.
646*3ac0a46fSAndroid Build Coastguard Worker   std::string ps_data;
647*3ac0a46fSAndroid Build Coastguard Worker   for (const auto* record : records) {
648*3ac0a46fSAndroid Build Coastguard Worker     if (record->iType != EMR_GDICOMMENT)
649*3ac0a46fSAndroid Build Coastguard Worker       continue;
650*3ac0a46fSAndroid Build Coastguard Worker 
651*3ac0a46fSAndroid Build Coastguard Worker     // PostScript data is encapsulated inside EMF comment records.
652*3ac0a46fSAndroid Build Coastguard Worker     // The first two bytes of the comment indicate the string length. The rest
653*3ac0a46fSAndroid Build Coastguard Worker     // is the actual string data.
654*3ac0a46fSAndroid Build Coastguard Worker     const auto* comment = reinterpret_cast<const EMRGDICOMMENT*>(record);
655*3ac0a46fSAndroid Build Coastguard Worker     const char* data = reinterpret_cast<const char*>(comment->Data);
656*3ac0a46fSAndroid Build Coastguard Worker     uint16_t size = *reinterpret_cast<const uint16_t*>(data);
657*3ac0a46fSAndroid Build Coastguard Worker     data += 2;
658*3ac0a46fSAndroid Build Coastguard Worker     ps_data.append(data, size);
659*3ac0a46fSAndroid Build Coastguard Worker   }
660*3ac0a46fSAndroid Build Coastguard Worker   DeleteEnhMetaFile(emf);
661*3ac0a46fSAndroid Build Coastguard Worker   return ps_data;
662*3ac0a46fSAndroid Build Coastguard Worker }
663*3ac0a46fSAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_WIN)
664*3ac0a46fSAndroid Build Coastguard Worker 
OpenSavedDocument()665*3ac0a46fSAndroid Build Coastguard Worker FPDF_DOCUMENT EmbedderTest::OpenSavedDocument() {
666*3ac0a46fSAndroid Build Coastguard Worker   return OpenSavedDocumentWithPassword(nullptr);
667*3ac0a46fSAndroid Build Coastguard Worker }
668*3ac0a46fSAndroid Build Coastguard Worker 
669*3ac0a46fSAndroid Build Coastguard Worker // static
BytesPerPixelForFormat(int format)670*3ac0a46fSAndroid Build Coastguard Worker int EmbedderTest::BytesPerPixelForFormat(int format) {
671*3ac0a46fSAndroid Build Coastguard Worker   switch (format) {
672*3ac0a46fSAndroid Build Coastguard Worker     case FPDFBitmap_Gray:
673*3ac0a46fSAndroid Build Coastguard Worker       return 1;
674*3ac0a46fSAndroid Build Coastguard Worker     case FPDFBitmap_BGR:
675*3ac0a46fSAndroid Build Coastguard Worker       return 3;
676*3ac0a46fSAndroid Build Coastguard Worker     case FPDFBitmap_BGRx:
677*3ac0a46fSAndroid Build Coastguard Worker     case FPDFBitmap_BGRA:
678*3ac0a46fSAndroid Build Coastguard Worker       return 4;
679*3ac0a46fSAndroid Build Coastguard Worker     default:
680*3ac0a46fSAndroid Build Coastguard Worker       NOTREACHED_NORETURN();
681*3ac0a46fSAndroid Build Coastguard Worker   }
682*3ac0a46fSAndroid Build Coastguard Worker }
683*3ac0a46fSAndroid Build Coastguard Worker 
OpenSavedDocumentWithPassword(const char * password)684*3ac0a46fSAndroid Build Coastguard Worker FPDF_DOCUMENT EmbedderTest::OpenSavedDocumentWithPassword(
685*3ac0a46fSAndroid Build Coastguard Worker     const char* password) {
686*3ac0a46fSAndroid Build Coastguard Worker   memset(&saved_file_access_, 0, sizeof(saved_file_access_));
687*3ac0a46fSAndroid Build Coastguard Worker   saved_file_access_.m_FileLen =
688*3ac0a46fSAndroid Build Coastguard Worker       pdfium::base::checked_cast<unsigned long>(data_string_.size());
689*3ac0a46fSAndroid Build Coastguard Worker   saved_file_access_.m_GetBlock = GetBlockFromString;
690*3ac0a46fSAndroid Build Coastguard Worker   // Copy data to prevent clearing it before saved document close.
691*3ac0a46fSAndroid Build Coastguard Worker   saved_document_file_data_ = data_string_;
692*3ac0a46fSAndroid Build Coastguard Worker   saved_file_access_.m_Param = &saved_document_file_data_;
693*3ac0a46fSAndroid Build Coastguard Worker 
694*3ac0a46fSAndroid Build Coastguard Worker   saved_fake_file_access_ =
695*3ac0a46fSAndroid Build Coastguard Worker       std::make_unique<FakeFileAccess>(&saved_file_access_);
696*3ac0a46fSAndroid Build Coastguard Worker 
697*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(OpenDocumentHelper(
698*3ac0a46fSAndroid Build Coastguard Worker       password, LinearizeOption::kDefaultLinearize,
699*3ac0a46fSAndroid Build Coastguard Worker       JavaScriptOption::kEnableJavaScript, saved_fake_file_access_.get(),
700*3ac0a46fSAndroid Build Coastguard Worker       &saved_document_, &saved_avail_, &saved_form_handle_));
701*3ac0a46fSAndroid Build Coastguard Worker   return saved_document();
702*3ac0a46fSAndroid Build Coastguard Worker }
703*3ac0a46fSAndroid Build Coastguard Worker 
CloseSavedDocument()704*3ac0a46fSAndroid Build Coastguard Worker void EmbedderTest::CloseSavedDocument() {
705*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(saved_document());
706*3ac0a46fSAndroid Build Coastguard Worker 
707*3ac0a46fSAndroid Build Coastguard Worker   saved_form_handle_.reset();
708*3ac0a46fSAndroid Build Coastguard Worker   saved_document_.reset();
709*3ac0a46fSAndroid Build Coastguard Worker   saved_avail_.reset();
710*3ac0a46fSAndroid Build Coastguard Worker }
711*3ac0a46fSAndroid Build Coastguard Worker 
LoadSavedPage(int page_number)712*3ac0a46fSAndroid Build Coastguard Worker FPDF_PAGE EmbedderTest::LoadSavedPage(int page_number) {
713*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(saved_form_handle());
714*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(page_number >= 0);
715*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(!pdfium::Contains(saved_page_map_, page_number));
716*3ac0a46fSAndroid Build Coastguard Worker 
717*3ac0a46fSAndroid Build Coastguard Worker   FPDF_PAGE page = FPDF_LoadPage(saved_document(), page_number);
718*3ac0a46fSAndroid Build Coastguard Worker   if (!page)
719*3ac0a46fSAndroid Build Coastguard Worker     return nullptr;
720*3ac0a46fSAndroid Build Coastguard Worker 
721*3ac0a46fSAndroid Build Coastguard Worker   FORM_OnAfterLoadPage(page, saved_form_handle());
722*3ac0a46fSAndroid Build Coastguard Worker   FORM_DoPageAAction(page, saved_form_handle(), FPDFPAGE_AACTION_OPEN);
723*3ac0a46fSAndroid Build Coastguard Worker   saved_page_map_[page_number] = page;
724*3ac0a46fSAndroid Build Coastguard Worker   return page;
725*3ac0a46fSAndroid Build Coastguard Worker }
726*3ac0a46fSAndroid Build Coastguard Worker 
CloseSavedPage(FPDF_PAGE page)727*3ac0a46fSAndroid Build Coastguard Worker void EmbedderTest::CloseSavedPage(FPDF_PAGE page) {
728*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(saved_form_handle());
729*3ac0a46fSAndroid Build Coastguard Worker 
730*3ac0a46fSAndroid Build Coastguard Worker   int page_number = GetPageNumberForSavedPage(page);
731*3ac0a46fSAndroid Build Coastguard Worker   CHECK_GE(page_number, 0);
732*3ac0a46fSAndroid Build Coastguard Worker 
733*3ac0a46fSAndroid Build Coastguard Worker   FORM_DoPageAAction(page, saved_form_handle(), FPDFPAGE_AACTION_CLOSE);
734*3ac0a46fSAndroid Build Coastguard Worker   FORM_OnBeforeClosePage(page, saved_form_handle());
735*3ac0a46fSAndroid Build Coastguard Worker   FPDF_ClosePage(page);
736*3ac0a46fSAndroid Build Coastguard Worker 
737*3ac0a46fSAndroid Build Coastguard Worker   saved_page_map_.erase(page_number);
738*3ac0a46fSAndroid Build Coastguard Worker }
739*3ac0a46fSAndroid Build Coastguard Worker 
VerifySavedRendering(FPDF_PAGE page,int width,int height,const char * md5)740*3ac0a46fSAndroid Build Coastguard Worker void EmbedderTest::VerifySavedRendering(FPDF_PAGE page,
741*3ac0a46fSAndroid Build Coastguard Worker                                         int width,
742*3ac0a46fSAndroid Build Coastguard Worker                                         int height,
743*3ac0a46fSAndroid Build Coastguard Worker                                         const char* md5) {
744*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(saved_document());
745*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(page);
746*3ac0a46fSAndroid Build Coastguard Worker 
747*3ac0a46fSAndroid Build Coastguard Worker   ScopedFPDFBitmap bitmap = RenderSavedPageWithFlags(page, FPDF_ANNOT);
748*3ac0a46fSAndroid Build Coastguard Worker   CompareBitmap(bitmap.get(), width, height, md5);
749*3ac0a46fSAndroid Build Coastguard Worker }
750*3ac0a46fSAndroid Build Coastguard Worker 
VerifySavedDocument(int width,int height,const char * md5)751*3ac0a46fSAndroid Build Coastguard Worker void EmbedderTest::VerifySavedDocument(int width, int height, const char* md5) {
752*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(OpenSavedDocument());
753*3ac0a46fSAndroid Build Coastguard Worker   FPDF_PAGE page = LoadSavedPage(0);
754*3ac0a46fSAndroid Build Coastguard Worker   VerifySavedRendering(page, width, height, md5);
755*3ac0a46fSAndroid Build Coastguard Worker   CloseSavedPage(page);
756*3ac0a46fSAndroid Build Coastguard Worker   CloseSavedDocument();
757*3ac0a46fSAndroid Build Coastguard Worker }
758*3ac0a46fSAndroid Build Coastguard Worker 
SetWholeFileAvailable()759*3ac0a46fSAndroid Build Coastguard Worker void EmbedderTest::SetWholeFileAvailable() {
760*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(fake_file_access_);
761*3ac0a46fSAndroid Build Coastguard Worker   fake_file_access_->SetWholeFileAvailable();
762*3ac0a46fSAndroid Build Coastguard Worker }
763*3ac0a46fSAndroid Build Coastguard Worker 
SetDocumentFromAvail()764*3ac0a46fSAndroid Build Coastguard Worker void EmbedderTest::SetDocumentFromAvail() {
765*3ac0a46fSAndroid Build Coastguard Worker   document_.reset(FPDFAvail_GetDocument(avail(), nullptr));
766*3ac0a46fSAndroid Build Coastguard Worker }
767*3ac0a46fSAndroid Build Coastguard Worker 
CreateAvail(FX_FILEAVAIL * file_avail,FPDF_FILEACCESS * file)768*3ac0a46fSAndroid Build Coastguard Worker void EmbedderTest::CreateAvail(FX_FILEAVAIL* file_avail,
769*3ac0a46fSAndroid Build Coastguard Worker                                FPDF_FILEACCESS* file) {
770*3ac0a46fSAndroid Build Coastguard Worker   avail_.reset(FPDFAvail_Create(file_avail, file));
771*3ac0a46fSAndroid Build Coastguard Worker }
772*3ac0a46fSAndroid Build Coastguard Worker 
GetPage(FPDF_FORMFILLINFO * info,FPDF_DOCUMENT document,int page_index)773*3ac0a46fSAndroid Build Coastguard Worker FPDF_PAGE EmbedderTest::Delegate::GetPage(FPDF_FORMFILLINFO* info,
774*3ac0a46fSAndroid Build Coastguard Worker                                           FPDF_DOCUMENT document,
775*3ac0a46fSAndroid Build Coastguard Worker                                           int page_index) {
776*3ac0a46fSAndroid Build Coastguard Worker   EmbedderTest* test = static_cast<EmbedderTest*>(info);
777*3ac0a46fSAndroid Build Coastguard Worker   auto it = test->page_map_.find(page_index);
778*3ac0a46fSAndroid Build Coastguard Worker   return it != test->page_map_.end() ? it->second : nullptr;
779*3ac0a46fSAndroid Build Coastguard Worker }
780*3ac0a46fSAndroid Build Coastguard Worker 
781*3ac0a46fSAndroid Build Coastguard Worker // static
HashBitmap(FPDF_BITMAP bitmap)782*3ac0a46fSAndroid Build Coastguard Worker std::string EmbedderTest::HashBitmap(FPDF_BITMAP bitmap) {
783*3ac0a46fSAndroid Build Coastguard Worker   int stride = FPDFBitmap_GetStride(bitmap);
784*3ac0a46fSAndroid Build Coastguard Worker   int usable_bytes_per_row =
785*3ac0a46fSAndroid Build Coastguard Worker       GetBitmapBytesPerPixel(bitmap) * FPDFBitmap_GetWidth(bitmap);
786*3ac0a46fSAndroid Build Coastguard Worker   int height = FPDFBitmap_GetHeight(bitmap);
787*3ac0a46fSAndroid Build Coastguard Worker   auto span = pdfium::make_span(
788*3ac0a46fSAndroid Build Coastguard Worker       static_cast<uint8_t*>(FPDFBitmap_GetBuffer(bitmap)), stride * height);
789*3ac0a46fSAndroid Build Coastguard Worker 
790*3ac0a46fSAndroid Build Coastguard Worker   CRYPT_md5_context context = CRYPT_MD5Start();
791*3ac0a46fSAndroid Build Coastguard Worker   for (int i = 0; i < height; ++i)
792*3ac0a46fSAndroid Build Coastguard Worker     CRYPT_MD5Update(&context, span.subspan(i * stride, usable_bytes_per_row));
793*3ac0a46fSAndroid Build Coastguard Worker   uint8_t digest[16];
794*3ac0a46fSAndroid Build Coastguard Worker   CRYPT_MD5Finish(&context, digest);
795*3ac0a46fSAndroid Build Coastguard Worker   return CryptToBase16(digest);
796*3ac0a46fSAndroid Build Coastguard Worker }
797*3ac0a46fSAndroid Build Coastguard Worker 
798*3ac0a46fSAndroid Build Coastguard Worker // static
WriteBitmapToPng(FPDF_BITMAP bitmap,const std::string & filename)799*3ac0a46fSAndroid Build Coastguard Worker void EmbedderTest::WriteBitmapToPng(FPDF_BITMAP bitmap,
800*3ac0a46fSAndroid Build Coastguard Worker                                     const std::string& filename) {
801*3ac0a46fSAndroid Build Coastguard Worker   BitmapSaver::WriteBitmapToPng(bitmap, filename);
802*3ac0a46fSAndroid Build Coastguard Worker }
803*3ac0a46fSAndroid Build Coastguard Worker 
804*3ac0a46fSAndroid Build Coastguard Worker // static
CompareBitmap(FPDF_BITMAP bitmap,int expected_width,int expected_height,const char * expected_md5sum)805*3ac0a46fSAndroid Build Coastguard Worker void EmbedderTest::CompareBitmap(FPDF_BITMAP bitmap,
806*3ac0a46fSAndroid Build Coastguard Worker                                  int expected_width,
807*3ac0a46fSAndroid Build Coastguard Worker                                  int expected_height,
808*3ac0a46fSAndroid Build Coastguard Worker                                  const char* expected_md5sum) {
809*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_EQ(expected_width, FPDFBitmap_GetWidth(bitmap));
810*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_EQ(expected_height, FPDFBitmap_GetHeight(bitmap));
811*3ac0a46fSAndroid Build Coastguard Worker 
812*3ac0a46fSAndroid Build Coastguard Worker   // The expected stride is calculated using the same formula as in
813*3ac0a46fSAndroid Build Coastguard Worker   // CFX_DIBitmap::CalculatePitchAndSize(), which sets the bitmap stride.
814*3ac0a46fSAndroid Build Coastguard Worker   const int expected_stride =
815*3ac0a46fSAndroid Build Coastguard Worker       (expected_width * GetBitmapBytesPerPixel(bitmap) * 8 + 31) / 32 * 4;
816*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_EQ(expected_stride, FPDFBitmap_GetStride(bitmap));
817*3ac0a46fSAndroid Build Coastguard Worker 
818*3ac0a46fSAndroid Build Coastguard Worker   if (!expected_md5sum)
819*3ac0a46fSAndroid Build Coastguard Worker     return;
820*3ac0a46fSAndroid Build Coastguard Worker 
821*3ac0a46fSAndroid Build Coastguard Worker   std::string actual_md5sum = HashBitmap(bitmap);
822*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(expected_md5sum, actual_md5sum);
823*3ac0a46fSAndroid Build Coastguard Worker   if (EmbedderTestEnvironment::GetInstance()->write_pngs()) {
824*3ac0a46fSAndroid Build Coastguard Worker     WriteBitmapToPng(bitmap, actual_md5sum + ".png");
825*3ac0a46fSAndroid Build Coastguard Worker   }
826*3ac0a46fSAndroid Build Coastguard Worker }
827*3ac0a46fSAndroid Build Coastguard Worker 
828*3ac0a46fSAndroid Build Coastguard Worker // static
WriteBlockCallback(FPDF_FILEWRITE * pFileWrite,const void * data,unsigned long size)829*3ac0a46fSAndroid Build Coastguard Worker int EmbedderTest::WriteBlockCallback(FPDF_FILEWRITE* pFileWrite,
830*3ac0a46fSAndroid Build Coastguard Worker                                      const void* data,
831*3ac0a46fSAndroid Build Coastguard Worker                                      unsigned long size) {
832*3ac0a46fSAndroid Build Coastguard Worker   EmbedderTest* pThis = static_cast<EmbedderTest*>(pFileWrite);
833*3ac0a46fSAndroid Build Coastguard Worker 
834*3ac0a46fSAndroid Build Coastguard Worker   pThis->data_string_.append(static_cast<const char*>(data), size);
835*3ac0a46fSAndroid Build Coastguard Worker 
836*3ac0a46fSAndroid Build Coastguard Worker   if (pThis->filestream_.is_open())
837*3ac0a46fSAndroid Build Coastguard Worker     pThis->filestream_.write(static_cast<const char*>(data), size);
838*3ac0a46fSAndroid Build Coastguard Worker 
839*3ac0a46fSAndroid Build Coastguard Worker   return 1;
840*3ac0a46fSAndroid Build Coastguard Worker }
841*3ac0a46fSAndroid Build Coastguard Worker 
842*3ac0a46fSAndroid Build Coastguard Worker // static
GetBlockFromString(void * param,unsigned long pos,unsigned char * buf,unsigned long size)843*3ac0a46fSAndroid Build Coastguard Worker int EmbedderTest::GetBlockFromString(void* param,
844*3ac0a46fSAndroid Build Coastguard Worker                                      unsigned long pos,
845*3ac0a46fSAndroid Build Coastguard Worker                                      unsigned char* buf,
846*3ac0a46fSAndroid Build Coastguard Worker                                      unsigned long size) {
847*3ac0a46fSAndroid Build Coastguard Worker   std::string* new_file = static_cast<std::string*>(param);
848*3ac0a46fSAndroid Build Coastguard Worker   CHECK(new_file);
849*3ac0a46fSAndroid Build Coastguard Worker 
850*3ac0a46fSAndroid Build Coastguard Worker   pdfium::base::CheckedNumeric<size_t> end = pos;
851*3ac0a46fSAndroid Build Coastguard Worker   end += size;
852*3ac0a46fSAndroid Build Coastguard Worker   CHECK_LE(end.ValueOrDie(), new_file->size());
853*3ac0a46fSAndroid Build Coastguard Worker 
854*3ac0a46fSAndroid Build Coastguard Worker   memcpy(buf, new_file->data() + pos, size);
855*3ac0a46fSAndroid Build Coastguard Worker   return 1;
856*3ac0a46fSAndroid Build Coastguard Worker }
857*3ac0a46fSAndroid Build Coastguard Worker 
858*3ac0a46fSAndroid Build Coastguard Worker // static
GetPageNumberForPage(const PageNumberToHandleMap & page_map,FPDF_PAGE page)859*3ac0a46fSAndroid Build Coastguard Worker int EmbedderTest::GetPageNumberForPage(const PageNumberToHandleMap& page_map,
860*3ac0a46fSAndroid Build Coastguard Worker                                        FPDF_PAGE page) {
861*3ac0a46fSAndroid Build Coastguard Worker   for (const auto& it : page_map) {
862*3ac0a46fSAndroid Build Coastguard Worker     if (it.second == page) {
863*3ac0a46fSAndroid Build Coastguard Worker       int page_number = it.first;
864*3ac0a46fSAndroid Build Coastguard Worker       DCHECK(page_number >= 0);
865*3ac0a46fSAndroid Build Coastguard Worker       return page_number;
866*3ac0a46fSAndroid Build Coastguard Worker     }
867*3ac0a46fSAndroid Build Coastguard Worker   }
868*3ac0a46fSAndroid Build Coastguard Worker   return -1;
869*3ac0a46fSAndroid Build Coastguard Worker }
870*3ac0a46fSAndroid Build Coastguard Worker 
GetPageNumberForLoadedPage(FPDF_PAGE page) const871*3ac0a46fSAndroid Build Coastguard Worker int EmbedderTest::GetPageNumberForLoadedPage(FPDF_PAGE page) const {
872*3ac0a46fSAndroid Build Coastguard Worker   return GetPageNumberForPage(page_map_, page);
873*3ac0a46fSAndroid Build Coastguard Worker }
874*3ac0a46fSAndroid Build Coastguard Worker 
GetPageNumberForSavedPage(FPDF_PAGE page) const875*3ac0a46fSAndroid Build Coastguard Worker int EmbedderTest::GetPageNumberForSavedPage(FPDF_PAGE page) const {
876*3ac0a46fSAndroid Build Coastguard Worker   return GetPageNumberForPage(saved_page_map_, page);
877*3ac0a46fSAndroid Build Coastguard Worker }
878*3ac0a46fSAndroid Build Coastguard Worker 
879*3ac0a46fSAndroid Build Coastguard Worker #ifndef NDEBUG
OpenPDFFileForWrite(const std::string & filename)880*3ac0a46fSAndroid Build Coastguard Worker void EmbedderTest::OpenPDFFileForWrite(const std::string& filename) {
881*3ac0a46fSAndroid Build Coastguard Worker   filestream_.open(filename, std::ios_base::binary);
882*3ac0a46fSAndroid Build Coastguard Worker }
883*3ac0a46fSAndroid Build Coastguard Worker 
ClosePDFFileForWrite()884*3ac0a46fSAndroid Build Coastguard Worker void EmbedderTest::ClosePDFFileForWrite() {
885*3ac0a46fSAndroid Build Coastguard Worker   filestream_.close();
886*3ac0a46fSAndroid Build Coastguard Worker }
887*3ac0a46fSAndroid Build Coastguard Worker #endif
888