xref: /aosp_15_r20/external/pdfium/fpdfsdk/fpdf_javascript_embeddertest.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright 2019 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <vector>
6 
7 #include "core/fxcrt/fx_memory.h"
8 #include "public/fpdf_javascript.h"
9 #include "public/fpdfview.h"
10 #include "testing/embedder_test.h"
11 #include "testing/fx_string_testhelpers.h"
12 #include "testing/utils/hash.h"
13 
14 class FPDFJavaScriptEmbedderTest : public EmbedderTest {};
15 
TEST_F(FPDFJavaScriptEmbedderTest,CountJS)16 TEST_F(FPDFJavaScriptEmbedderTest, CountJS) {
17   // Open a file with JS.
18   ASSERT_TRUE(OpenDocument("bug_679649.pdf"));
19   EXPECT_EQ(1, FPDFDoc_GetJavaScriptActionCount(document()));
20 }
21 
TEST_F(FPDFJavaScriptEmbedderTest,CountNoJS)22 TEST_F(FPDFJavaScriptEmbedderTest, CountNoJS) {
23   // Open a file without JS.
24   ASSERT_TRUE(OpenDocument("hello_world.pdf"));
25   EXPECT_EQ(0, FPDFDoc_GetJavaScriptActionCount(document()));
26 
27   // Provide no document.
28   EXPECT_EQ(-1, FPDFDoc_GetJavaScriptActionCount(nullptr));
29 }
30 
TEST_F(FPDFJavaScriptEmbedderTest,GetJS)31 TEST_F(FPDFJavaScriptEmbedderTest, GetJS) {
32   ASSERT_TRUE(OpenDocument("js.pdf"));
33   EXPECT_EQ(5, FPDFDoc_GetJavaScriptActionCount(document()));
34 
35   ScopedFPDFJavaScriptAction js;
36   js.reset(FPDFDoc_GetJavaScriptAction(document(), -1));
37   EXPECT_FALSE(js);
38   js.reset(FPDFDoc_GetJavaScriptAction(document(), 5));
39   EXPECT_FALSE(js);
40   js.reset(FPDFDoc_GetJavaScriptAction(nullptr, -1));
41   EXPECT_FALSE(js);
42   js.reset(FPDFDoc_GetJavaScriptAction(nullptr, 0));
43   EXPECT_FALSE(js);
44   js.reset(FPDFDoc_GetJavaScriptAction(nullptr, 1));
45   EXPECT_FALSE(js);
46   js.reset(FPDFDoc_GetJavaScriptAction(nullptr, 2));
47   EXPECT_FALSE(js);
48   js.reset(FPDFDoc_GetJavaScriptAction(nullptr, 5));
49   EXPECT_FALSE(js);
50 
51   js.reset(FPDFDoc_GetJavaScriptAction(document(), 0));
52   EXPECT_TRUE(js);
53   js.reset(FPDFDoc_GetJavaScriptAction(document(), 1));
54   EXPECT_TRUE(js);
55   js.reset(FPDFDoc_GetJavaScriptAction(document(), 2));
56   EXPECT_FALSE(js);
57   js.reset(FPDFDoc_GetJavaScriptAction(document(), 3));
58   EXPECT_FALSE(js);
59   js.reset(FPDFDoc_GetJavaScriptAction(document(), 4));
60   EXPECT_FALSE(js);
61 }
62 
TEST_F(FPDFJavaScriptEmbedderTest,GetJSName)63 TEST_F(FPDFJavaScriptEmbedderTest, GetJSName) {
64   ASSERT_TRUE(OpenDocument("bug_679649.pdf"));
65   ScopedFPDFJavaScriptAction js(FPDFDoc_GetJavaScriptAction(document(), 0));
66   ASSERT_TRUE(js);
67 
68   {
69     FPDF_WCHAR buf[10];
70     EXPECT_EQ(0u, FPDFJavaScriptAction_GetName(nullptr, nullptr, 0));
71     EXPECT_EQ(0u, FPDFJavaScriptAction_GetName(nullptr, buf, 0));
72     EXPECT_EQ(0u, FPDFJavaScriptAction_GetName(nullptr, buf, sizeof(buf)));
73   }
74 
75   constexpr size_t kExpectedLength = 22;
76   ASSERT_EQ(kExpectedLength,
77             FPDFJavaScriptAction_GetName(js.get(), nullptr, 0));
78 
79   // Check that the name not returned if the buffer is too small.
80   // The result buffer should be overwritten with an empty string.
81   std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(kExpectedLength);
82   // Write in the buffer to verify it's not overwritten.
83   memcpy(buf.data(), "abcdefgh", 8);
84   EXPECT_EQ(kExpectedLength, FPDFJavaScriptAction_GetName(js.get(), buf.data(),
85                                                           kExpectedLength - 1));
86   EXPECT_EQ(0, memcmp(buf.data(), "abcdefgh", 8));
87 
88   EXPECT_EQ(kExpectedLength, FPDFJavaScriptAction_GetName(js.get(), buf.data(),
89                                                           kExpectedLength));
90   EXPECT_EQ(L"startDelay", GetPlatformWString(buf.data()));
91 }
92 
TEST_F(FPDFJavaScriptEmbedderTest,GetJSScript)93 TEST_F(FPDFJavaScriptEmbedderTest, GetJSScript) {
94   ASSERT_TRUE(OpenDocument("bug_679649.pdf"));
95   ScopedFPDFJavaScriptAction js(FPDFDoc_GetJavaScriptAction(document(), 0));
96   ASSERT_TRUE(js);
97 
98   {
99     FPDF_WCHAR buf[10];
100     EXPECT_EQ(0u, FPDFJavaScriptAction_GetScript(nullptr, nullptr, 0));
101     EXPECT_EQ(0u, FPDFJavaScriptAction_GetScript(nullptr, buf, 0));
102     EXPECT_EQ(0u, FPDFJavaScriptAction_GetScript(nullptr, buf, sizeof(buf)));
103   }
104 
105   constexpr size_t kExpectedLength = 218;
106   ASSERT_EQ(kExpectedLength,
107             FPDFJavaScriptAction_GetScript(js.get(), nullptr, 0));
108 
109   // Check that the string value of an AP is not returned if the buffer is too
110   // small. The result buffer should be overwritten with an empty string.
111   std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(kExpectedLength);
112   // Write in the buffer to verify it's not overwritten.
113   memcpy(buf.data(), "abcdefgh", 8);
114   EXPECT_EQ(kExpectedLength, FPDFJavaScriptAction_GetScript(
115                                  js.get(), buf.data(), kExpectedLength - 1));
116   EXPECT_EQ(0, memcmp(buf.data(), "abcdefgh", 8));
117 
118   static const wchar_t kExpectedScript[] =
119       L"function ping() {\n  app.alert(\"ping\");\n}\n"
120       L"var timer = app.setTimeOut(\"ping()\", 100);\napp.clearTimeOut(timer);";
121   EXPECT_EQ(kExpectedLength, FPDFJavaScriptAction_GetScript(
122                                  js.get(), buf.data(), kExpectedLength));
123   EXPECT_EQ(kExpectedScript, GetPlatformWString(buf.data()));
124 }
125