| OLD | NEW |
| 1 // Copyright 2015 PDFium Authors. All rights reserved. | 1 // Copyright 2015 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <limits> | 5 #include <limits> |
| 6 #include <string> | 6 #include <string> |
| 7 | 7 |
| 8 #include "core/include/fpdfapi/cpdf_parser.h" | 8 #include "core/include/fpdfapi/cpdf_parser.h" |
| 9 #include "core/include/fpdfapi/fpdf_parser.h" | |
| 10 #include "core/include/fxcrt/fx_stream.h" | 9 #include "core/include/fxcrt/fx_stream.h" |
| 11 #include "core/include/fxcrt/fx_ext.h" | 10 #include "core/include/fxcrt/fx_ext.h" |
| 12 #include "core/src/fpdfapi/fpdf_parser/cpdf_syntax_parser.h" | 11 #include "core/src/fpdfapi/fpdf_parser/cpdf_syntax_parser.h" |
| 13 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
| 14 #include "testing/utils/path_service.h" | 13 #include "testing/utils/path_service.h" |
| 15 | 14 |
| 16 // Provide a way to read test data from a buffer instead of a file. | 15 // Provide a way to read test data from a buffer instead of a file. |
| 17 class CFX_TestBufferRead : public IFX_FileRead { | 16 class CFX_TestBufferRead : public IFX_FileRead { |
| 18 public: | 17 public: |
| 19 CFX_TestBufferRead(const unsigned char* buffer_in, size_t buf_size) | 18 CFX_TestBufferRead(const unsigned char* buffer_in, size_t buf_size) |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 | 60 |
| 62 // For the test file, the header is set at the beginning. | 61 // For the test file, the header is set at the beginning. |
| 63 m_pSyntax->InitParser(buffer_reader, 0); | 62 m_pSyntax->InitParser(buffer_reader, 0); |
| 64 return true; | 63 return true; |
| 65 } | 64 } |
| 66 | 65 |
| 67 private: | 66 private: |
| 68 // Add test cases here as private friend so that protected members in | 67 // Add test cases here as private friend so that protected members in |
| 69 // CPDF_Parser can be accessed by test cases. | 68 // CPDF_Parser can be accessed by test cases. |
| 70 // Need to access RebuildCrossRef. | 69 // Need to access RebuildCrossRef. |
| 71 FRIEND_TEST(fpdf_parser_parser, RebuildCrossRefCorrectly); | 70 FRIEND_TEST(cpdf_parser, RebuildCrossRefCorrectly); |
| 72 FRIEND_TEST(fpdf_parser_parser, RebuildCrossRefFailed); | 71 FRIEND_TEST(cpdf_parser, RebuildCrossRefFailed); |
| 73 // Need to access LoadCrossRefV4. | 72 // Need to access LoadCrossRefV4. |
| 74 FRIEND_TEST(fpdf_parser_parser, LoadCrossRefV4); | 73 FRIEND_TEST(cpdf_parser, LoadCrossRefV4); |
| 75 }; | 74 }; |
| 76 | 75 |
| 77 TEST(fpdf_parser_parser, ReadHexString) { | 76 TEST(cpdf_parser, RebuildCrossRefCorrectly) { |
| 78 { | |
| 79 // Empty string. | |
| 80 uint8_t data[] = ""; | |
| 81 ScopedFileStream stream(FX_CreateMemoryStream(data, 0, FALSE)); | |
| 82 | |
| 83 CPDF_SyntaxParser parser; | |
| 84 parser.InitParser(stream.get(), 0); | |
| 85 EXPECT_EQ("", parser.ReadHexString()); | |
| 86 EXPECT_EQ(0, parser.SavePos()); | |
| 87 } | |
| 88 | |
| 89 { | |
| 90 // Blank string. | |
| 91 uint8_t data[] = " "; | |
| 92 ScopedFileStream stream(FX_CreateMemoryStream(data, 2, FALSE)); | |
| 93 | |
| 94 CPDF_SyntaxParser parser; | |
| 95 parser.InitParser(stream.get(), 0); | |
| 96 EXPECT_EQ("", parser.ReadHexString()); | |
| 97 EXPECT_EQ(2, parser.SavePos()); | |
| 98 } | |
| 99 | |
| 100 { | |
| 101 // Skips unknown characters. | |
| 102 uint8_t data[] = "z12b"; | |
| 103 ScopedFileStream stream(FX_CreateMemoryStream(data, 4, FALSE)); | |
| 104 | |
| 105 CPDF_SyntaxParser parser; | |
| 106 parser.InitParser(stream.get(), 0); | |
| 107 EXPECT_EQ("\x12\xb0", parser.ReadHexString()); | |
| 108 EXPECT_EQ(4, parser.SavePos()); | |
| 109 } | |
| 110 | |
| 111 { | |
| 112 // Skips unknown characters. | |
| 113 uint8_t data[] = "*<&*#$^&@1"; | |
| 114 ScopedFileStream stream(FX_CreateMemoryStream(data, 10, FALSE)); | |
| 115 | |
| 116 CPDF_SyntaxParser parser; | |
| 117 parser.InitParser(stream.get(), 0); | |
| 118 EXPECT_EQ("\x10", parser.ReadHexString()); | |
| 119 EXPECT_EQ(10, parser.SavePos()); | |
| 120 } | |
| 121 | |
| 122 { | |
| 123 // Skips unknown characters. | |
| 124 uint8_t data[] = "\x80zab"; | |
| 125 ScopedFileStream stream(FX_CreateMemoryStream(data, 4, FALSE)); | |
| 126 | |
| 127 CPDF_SyntaxParser parser; | |
| 128 parser.InitParser(stream.get(), 0); | |
| 129 EXPECT_EQ("\xab", parser.ReadHexString()); | |
| 130 EXPECT_EQ(4, parser.SavePos()); | |
| 131 } | |
| 132 | |
| 133 { | |
| 134 // Skips unknown characters. | |
| 135 uint8_t data[] = "\xffzab"; | |
| 136 ScopedFileStream stream(FX_CreateMemoryStream(data, 4, FALSE)); | |
| 137 | |
| 138 CPDF_SyntaxParser parser; | |
| 139 parser.InitParser(stream.get(), 0); | |
| 140 EXPECT_EQ("\xab", parser.ReadHexString()); | |
| 141 EXPECT_EQ(4, parser.SavePos()); | |
| 142 } | |
| 143 | |
| 144 { | |
| 145 // Regular conversion. | |
| 146 uint8_t data[] = "1A2b>abcd"; | |
| 147 ScopedFileStream stream(FX_CreateMemoryStream(data, 9, FALSE)); | |
| 148 | |
| 149 CPDF_SyntaxParser parser; | |
| 150 parser.InitParser(stream.get(), 0); | |
| 151 EXPECT_EQ("\x1a\x2b", parser.ReadHexString()); | |
| 152 EXPECT_EQ(5, parser.SavePos()); | |
| 153 } | |
| 154 | |
| 155 { | |
| 156 // Position out of bounds. | |
| 157 uint8_t data[] = "12ab>"; | |
| 158 ScopedFileStream stream(FX_CreateMemoryStream(data, 5, FALSE)); | |
| 159 | |
| 160 CPDF_SyntaxParser parser; | |
| 161 parser.InitParser(stream.get(), 0); | |
| 162 parser.RestorePos(5); | |
| 163 EXPECT_EQ("", parser.ReadHexString()); | |
| 164 | |
| 165 parser.RestorePos(6); | |
| 166 EXPECT_EQ("", parser.ReadHexString()); | |
| 167 | |
| 168 parser.RestorePos(-1); | |
| 169 EXPECT_EQ("", parser.ReadHexString()); | |
| 170 | |
| 171 parser.RestorePos(std::numeric_limits<FX_FILESIZE>::max()); | |
| 172 EXPECT_EQ("", parser.ReadHexString()); | |
| 173 | |
| 174 // Check string still parses when set to 0. | |
| 175 parser.RestorePos(0); | |
| 176 EXPECT_EQ("\x12\xab", parser.ReadHexString()); | |
| 177 } | |
| 178 | |
| 179 { | |
| 180 // Missing ending >. | |
| 181 uint8_t data[] = "1A2b"; | |
| 182 ScopedFileStream stream(FX_CreateMemoryStream(data, 4, FALSE)); | |
| 183 | |
| 184 CPDF_SyntaxParser parser; | |
| 185 parser.InitParser(stream.get(), 0); | |
| 186 EXPECT_EQ("\x1a\x2b", parser.ReadHexString()); | |
| 187 EXPECT_EQ(4, parser.SavePos()); | |
| 188 } | |
| 189 | |
| 190 { | |
| 191 // Missing ending >. | |
| 192 uint8_t data[] = "12abz"; | |
| 193 ScopedFileStream stream(FX_CreateMemoryStream(data, 5, FALSE)); | |
| 194 | |
| 195 CPDF_SyntaxParser parser; | |
| 196 parser.InitParser(stream.get(), 0); | |
| 197 EXPECT_EQ("\x12\xab", parser.ReadHexString()); | |
| 198 EXPECT_EQ(5, parser.SavePos()); | |
| 199 } | |
| 200 | |
| 201 { | |
| 202 // Uneven number of bytes. | |
| 203 uint8_t data[] = "1A2>asdf"; | |
| 204 ScopedFileStream stream(FX_CreateMemoryStream(data, 8, FALSE)); | |
| 205 | |
| 206 CPDF_SyntaxParser parser; | |
| 207 parser.InitParser(stream.get(), 0); | |
| 208 EXPECT_EQ("\x1a\x20", parser.ReadHexString()); | |
| 209 EXPECT_EQ(4, parser.SavePos()); | |
| 210 } | |
| 211 | |
| 212 { | |
| 213 // Uneven number of bytes. | |
| 214 uint8_t data[] = "1A2zasdf"; | |
| 215 ScopedFileStream stream(FX_CreateMemoryStream(data, 8, FALSE)); | |
| 216 | |
| 217 CPDF_SyntaxParser parser; | |
| 218 parser.InitParser(stream.get(), 0); | |
| 219 EXPECT_EQ("\x1a\x2a\xdf", parser.ReadHexString()); | |
| 220 EXPECT_EQ(8, parser.SavePos()); | |
| 221 } | |
| 222 | |
| 223 { | |
| 224 // Just ending character. | |
| 225 uint8_t data[] = ">"; | |
| 226 ScopedFileStream stream(FX_CreateMemoryStream(data, 1, FALSE)); | |
| 227 | |
| 228 CPDF_SyntaxParser parser; | |
| 229 parser.InitParser(stream.get(), 0); | |
| 230 EXPECT_EQ("", parser.ReadHexString()); | |
| 231 EXPECT_EQ(1, parser.SavePos()); | |
| 232 } | |
| 233 } | |
| 234 | |
| 235 TEST(fpdf_parser_parser, RebuildCrossRefCorrectly) { | |
| 236 CPDF_TestParser parser; | 77 CPDF_TestParser parser; |
| 237 std::string test_file; | 78 std::string test_file; |
| 238 ASSERT_TRUE(PathService::GetTestFilePath("parser_rebuildxref_correct.pdf", | 79 ASSERT_TRUE(PathService::GetTestFilePath("parser_rebuildxref_correct.pdf", |
| 239 &test_file)); | 80 &test_file)); |
| 240 ASSERT_TRUE(parser.InitTestFromFile(test_file.c_str())) << test_file; | 81 ASSERT_TRUE(parser.InitTestFromFile(test_file.c_str())) << test_file; |
| 241 | 82 |
| 242 ASSERT_TRUE(parser.RebuildCrossRef()); | 83 ASSERT_TRUE(parser.RebuildCrossRef()); |
| 243 const FX_FILESIZE offsets[] = {0, 15, 61, 154, 296, 374, 450}; | 84 const FX_FILESIZE offsets[] = {0, 15, 61, 154, 296, 374, 450}; |
| 244 const FX_WORD versions[] = {0, 0, 2, 4, 6, 8, 0}; | 85 const FX_WORD versions[] = {0, 0, 2, 4, 6, 8, 0}; |
| 245 for (size_t i = 0; i < FX_ArraySize(offsets); ++i) | 86 for (size_t i = 0; i < FX_ArraySize(offsets); ++i) |
| 246 EXPECT_EQ(offsets[i], parser.m_ObjectInfo[i].pos); | 87 EXPECT_EQ(offsets[i], parser.m_ObjectInfo[i].pos); |
| 247 for (size_t i = 0; i < FX_ArraySize(versions); ++i) | 88 for (size_t i = 0; i < FX_ArraySize(versions); ++i) |
| 248 EXPECT_EQ(versions[i], parser.m_ObjectInfo[i].gennum); | 89 EXPECT_EQ(versions[i], parser.m_ObjectInfo[i].gennum); |
| 249 } | 90 } |
| 250 | 91 |
| 251 TEST(fpdf_parser_parser, RebuildCrossRefFailed) { | 92 TEST(cpdf_parser, RebuildCrossRefFailed) { |
| 252 CPDF_TestParser parser; | 93 CPDF_TestParser parser; |
| 253 std::string test_file; | 94 std::string test_file; |
| 254 ASSERT_TRUE(PathService::GetTestFilePath( | 95 ASSERT_TRUE(PathService::GetTestFilePath( |
| 255 "parser_rebuildxref_error_notrailer.pdf", &test_file)); | 96 "parser_rebuildxref_error_notrailer.pdf", &test_file)); |
| 256 ASSERT_TRUE(parser.InitTestFromFile(test_file.c_str())) << test_file; | 97 ASSERT_TRUE(parser.InitTestFromFile(test_file.c_str())) << test_file; |
| 257 | 98 |
| 258 ASSERT_FALSE(parser.RebuildCrossRef()); | 99 ASSERT_FALSE(parser.RebuildCrossRef()); |
| 259 } | 100 } |
| 260 | 101 |
| 261 TEST(fpdf_parser_parser, LoadCrossRefV4) { | 102 TEST(cpdf_parser, LoadCrossRefV4) { |
| 262 { | 103 { |
| 263 const unsigned char xref_table[] = | 104 const unsigned char xref_table[] = |
| 264 "xref \n" | 105 "xref \n" |
| 265 "0 6 \n" | 106 "0 6 \n" |
| 266 "0000000003 65535 f \n" | 107 "0000000003 65535 f \n" |
| 267 "0000000017 00000 n \n" | 108 "0000000017 00000 n \n" |
| 268 "0000000081 00000 n \n" | 109 "0000000081 00000 n \n" |
| 269 "0000000000 00007 f \n" | 110 "0000000000 00007 f \n" |
| 270 "0000000331 00000 n \n" | 111 "0000000331 00000 n \n" |
| 271 "0000000409 00000 n \n" | 112 "0000000409 00000 n \n" |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 | 193 |
| 353 ASSERT_TRUE(parser.LoadCrossRefV4(0, 0, FALSE)); | 194 ASSERT_TRUE(parser.LoadCrossRefV4(0, 0, FALSE)); |
| 354 const FX_FILESIZE offsets[] = {0, 23, 0, 0, 0, 45, 179}; | 195 const FX_FILESIZE offsets[] = {0, 23, 0, 0, 0, 45, 179}; |
| 355 const uint8_t types[] = {0, 1, 0, 0, 0, 1, 1}; | 196 const uint8_t types[] = {0, 1, 0, 0, 0, 1, 1}; |
| 356 for (size_t i = 0; i < FX_ArraySize(offsets); ++i) { | 197 for (size_t i = 0; i < FX_ArraySize(offsets); ++i) { |
| 357 EXPECT_EQ(offsets[i], parser.m_ObjectInfo[i].pos); | 198 EXPECT_EQ(offsets[i], parser.m_ObjectInfo[i].pos); |
| 358 EXPECT_EQ(types[i], parser.m_ObjectInfo[i].type); | 199 EXPECT_EQ(types[i], parser.m_ObjectInfo[i].type); |
| 359 } | 200 } |
| 360 } | 201 } |
| 361 } | 202 } |
| OLD | NEW |