OLD | NEW |
| (Empty) |
1 // Copyright 2015 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 #include <string> | |
7 | |
8 #include "core/fpdfapi/fpdf_parser/cpdf_parser.h" | |
9 #include "core/fpdfapi/fpdf_parser/cpdf_syntax_parser.h" | |
10 #include "core/fxcrt/fx_ext.h" | |
11 #include "core/fxcrt/fx_stream.h" | |
12 #include "testing/gtest/include/gtest/gtest.h" | |
13 #include "testing/utils/path_service.h" | |
14 | |
15 // Provide a way to read test data from a buffer instead of a file. | |
16 class CFX_TestBufferRead : public IFX_FileRead { | |
17 public: | |
18 CFX_TestBufferRead(const unsigned char* buffer_in, size_t buf_size) | |
19 : buffer_(buffer_in), total_size_(buf_size) {} | |
20 | |
21 // IFX_Stream | |
22 void Release() override { delete this; } | |
23 | |
24 // IFX_FileRead | |
25 FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override { | |
26 if (offset < 0 || offset + size > total_size_) { | |
27 return FALSE; | |
28 } | |
29 | |
30 memcpy(buffer, buffer_ + offset, size); | |
31 return TRUE; | |
32 } | |
33 FX_FILESIZE GetSize() override { return (FX_FILESIZE)total_size_; }; | |
34 | |
35 protected: | |
36 const unsigned char* buffer_; | |
37 size_t total_size_; | |
38 }; | |
39 | |
40 // A wrapper class to help test member functions of CPDF_Parser. | |
41 class CPDF_TestParser : public CPDF_Parser { | |
42 public: | |
43 CPDF_TestParser() {} | |
44 ~CPDF_TestParser() {} | |
45 | |
46 // Setup reading from a file and initial states. | |
47 bool InitTestFromFile(const FX_CHAR* path) { | |
48 IFX_FileRead* pFileAccess = FX_CreateFileRead(path); | |
49 if (!pFileAccess) | |
50 return false; | |
51 | |
52 // For the test file, the header is set at the beginning. | |
53 m_pSyntax->InitParser(pFileAccess, 0); | |
54 return true; | |
55 } | |
56 | |
57 // Setup reading from a buffer and initial states. | |
58 bool InitTestFromBuffer(const unsigned char* buffer, size_t len) { | |
59 CFX_TestBufferRead* buffer_reader = new CFX_TestBufferRead(buffer, len); | |
60 | |
61 // For the test file, the header is set at the beginning. | |
62 m_pSyntax->InitParser(buffer_reader, 0); | |
63 return true; | |
64 } | |
65 | |
66 private: | |
67 // Add test cases here as private friend so that protected members in | |
68 // CPDF_Parser can be accessed by test cases. | |
69 // Need to access RebuildCrossRef. | |
70 FRIEND_TEST(cpdf_parser, RebuildCrossRefCorrectly); | |
71 FRIEND_TEST(cpdf_parser, RebuildCrossRefFailed); | |
72 // Need to access LoadCrossRefV4. | |
73 FRIEND_TEST(cpdf_parser, LoadCrossRefV4); | |
74 }; | |
75 | |
76 TEST(cpdf_parser, RebuildCrossRefCorrectly) { | |
77 CPDF_TestParser parser; | |
78 std::string test_file; | |
79 ASSERT_TRUE(PathService::GetTestFilePath("parser_rebuildxref_correct.pdf", | |
80 &test_file)); | |
81 ASSERT_TRUE(parser.InitTestFromFile(test_file.c_str())) << test_file; | |
82 | |
83 ASSERT_TRUE(parser.RebuildCrossRef()); | |
84 const FX_FILESIZE offsets[] = {0, 15, 61, 154, 296, 374, 450}; | |
85 const uint16_t versions[] = {0, 0, 2, 4, 6, 8, 0}; | |
86 for (size_t i = 0; i < FX_ArraySize(offsets); ++i) | |
87 EXPECT_EQ(offsets[i], parser.m_ObjectInfo[i].pos); | |
88 for (size_t i = 0; i < FX_ArraySize(versions); ++i) | |
89 EXPECT_EQ(versions[i], parser.m_ObjectInfo[i].gennum); | |
90 } | |
91 | |
92 TEST(cpdf_parser, RebuildCrossRefFailed) { | |
93 CPDF_TestParser parser; | |
94 std::string test_file; | |
95 ASSERT_TRUE(PathService::GetTestFilePath( | |
96 "parser_rebuildxref_error_notrailer.pdf", &test_file)); | |
97 ASSERT_TRUE(parser.InitTestFromFile(test_file.c_str())) << test_file; | |
98 | |
99 ASSERT_FALSE(parser.RebuildCrossRef()); | |
100 } | |
101 | |
102 TEST(cpdf_parser, LoadCrossRefV4) { | |
103 { | |
104 const unsigned char xref_table[] = | |
105 "xref \n" | |
106 "0 6 \n" | |
107 "0000000003 65535 f \n" | |
108 "0000000017 00000 n \n" | |
109 "0000000081 00000 n \n" | |
110 "0000000000 00007 f \n" | |
111 "0000000331 00000 n \n" | |
112 "0000000409 00000 n \n" | |
113 "trail"; // Needed to end cross ref table reading. | |
114 CPDF_TestParser parser; | |
115 ASSERT_TRUE( | |
116 parser.InitTestFromBuffer(xref_table, FX_ArraySize(xref_table))); | |
117 | |
118 ASSERT_TRUE(parser.LoadCrossRefV4(0, 0, FALSE)); | |
119 const FX_FILESIZE offsets[] = {0, 17, 81, 0, 331, 409}; | |
120 const uint8_t types[] = {0, 1, 1, 0, 1, 1}; | |
121 for (size_t i = 0; i < FX_ArraySize(offsets); ++i) { | |
122 EXPECT_EQ(offsets[i], parser.m_ObjectInfo[i].pos); | |
123 EXPECT_EQ(types[i], parser.m_ObjectInfo[i].type); | |
124 } | |
125 } | |
126 { | |
127 const unsigned char xref_table[] = | |
128 "xref \n" | |
129 "0 1 \n" | |
130 "0000000000 65535 f \n" | |
131 "3 1 \n" | |
132 "0000025325 00000 n \n" | |
133 "8 2 \n" | |
134 "0000025518 00002 n \n" | |
135 "0000025635 00000 n \n" | |
136 "12 1 \n" | |
137 "0000025777 00000 n \n" | |
138 "trail"; // Needed to end cross ref table reading. | |
139 CPDF_TestParser parser; | |
140 ASSERT_TRUE( | |
141 parser.InitTestFromBuffer(xref_table, FX_ArraySize(xref_table))); | |
142 | |
143 ASSERT_TRUE(parser.LoadCrossRefV4(0, 0, FALSE)); | |
144 const FX_FILESIZE offsets[] = {0, 0, 0, 25325, 0, 0, 0, | |
145 0, 25518, 25635, 0, 0, 25777}; | |
146 const uint8_t types[] = {0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1}; | |
147 for (size_t i = 0; i < FX_ArraySize(offsets); ++i) { | |
148 EXPECT_EQ(offsets[i], parser.m_ObjectInfo[i].pos); | |
149 EXPECT_EQ(types[i], parser.m_ObjectInfo[i].type); | |
150 } | |
151 } | |
152 { | |
153 const unsigned char xref_table[] = | |
154 "xref \n" | |
155 "0 1 \n" | |
156 "0000000000 65535 f \n" | |
157 "3 1 \n" | |
158 "0000025325 00000 n \n" | |
159 "8 2 \n" | |
160 "0000000000 65535 f \n" | |
161 "0000025635 00000 n \n" | |
162 "12 1 \n" | |
163 "0000025777 00000 n \n" | |
164 "trail"; // Needed to end cross ref table reading. | |
165 CPDF_TestParser parser; | |
166 ASSERT_TRUE( | |
167 parser.InitTestFromBuffer(xref_table, FX_ArraySize(xref_table))); | |
168 | |
169 ASSERT_TRUE(parser.LoadCrossRefV4(0, 0, FALSE)); | |
170 const FX_FILESIZE offsets[] = {0, 0, 0, 25325, 0, 0, 0, | |
171 0, 0, 25635, 0, 0, 25777}; | |
172 const uint8_t types[] = {0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1}; | |
173 for (size_t i = 0; i < FX_ArraySize(offsets); ++i) { | |
174 EXPECT_EQ(offsets[i], parser.m_ObjectInfo[i].pos); | |
175 EXPECT_EQ(types[i], parser.m_ObjectInfo[i].type); | |
176 } | |
177 } | |
178 { | |
179 const unsigned char xref_table[] = | |
180 "xref \n" | |
181 "0 7 \n" | |
182 "0000000002 65535 f \n" | |
183 "0000000023 00000 n \n" | |
184 "0000000003 65535 f \n" | |
185 "0000000004 65535 f \n" | |
186 "0000000000 65535 f \n" | |
187 "0000000045 00000 n \n" | |
188 "0000000179 00000 n \n" | |
189 "trail"; // Needed to end cross ref table reading. | |
190 CPDF_TestParser parser; | |
191 ASSERT_TRUE( | |
192 parser.InitTestFromBuffer(xref_table, FX_ArraySize(xref_table))); | |
193 | |
194 ASSERT_TRUE(parser.LoadCrossRefV4(0, 0, FALSE)); | |
195 const FX_FILESIZE offsets[] = {0, 23, 0, 0, 0, 45, 179}; | |
196 const uint8_t types[] = {0, 1, 0, 0, 0, 1, 1}; | |
197 for (size_t i = 0; i < FX_ArraySize(offsets); ++i) { | |
198 EXPECT_EQ(offsets[i], parser.m_ObjectInfo[i].pos); | |
199 EXPECT_EQ(types[i], parser.m_ObjectInfo[i].type); | |
200 } | |
201 } | |
202 } | |
OLD | NEW |