1 // Copyright 2017 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 #include "xfa/fxfa/fm2js/cxfa_fmparser.h"
6
7 #include <vector>
8
9 #include "core/fxcrt/cfx_widetextbuf.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "testing/test_support.h"
12 #include "third_party/base/ptr_util.h"
13 #include "xfa/fxfa/fm2js/cxfa_fmtojavascriptdepth.h"
14
TEST(CXFA_FMParserTest,Empty)15 TEST(CXFA_FMParserTest, Empty) {
16 auto parser = pdfium::MakeUnique<CXFA_FMParser>(L"");
17 std::unique_ptr<CXFA_FMFunctionDefinition> ast = parser->Parse();
18 ASSERT(ast != nullptr);
19 EXPECT_FALSE(parser->HasError());
20
21 CXFA_FMToJavaScriptDepth::Reset();
22 CFX_WideTextBuf buf;
23 EXPECT_TRUE(ast->ToJavaScript(buf));
24 // TODO(dsinclair): This is a little weird .....
25 EXPECT_EQ(L"// comments only", buf.AsStringView());
26 }
27
TEST(CXFA_FMParserTest,CommentOnlyIsError)28 TEST(CXFA_FMParserTest, CommentOnlyIsError) {
29 auto parser = pdfium::MakeUnique<CXFA_FMParser>(L"; Just comment");
30 std::unique_ptr<CXFA_FMFunctionDefinition> ast = parser->Parse();
31 ASSERT(ast != nullptr);
32 // TODO(dsinclair): This isn't allowed per the spec.
33 EXPECT_FALSE(parser->HasError());
34 // EXPECT_TRUE(parser->HasError());
35
36 CXFA_FMToJavaScriptDepth::Reset();
37 CFX_WideTextBuf buf;
38 EXPECT_TRUE(ast->ToJavaScript(buf));
39 EXPECT_EQ(L"// comments only", buf.AsStringView());
40 }
41
TEST(CXFA_FMParserTest,CommentThenValue)42 TEST(CXFA_FMParserTest, CommentThenValue) {
43 const wchar_t ret[] =
44 L"(\nfunction ()\n{\n"
45 L"var pfm_ret = null;\n"
46 L"pfm_ret = 12;\n"
47 L"return pfm_rt.get_val(pfm_ret);\n"
48 L"}\n).call(this);\n";
49
50 auto parser = pdfium::MakeUnique<CXFA_FMParser>(L"; Just comment\n12");
51 std::unique_ptr<CXFA_FMFunctionDefinition> ast = parser->Parse();
52 ASSERT(ast != nullptr);
53 EXPECT_FALSE(parser->HasError());
54
55 CXFA_FMToJavaScriptDepth::Reset();
56 CFX_WideTextBuf buf;
57 EXPECT_TRUE(ast->ToJavaScript(buf));
58 EXPECT_EQ(ret, buf.AsStringView());
59 }
60
TEST(CXFA_FMParserTest,Parse)61 TEST(CXFA_FMParserTest, Parse) {
62 const wchar_t input[] =
63 L"$ = Avg (-3, 5, -6, 12, -13);\n"
64 L"$ = Avg (Table2..Row[*].Cell1);\n"
65 L"\n"
66 L"if ($ ne -1)then\n"
67 L" border.fill.color.value = \"255,64,64\";\n"
68 L"else\n"
69 L" border.fill.color.value = \"20,170,13\";\n"
70 L"endif\n"
71 L"\n"
72 L"$";
73
74 const wchar_t ret[] =
75 L"(\nfunction ()\n{\n"
76 L"var pfm_ret = null;\n"
77 L"if (pfm_rt.is_obj(this))\n{\n"
78 L"pfm_rt.asgn_val_op(this, pfm_rt.Avg(pfm_rt.neg_op(3), 5, "
79 L"pfm_rt.neg_op(6), 12, pfm_rt.neg_op(13)));\n"
80 L"}\n"
81 L"if (pfm_rt.is_obj(this))\n{\n"
82 L"pfm_rt.asgn_val_op(this, pfm_rt.Avg(pfm_rt.dot_acc(pfm_rt.dotdot_acc("
83 L"Table2, \"Table2\", \"Row\", 1), \"\", \"Cell1\", 0, 0)));\n"
84 L"}\n"
85 L"if (pfm_rt.get_val(pfm_rt.neq_op(this, pfm_rt.neg_op(1))))\n{\n"
86 L"if (pfm_rt.is_obj(pfm_rt.dot_acc(pfm_rt.dot_acc(pfm_rt.dot_acc("
87 L"border, \"border\", \"fill\", 0, 0), \"\", \"color\", 0, 0), \"\", "
88 L"\"value\", 0, 0)))\n{\n"
89 L"pfm_rt.asgn_val_op(pfm_rt.dot_acc(pfm_rt.dot_acc("
90 L"pfm_rt.dot_acc(border, \"border\", \"fill\", 0, 0), \"\", "
91 L"\"color\", 0, 0), \"\", \"value\", 0, 0), \"255,64,64\");\n"
92 L"}\n"
93 L"}\nelse\n{\n"
94 L"if (pfm_rt.is_obj(pfm_rt.dot_acc(pfm_rt.dot_acc(pfm_rt.dot_acc("
95 L"border, \"border\", \"fill\", 0, 0), \"\", \"color\", 0, 0), \"\", "
96 L"\"value\", 0, 0)))\n{\n"
97 L"pfm_rt.asgn_val_op(pfm_rt.dot_acc(pfm_rt.dot_acc("
98 L"pfm_rt.dot_acc(border, \"border\", \"fill\", 0, 0), \"\", "
99 L"\"color\", 0, 0), \"\", \"value\", 0, 0), \"20,170,13\");\n"
100 L"}\n"
101 L"}\n"
102 L"pfm_ret = this;\n"
103 L"return pfm_rt.get_val(pfm_ret);\n"
104 L"}\n).call(this);\n";
105
106 auto parser = pdfium::MakeUnique<CXFA_FMParser>(input);
107 std::unique_ptr<CXFA_FMFunctionDefinition> ast = parser->Parse();
108 ASSERT(ast != nullptr);
109 EXPECT_FALSE(parser->HasError());
110
111 CXFA_FMToJavaScriptDepth::Reset();
112 CFX_WideTextBuf buf;
113 EXPECT_TRUE(ast->ToJavaScript(buf));
114 EXPECT_EQ(ret, buf.AsStringView());
115 }
116
TEST(CXFA_FMParserTest,MaxParseDepth)117 TEST(CXFA_FMParserTest, MaxParseDepth) {
118 auto parser = pdfium::MakeUnique<CXFA_FMParser>(L"foo(bar[baz(fizz[0])])");
119 parser->SetMaxParseDepthForTest(5);
120 EXPECT_EQ(nullptr, parser->Parse());
121 EXPECT_TRUE(parser->HasError());
122 }
123
TEST(CFXA_FMParserTest,chromium752201)124 TEST(CFXA_FMParserTest, chromium752201) {
125 auto parser = pdfium::MakeUnique<CXFA_FMParser>(
126 L"fTep a\n"
127 L".#\n"
128 L"fo@ =[=l");
129 EXPECT_EQ(nullptr, parser->Parse());
130 EXPECT_TRUE(parser->HasError());
131 }
132