• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <limits>
6 
7 #include "core/fpdfapi/page/cpdf_psengine.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 
10 namespace {
11 
DoOperator1(CPDF_PSEngine * engine,float v1,PDF_PSOP op)12 float DoOperator1(CPDF_PSEngine* engine, float v1, PDF_PSOP op) {
13   EXPECT_EQ(0u, engine->GetStackSize());
14   engine->Push(v1);
15   engine->DoOperator(op);
16   float ret = engine->Pop();
17   EXPECT_EQ(0u, engine->GetStackSize());
18   return ret;
19 }
20 
DoOperator2(CPDF_PSEngine * engine,float v1,float v2,PDF_PSOP op)21 float DoOperator2(CPDF_PSEngine* engine, float v1, float v2, PDF_PSOP op) {
22   EXPECT_EQ(0u, engine->GetStackSize());
23   engine->Push(v1);
24   engine->Push(v2);
25   engine->DoOperator(op);
26   float ret = engine->Pop();
27   EXPECT_EQ(0u, engine->GetStackSize());
28   return ret;
29 }
30 
31 }  // namespace
32 
TEST(CPDF_PSProc,AddOperator)33 TEST(CPDF_PSProc, AddOperator) {
34   static const struct {
35     const char* name;
36     PDF_PSOP op;
37   } kTestData[] = {
38       {"add", PSOP_ADD},         {"sub", PSOP_SUB},
39       {"mul", PSOP_MUL},         {"div", PSOP_DIV},
40       {"idiv", PSOP_IDIV},       {"mod", PSOP_MOD},
41       {"neg", PSOP_NEG},         {"abs", PSOP_ABS},
42       {"ceiling", PSOP_CEILING}, {"floor", PSOP_FLOOR},
43       {"round", PSOP_ROUND},     {"truncate", PSOP_TRUNCATE},
44       {"sqrt", PSOP_SQRT},       {"sin", PSOP_SIN},
45       {"cos", PSOP_COS},         {"atan", PSOP_ATAN},
46       {"exp", PSOP_EXP},         {"ln", PSOP_LN},
47       {"log", PSOP_LOG},         {"cvi", PSOP_CVI},
48       {"cvr", PSOP_CVR},         {"eq", PSOP_EQ},
49       {"ne", PSOP_NE},           {"gt", PSOP_GT},
50       {"ge", PSOP_GE},           {"lt", PSOP_LT},
51       {"le", PSOP_LE},           {"and", PSOP_AND},
52       {"or", PSOP_OR},           {"xor", PSOP_XOR},
53       {"not", PSOP_NOT},         {"bitshift", PSOP_BITSHIFT},
54       {"true", PSOP_TRUE},       {"false", PSOP_FALSE},
55       {"if", PSOP_IF},           {"ifelse", PSOP_IFELSE},
56       {"pop", PSOP_POP},         {"exch", PSOP_EXCH},
57       {"dup", PSOP_DUP},         {"copy", PSOP_COPY},
58       {"index", PSOP_INDEX},     {"roll", PSOP_ROLL},
59       {"55", PSOP_CONST},        {"123.4", PSOP_CONST},
60       {"-5", PSOP_CONST},        {"invalid", PSOP_CONST},
61   };
62 
63   CPDF_PSProc proc;
64   EXPECT_EQ(0U, proc.num_operators());
65   for (size_t i = 0; i < FX_ArraySize(kTestData); ++i) {
66     ByteStringView word(kTestData[i].name);
67     proc.AddOperatorForTesting(word);
68     ASSERT_EQ(i + 1, proc.num_operators());
69     const std::unique_ptr<CPDF_PSOP>& new_psop = proc.last_operator();
70     ASSERT_TRUE(new_psop);
71     PDF_PSOP new_op = new_psop->GetOp();
72     EXPECT_EQ(kTestData[i].op, new_op);
73     if (new_op == PSOP_CONST) {
74       float fv = new_psop->GetFloatValue();
75       if (word == "invalid")
76         EXPECT_FLOAT_EQ(0, fv);
77       else
78         EXPECT_EQ(word, ByteString::FormatFloat(fv));
79     }
80   }
81 }
82 
TEST(CPDF_PSEngine,Basic)83 TEST(CPDF_PSEngine, Basic) {
84   CPDF_PSEngine engine;
85 
86   EXPECT_FLOAT_EQ(300.0f, DoOperator2(&engine, 100, 200, PSOP_ADD));
87   EXPECT_FLOAT_EQ(-50.0f, DoOperator2(&engine, 100, 150, PSOP_SUB));
88   EXPECT_FLOAT_EQ(600.0f, DoOperator2(&engine, 5, 120, PSOP_MUL));
89   EXPECT_FLOAT_EQ(1.5f, DoOperator2(&engine, 15, 10, PSOP_DIV));
90   EXPECT_FLOAT_EQ(1.0f, DoOperator2(&engine, 15, 10, PSOP_IDIV));
91   EXPECT_FLOAT_EQ(5.0f, DoOperator2(&engine, 15, 10, PSOP_MOD));
92   EXPECT_FLOAT_EQ(5.0f, DoOperator1(&engine, -5, PSOP_NEG));
93   EXPECT_FLOAT_EQ(5.0f, DoOperator1(&engine, -5, PSOP_ABS));
94 }
95 
TEST(CPDF_PSEngine,Ceiling)96 TEST(CPDF_PSEngine, Ceiling) {
97   CPDF_PSEngine engine;
98 
99   // Smallest positive float value.
100   float min_float = std::numeric_limits<float>::min();
101   // Largest positive float value.
102   float max_float = std::numeric_limits<float>::max();
103   EXPECT_FLOAT_EQ(1.0f, DoOperator1(&engine, min_float, PSOP_CEILING));
104   EXPECT_FLOAT_EQ(max_float, DoOperator1(&engine, max_float, PSOP_CEILING));
105   EXPECT_FLOAT_EQ(0.0f, DoOperator1(&engine, -min_float, PSOP_CEILING));
106   EXPECT_FLOAT_EQ(-max_float, DoOperator1(&engine, -max_float, PSOP_CEILING));
107   EXPECT_FLOAT_EQ(0.0f, DoOperator1(&engine, -0.9f, PSOP_CEILING));
108   EXPECT_FLOAT_EQ(1.0f, DoOperator1(&engine, 0.0000000001f, PSOP_CEILING));
109   EXPECT_FLOAT_EQ(0.0f, DoOperator1(&engine, 0.0f, PSOP_CEILING));
110   EXPECT_FLOAT_EQ(3.0f, DoOperator1(&engine, 2.3f, PSOP_CEILING));
111   EXPECT_FLOAT_EQ(4.0f, DoOperator1(&engine, 3.8f, PSOP_CEILING));
112   EXPECT_FLOAT_EQ(6.0f, DoOperator1(&engine, 5.5f, PSOP_CEILING));
113   EXPECT_FLOAT_EQ(-2.0f, DoOperator1(&engine, -2.3f, PSOP_CEILING));
114   EXPECT_FLOAT_EQ(-3.0f, DoOperator1(&engine, -3.8f, PSOP_CEILING));
115   EXPECT_FLOAT_EQ(-5.0f, DoOperator1(&engine, -5.5f, PSOP_CEILING));
116 }
117 
TEST(CPDF_PSEngine,Floor)118 TEST(CPDF_PSEngine, Floor) {
119   CPDF_PSEngine engine;
120 
121   // Smallest positive float value.
122   float min_float = std::numeric_limits<float>::min();
123   // Largest positive float value.
124   float max_float = std::numeric_limits<float>::max();
125   EXPECT_FLOAT_EQ(0.0f, DoOperator1(&engine, min_float, PSOP_FLOOR));
126   EXPECT_FLOAT_EQ(max_float, DoOperator1(&engine, max_float, PSOP_FLOOR));
127   EXPECT_FLOAT_EQ(-1.0f, DoOperator1(&engine, -min_float, PSOP_FLOOR));
128   EXPECT_FLOAT_EQ(-max_float, DoOperator1(&engine, -max_float, PSOP_FLOOR));
129   EXPECT_FLOAT_EQ(5.0f, DoOperator1(&engine, 5.9f, PSOP_FLOOR));
130   EXPECT_FLOAT_EQ(-4.0f, DoOperator1(&engine, -4.0000000001f, PSOP_FLOOR));
131   EXPECT_FLOAT_EQ(0.0f, DoOperator1(&engine, 0.0f, PSOP_FLOOR));
132   EXPECT_FLOAT_EQ(-1.0f, DoOperator1(&engine, -0.9f, PSOP_FLOOR));
133   EXPECT_FLOAT_EQ(0.0f, DoOperator1(&engine, 0.0000000001f, PSOP_FLOOR));
134   EXPECT_FLOAT_EQ(0.0f, DoOperator1(&engine, 0.0f, PSOP_FLOOR));
135   EXPECT_FLOAT_EQ(2.0f, DoOperator1(&engine, 2.3f, PSOP_FLOOR));
136   EXPECT_FLOAT_EQ(3.0f, DoOperator1(&engine, 3.8f, PSOP_FLOOR));
137   EXPECT_FLOAT_EQ(5.0f, DoOperator1(&engine, 5.5f, PSOP_FLOOR));
138   EXPECT_FLOAT_EQ(-3.0f, DoOperator1(&engine, -2.3f, PSOP_FLOOR));
139   EXPECT_FLOAT_EQ(-4.0f, DoOperator1(&engine, -3.8f, PSOP_FLOOR));
140   EXPECT_FLOAT_EQ(-6.0f, DoOperator1(&engine, -5.5f, PSOP_FLOOR));
141 }
142 
TEST(CPDF_PSEngine,Round)143 TEST(CPDF_PSEngine, Round) {
144   CPDF_PSEngine engine;
145 
146   EXPECT_FLOAT_EQ(6.0f, DoOperator1(&engine, 5.9f, PSOP_ROUND));
147   EXPECT_FLOAT_EQ(-4.0f, DoOperator1(&engine, -4.0000000001f, PSOP_ROUND));
148   EXPECT_FLOAT_EQ(0.0f, DoOperator1(&engine, 0.0f, PSOP_ROUND));
149   EXPECT_FLOAT_EQ(-1.0f, DoOperator1(&engine, -0.9f, PSOP_ROUND));
150   EXPECT_FLOAT_EQ(0.0f, DoOperator1(&engine, 0.0000000001f, PSOP_ROUND));
151   EXPECT_FLOAT_EQ(0.0f, DoOperator1(&engine, 0.0f, PSOP_ROUND));
152   // Smallest positive float value.
153   float min_float = std::numeric_limits<float>::min();
154   // Largest positive float value.
155   float max_float = std::numeric_limits<float>::max();
156   EXPECT_FLOAT_EQ(0.0f, DoOperator1(&engine, min_float, PSOP_ROUND));
157   EXPECT_FLOAT_EQ(0.0f, DoOperator1(&engine, -min_float, PSOP_ROUND));
158   EXPECT_FLOAT_EQ(max_float, DoOperator1(&engine, max_float, PSOP_ROUND));
159   EXPECT_FLOAT_EQ(-max_float, DoOperator1(&engine, -max_float, PSOP_ROUND));
160   EXPECT_FLOAT_EQ(2.0f, DoOperator1(&engine, 2.3f, PSOP_ROUND));
161   EXPECT_FLOAT_EQ(4.0f, DoOperator1(&engine, 3.8f, PSOP_ROUND));
162   EXPECT_FLOAT_EQ(6.0f, DoOperator1(&engine, 5.5f, PSOP_ROUND));
163   EXPECT_FLOAT_EQ(-2.0f, DoOperator1(&engine, -2.3f, PSOP_ROUND));
164   EXPECT_FLOAT_EQ(-4.0f, DoOperator1(&engine, -3.8f, PSOP_ROUND));
165   EXPECT_FLOAT_EQ(-5.0f, DoOperator1(&engine, -5.5f, PSOP_ROUND));
166 }
167 
TEST(CPDF_PSEngine,Truncate)168 TEST(CPDF_PSEngine, Truncate) {
169   CPDF_PSEngine engine;
170 
171   EXPECT_FLOAT_EQ(0.0f, DoOperator1(&engine, -0.9f, PSOP_TRUNCATE));
172   EXPECT_FLOAT_EQ(0.0f, DoOperator1(&engine, 0.0000000001f, PSOP_TRUNCATE));
173   EXPECT_FLOAT_EQ(0.0f, DoOperator1(&engine, 0.0f, PSOP_TRUNCATE));
174   // Smallest positive float value.
175   float min_float = std::numeric_limits<float>::min();
176   EXPECT_FLOAT_EQ(0.0f, DoOperator1(&engine, min_float, PSOP_TRUNCATE));
177   EXPECT_FLOAT_EQ(0.0f, DoOperator1(&engine, -min_float, PSOP_TRUNCATE));
178   EXPECT_FLOAT_EQ(2.0f, DoOperator1(&engine, 2.3f, PSOP_TRUNCATE));
179   EXPECT_FLOAT_EQ(3.0f, DoOperator1(&engine, 3.8f, PSOP_TRUNCATE));
180   EXPECT_FLOAT_EQ(5.0f, DoOperator1(&engine, 5.5f, PSOP_TRUNCATE));
181   EXPECT_FLOAT_EQ(-2.0f, DoOperator1(&engine, -2.3f, PSOP_TRUNCATE));
182   EXPECT_FLOAT_EQ(-3.0f, DoOperator1(&engine, -3.8f, PSOP_TRUNCATE));
183   EXPECT_FLOAT_EQ(-5.0f, DoOperator1(&engine, -5.5f, PSOP_TRUNCATE));
184 
185   // Truncate does not behave according to the PostScript Language Reference for
186   // values beyond the range of integers. This seems to match Acrobat's
187   // behavior. See https://crbug.com/1314.
188   float max_int = std::numeric_limits<int>::max();
189   EXPECT_FLOAT_EQ(-max_int,
190                   DoOperator1(&engine, max_int * 2.0f, PSOP_TRUNCATE));
191   EXPECT_FLOAT_EQ(-max_int,
192                   DoOperator1(&engine, max_int * -1.5f, PSOP_TRUNCATE));
193 }
194