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