| OLD | NEW |
| 1 // Copyright 2016 PDFium Authors. All rights reserved. | 1 // Copyright 2016 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 "core/fpdfapi/parser/cpdf_array.h" | 5 #include "core/fpdfapi/parser/cpdf_array.h" |
| 6 #include "core/fpdfapi/parser/cpdf_boolean.h" | 6 #include "core/fpdfapi/parser/cpdf_boolean.h" |
| 7 #include "core/fpdfapi/parser/cpdf_dictionary.h" | 7 #include "core/fpdfapi/parser/cpdf_dictionary.h" |
| 8 #include "core/fpdfapi/parser/cpdf_name.h" | 8 #include "core/fpdfapi/parser/cpdf_name.h" |
| 9 #include "core/fpdfapi/parser/cpdf_null.h" | 9 #include "core/fpdfapi/parser/cpdf_null.h" |
| 10 #include "core/fpdfapi/parser/cpdf_number.h" | 10 #include "core/fpdfapi/parser/cpdf_number.h" |
| 11 #include "core/fpdfapi/parser/cpdf_reference.h" | 11 #include "core/fpdfapi/parser/cpdf_reference.h" |
| 12 #include "core/fpdfapi/parser/cpdf_stream.h" | 12 #include "core/fpdfapi/parser/cpdf_stream.h" |
| 13 #include "core/fpdfapi/parser/cpdf_string.h" | 13 #include "core/fpdfapi/parser/cpdf_string.h" |
| 14 | 14 |
| 15 #include <memory> | 15 #include <memory> |
| 16 #include <string> | 16 #include <string> |
| 17 #include <vector> | 17 #include <vector> |
| 18 | 18 |
| 19 #include "core/fpdfapi/parser/cpdf_indirect_object_holder.h" | 19 #include "core/fpdfapi/parser/cpdf_indirect_object_holder.h" |
| 20 #include "core/fxcrt/fx_basic.h" | 20 #include "core/fxcrt/fx_basic.h" |
| 21 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
| 22 | 22 |
| 23 namespace { | 23 namespace { |
| 24 | 24 |
| 25 using ScopedArray = std::unique_ptr<CPDF_Array, ReleaseDeleter<CPDF_Array>>; |
| 26 using ScopedDict = |
| 27 std::unique_ptr<CPDF_Dictionary, ReleaseDeleter<CPDF_Dictionary>>; |
| 28 using ScopedStream = std::unique_ptr<CPDF_Stream, ReleaseDeleter<CPDF_Stream>>; |
| 29 |
| 25 void TestArrayAccessors(const CPDF_Array* arr, | 30 void TestArrayAccessors(const CPDF_Array* arr, |
| 26 size_t index, | 31 size_t index, |
| 27 const char* str_val, | 32 const char* str_val, |
| 28 const char* const_str_val, | 33 const char* const_str_val, |
| 29 int int_val, | 34 int int_val, |
| 30 float float_val, | 35 float float_val, |
| 31 CPDF_Array* arr_val, | 36 CPDF_Array* arr_val, |
| 32 CPDF_Dictionary* dict_val, | 37 CPDF_Dictionary* dict_val, |
| 33 CPDF_Stream* stream_val) { | 38 CPDF_Stream* stream_val) { |
| 34 EXPECT_STREQ(str_val, arr->GetStringAt(index).c_str()); | 39 EXPECT_STREQ(str_val, arr->GetStringAt(index).c_str()); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 stream1->GetRawSize()) == 0; | 166 stream1->GetRawSize()) == 0; |
| 162 } | 167 } |
| 163 case CPDF_Object::REFERENCE: | 168 case CPDF_Object::REFERENCE: |
| 164 return obj1->AsReference()->GetRefObjNum() == | 169 return obj1->AsReference()->GetRefObjNum() == |
| 165 obj2->AsReference()->GetRefObjNum(); | 170 obj2->AsReference()->GetRefObjNum(); |
| 166 } | 171 } |
| 167 return false; | 172 return false; |
| 168 } | 173 } |
| 169 | 174 |
| 170 protected: | 175 protected: |
| 176 using ScopedObj = std::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>>; |
| 177 |
| 171 // m_ObjHolder needs to be declared first and destructed last since it also | 178 // m_ObjHolder needs to be declared first and destructed last since it also |
| 172 // refers to some objects in m_DirectObjs. | 179 // refers to some objects in m_DirectObjs. |
| 173 std::unique_ptr<CPDF_IndirectObjectHolder> m_ObjHolder; | 180 std::unique_ptr<CPDF_IndirectObjectHolder> m_ObjHolder; |
| 174 std::vector<std::unique_ptr<CPDF_Object>> m_DirectObjs; | 181 std::vector<ScopedObj> m_DirectObjs; |
| 175 std::vector<int> m_DirectObjTypes; | 182 std::vector<int> m_DirectObjTypes; |
| 176 std::vector<std::unique_ptr<CPDF_Object>> m_RefObjs; | 183 std::vector<ScopedObj> m_RefObjs; |
| 177 CPDF_Dictionary* m_DictObj; | 184 CPDF_Dictionary* m_DictObj; |
| 178 CPDF_Dictionary* m_StreamDictObj; | 185 CPDF_Dictionary* m_StreamDictObj; |
| 179 CPDF_Array* m_ArrayObj; | 186 CPDF_Array* m_ArrayObj; |
| 180 std::vector<CPDF_Object*> m_IndirectObjs; | 187 std::vector<CPDF_Object*> m_IndirectObjs; |
| 181 }; | 188 }; |
| 182 | 189 |
| 183 TEST_F(PDFObjectsTest, GetString) { | 190 TEST_F(PDFObjectsTest, GetString) { |
| 184 const char* const direct_obj_results[] = { | 191 const char* const direct_obj_results[] = { |
| 185 "false", "true", "1245", "9.00345", "A simple test", "\t\n", "space", | 192 "false", "true", "1245", "9.00345", "A simple test", "\t\n", "space", |
| 186 "", "", "", ""}; | 193 "", "", "", ""}; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 EXPECT_EQ(direct_obj_results[i], m_DirectObjs[i]->AsArray()); | 268 EXPECT_EQ(direct_obj_results[i], m_DirectObjs[i]->AsArray()); |
| 262 | 269 |
| 263 // Check indirect references. | 270 // Check indirect references. |
| 264 for (const auto& it : m_RefObjs) | 271 for (const auto& it : m_RefObjs) |
| 265 EXPECT_EQ(nullptr, it->AsArray()); | 272 EXPECT_EQ(nullptr, it->AsArray()); |
| 266 } | 273 } |
| 267 | 274 |
| 268 TEST_F(PDFObjectsTest, Clone) { | 275 TEST_F(PDFObjectsTest, Clone) { |
| 269 // Check for direct objects. | 276 // Check for direct objects. |
| 270 for (size_t i = 0; i < m_DirectObjs.size(); ++i) { | 277 for (size_t i = 0; i < m_DirectObjs.size(); ++i) { |
| 271 std::unique_ptr<CPDF_Object> obj(m_DirectObjs[i]->Clone()); | 278 ScopedObj obj(m_DirectObjs[i]->Clone()); |
| 272 EXPECT_TRUE(Equal(m_DirectObjs[i].get(), obj.get())); | 279 EXPECT_TRUE(Equal(m_DirectObjs[i].get(), obj.get())); |
| 273 } | 280 } |
| 274 | 281 |
| 275 // Check indirect references. | 282 // Check indirect references. |
| 276 for (const auto& it : m_RefObjs) { | 283 for (const auto& it : m_RefObjs) { |
| 277 std::unique_ptr<CPDF_Object> obj(it->Clone()); | 284 ScopedObj obj(it->Clone()); |
| 278 EXPECT_TRUE(Equal(it.get(), obj.get())); | 285 EXPECT_TRUE(Equal(it.get(), obj.get())); |
| 279 } | 286 } |
| 280 } | 287 } |
| 281 | 288 |
| 282 TEST_F(PDFObjectsTest, GetType) { | 289 TEST_F(PDFObjectsTest, GetType) { |
| 283 // Check for direct objects. | 290 // Check for direct objects. |
| 284 for (size_t i = 0; i < m_DirectObjs.size(); ++i) | 291 for (size_t i = 0; i < m_DirectObjs.size(); ++i) |
| 285 EXPECT_EQ(m_DirectObjTypes[i], m_DirectObjs[i]->GetType()); | 292 EXPECT_EQ(m_DirectObjTypes[i], m_DirectObjs[i]->GetType()); |
| 286 | 293 |
| 287 // Check indirect references. | 294 // Check indirect references. |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 EXPECT_EQ(m_RefObjs[i].get(), m_RefObjs[i]->AsReference()); | 386 EXPECT_EQ(m_RefObjs[i].get(), m_RefObjs[i]->AsReference()); |
| 380 } | 387 } |
| 381 } | 388 } |
| 382 | 389 |
| 383 TEST(PDFArrayTest, GetMatrix) { | 390 TEST(PDFArrayTest, GetMatrix) { |
| 384 float elems[][6] = {{0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, | 391 float elems[][6] = {{0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, |
| 385 {1, 2, 3, 4, 5, 6}, | 392 {1, 2, 3, 4, 5, 6}, |
| 386 {2.3f, 4.05f, 3, -2, -3, 0.0f}, | 393 {2.3f, 4.05f, 3, -2, -3, 0.0f}, |
| 387 {0.05f, 0.1f, 0.56f, 0.67f, 1.34f, 99.9f}}; | 394 {0.05f, 0.1f, 0.56f, 0.67f, 1.34f, 99.9f}}; |
| 388 for (size_t i = 0; i < FX_ArraySize(elems); ++i) { | 395 for (size_t i = 0; i < FX_ArraySize(elems); ++i) { |
| 389 std::unique_ptr<CPDF_Array> arr(new CPDF_Array); | 396 ScopedArray arr(new CPDF_Array); |
| 390 CFX_Matrix matrix(elems[i][0], elems[i][1], elems[i][2], elems[i][3], | 397 CFX_Matrix matrix(elems[i][0], elems[i][1], elems[i][2], elems[i][3], |
| 391 elems[i][4], elems[i][5]); | 398 elems[i][4], elems[i][5]); |
| 392 for (size_t j = 0; j < 6; ++j) | 399 for (size_t j = 0; j < 6; ++j) |
| 393 arr->AddNumber(elems[i][j]); | 400 arr->AddNumber(elems[i][j]); |
| 394 CFX_Matrix arr_matrix = arr->GetMatrix(); | 401 CFX_Matrix arr_matrix = arr->GetMatrix(); |
| 395 EXPECT_EQ(matrix.GetA(), arr_matrix.GetA()); | 402 EXPECT_EQ(matrix.GetA(), arr_matrix.GetA()); |
| 396 EXPECT_EQ(matrix.GetB(), arr_matrix.GetB()); | 403 EXPECT_EQ(matrix.GetB(), arr_matrix.GetB()); |
| 397 EXPECT_EQ(matrix.GetC(), arr_matrix.GetC()); | 404 EXPECT_EQ(matrix.GetC(), arr_matrix.GetC()); |
| 398 EXPECT_EQ(matrix.GetD(), arr_matrix.GetD()); | 405 EXPECT_EQ(matrix.GetD(), arr_matrix.GetD()); |
| 399 EXPECT_EQ(matrix.GetE(), arr_matrix.GetE()); | 406 EXPECT_EQ(matrix.GetE(), arr_matrix.GetE()); |
| 400 EXPECT_EQ(matrix.GetF(), arr_matrix.GetF()); | 407 EXPECT_EQ(matrix.GetF(), arr_matrix.GetF()); |
| 401 } | 408 } |
| 402 } | 409 } |
| 403 | 410 |
| 404 TEST(PDFArrayTest, GetRect) { | 411 TEST(PDFArrayTest, GetRect) { |
| 405 float elems[][4] = {{0.0f, 0.0f, 0.0f, 0.0f}, | 412 float elems[][4] = {{0.0f, 0.0f, 0.0f, 0.0f}, |
| 406 {1, 2, 5, 6}, | 413 {1, 2, 5, 6}, |
| 407 {2.3f, 4.05f, -3, 0.0f}, | 414 {2.3f, 4.05f, -3, 0.0f}, |
| 408 {0.05f, 0.1f, 1.34f, 99.9f}}; | 415 {0.05f, 0.1f, 1.34f, 99.9f}}; |
| 409 for (size_t i = 0; i < FX_ArraySize(elems); ++i) { | 416 for (size_t i = 0; i < FX_ArraySize(elems); ++i) { |
| 410 std::unique_ptr<CPDF_Array> arr(new CPDF_Array); | 417 ScopedArray arr(new CPDF_Array); |
| 411 CFX_FloatRect rect(elems[i]); | 418 CFX_FloatRect rect(elems[i]); |
| 412 for (size_t j = 0; j < 4; ++j) | 419 for (size_t j = 0; j < 4; ++j) |
| 413 arr->AddNumber(elems[i][j]); | 420 arr->AddNumber(elems[i][j]); |
| 414 CFX_FloatRect arr_rect = arr->GetRect(); | 421 CFX_FloatRect arr_rect = arr->GetRect(); |
| 415 EXPECT_EQ(rect.left, arr_rect.left); | 422 EXPECT_EQ(rect.left, arr_rect.left); |
| 416 EXPECT_EQ(rect.right, arr_rect.right); | 423 EXPECT_EQ(rect.right, arr_rect.right); |
| 417 EXPECT_EQ(rect.bottom, arr_rect.bottom); | 424 EXPECT_EQ(rect.bottom, arr_rect.bottom); |
| 418 EXPECT_EQ(rect.top, arr_rect.top); | 425 EXPECT_EQ(rect.top, arr_rect.top); |
| 419 } | 426 } |
| 420 } | 427 } |
| 421 | 428 |
| 422 TEST(PDFArrayTest, GetTypeAt) { | 429 TEST(PDFArrayTest, GetTypeAt) { |
| 423 { | 430 { |
| 424 // Boolean array. | 431 // Boolean array. |
| 425 const bool vals[] = {true, false, false, true, true}; | 432 const bool vals[] = {true, false, false, true, true}; |
| 426 std::unique_ptr<CPDF_Array> arr(new CPDF_Array); | 433 ScopedArray arr(new CPDF_Array); |
| 427 for (size_t i = 0; i < FX_ArraySize(vals); ++i) | 434 for (size_t i = 0; i < FX_ArraySize(vals); ++i) |
| 428 arr->InsertAt(i, new CPDF_Boolean(vals[i])); | 435 arr->InsertAt(i, new CPDF_Boolean(vals[i])); |
| 429 for (size_t i = 0; i < FX_ArraySize(vals); ++i) { | 436 for (size_t i = 0; i < FX_ArraySize(vals); ++i) { |
| 430 TestArrayAccessors(arr.get(), i, // Array and index. | 437 TestArrayAccessors(arr.get(), i, // Array and index. |
| 431 vals[i] ? "true" : "false", // String value. | 438 vals[i] ? "true" : "false", // String value. |
| 432 nullptr, // Const string value. | 439 nullptr, // Const string value. |
| 433 vals[i] ? 1 : 0, // Integer value. | 440 vals[i] ? 1 : 0, // Integer value. |
| 434 0, // Float value. | 441 0, // Float value. |
| 435 nullptr, // Array value. | 442 nullptr, // Array value. |
| 436 nullptr, // Dictionary value. | 443 nullptr, // Dictionary value. |
| 437 nullptr); // Stream value. | 444 nullptr); // Stream value. |
| 438 } | 445 } |
| 439 } | 446 } |
| 440 { | 447 { |
| 441 // Integer array. | 448 // Integer array. |
| 442 const int vals[] = {10, 0, -345, 2089345456, -1000000000, 567, 93658767}; | 449 const int vals[] = {10, 0, -345, 2089345456, -1000000000, 567, 93658767}; |
| 443 std::unique_ptr<CPDF_Array> arr(new CPDF_Array); | 450 ScopedArray arr(new CPDF_Array); |
| 444 for (size_t i = 0; i < FX_ArraySize(vals); ++i) | 451 for (size_t i = 0; i < FX_ArraySize(vals); ++i) |
| 445 arr->InsertAt(i, new CPDF_Number(vals[i])); | 452 arr->InsertAt(i, new CPDF_Number(vals[i])); |
| 446 for (size_t i = 0; i < FX_ArraySize(vals); ++i) { | 453 for (size_t i = 0; i < FX_ArraySize(vals); ++i) { |
| 447 char buf[33]; | 454 char buf[33]; |
| 448 TestArrayAccessors(arr.get(), i, // Array and index. | 455 TestArrayAccessors(arr.get(), i, // Array and index. |
| 449 FXSYS_itoa(vals[i], buf, 10), // String value. | 456 FXSYS_itoa(vals[i], buf, 10), // String value. |
| 450 nullptr, // Const string value. | 457 nullptr, // Const string value. |
| 451 vals[i], // Integer value. | 458 vals[i], // Integer value. |
| 452 vals[i], // Float value. | 459 vals[i], // Float value. |
| 453 nullptr, // Array value. | 460 nullptr, // Array value. |
| 454 nullptr, // Dictionary value. | 461 nullptr, // Dictionary value. |
| 455 nullptr); // Stream value. | 462 nullptr); // Stream value. |
| 456 } | 463 } |
| 457 } | 464 } |
| 458 { | 465 { |
| 459 // Float array. | 466 // Float array. |
| 460 const float vals[] = {0.0f, 0, 10, 10.0f, 0.0345f, | 467 const float vals[] = {0.0f, 0, 10, 10.0f, 0.0345f, |
| 461 897.34f, -2.5f, -1.0f, -345.0f, -0.0f}; | 468 897.34f, -2.5f, -1.0f, -345.0f, -0.0f}; |
| 462 const char* const expected_str[] = { | 469 const char* const expected_str[] = { |
| 463 "0", "0", "10", "10", "0.0345", "897.34", "-2.5", "-1", "-345", "0"}; | 470 "0", "0", "10", "10", "0.0345", "897.34", "-2.5", "-1", "-345", "0"}; |
| 464 std::unique_ptr<CPDF_Array> arr(new CPDF_Array); | 471 ScopedArray arr(new CPDF_Array); |
| 465 for (size_t i = 0; i < FX_ArraySize(vals); ++i) { | 472 for (size_t i = 0; i < FX_ArraySize(vals); ++i) { |
| 466 arr->InsertAt(i, new CPDF_Number(vals[i])); | 473 arr->InsertAt(i, new CPDF_Number(vals[i])); |
| 467 } | 474 } |
| 468 for (size_t i = 0; i < FX_ArraySize(vals); ++i) { | 475 for (size_t i = 0; i < FX_ArraySize(vals); ++i) { |
| 469 TestArrayAccessors(arr.get(), i, // Array and index. | 476 TestArrayAccessors(arr.get(), i, // Array and index. |
| 470 expected_str[i], // String value. | 477 expected_str[i], // String value. |
| 471 nullptr, // Const string value. | 478 nullptr, // Const string value. |
| 472 vals[i], // Integer value. | 479 vals[i], // Integer value. |
| 473 vals[i], // Float value. | 480 vals[i], // Float value. |
| 474 nullptr, // Array value. | 481 nullptr, // Array value. |
| 475 nullptr, // Dictionary value. | 482 nullptr, // Dictionary value. |
| 476 nullptr); // Stream value. | 483 nullptr); // Stream value. |
| 477 } | 484 } |
| 478 } | 485 } |
| 479 { | 486 { |
| 480 // String and name array | 487 // String and name array |
| 481 const char* const vals[] = {"this", "adsde$%^", "\r\t", "\"012", | 488 const char* const vals[] = {"this", "adsde$%^", "\r\t", "\"012", |
| 482 ".", "EYREW", "It is a joke :)"}; | 489 ".", "EYREW", "It is a joke :)"}; |
| 483 std::unique_ptr<CPDF_Array> string_array(new CPDF_Array); | 490 ScopedArray string_array(new CPDF_Array); |
| 484 std::unique_ptr<CPDF_Array> name_array(new CPDF_Array); | 491 ScopedArray name_array(new CPDF_Array); |
| 485 for (size_t i = 0; i < FX_ArraySize(vals); ++i) { | 492 for (size_t i = 0; i < FX_ArraySize(vals); ++i) { |
| 486 string_array->InsertAt(i, new CPDF_String(vals[i], false)); | 493 string_array->InsertAt(i, new CPDF_String(vals[i], false)); |
| 487 name_array->InsertAt(i, new CPDF_Name(vals[i])); | 494 name_array->InsertAt(i, new CPDF_Name(vals[i])); |
| 488 } | 495 } |
| 489 for (size_t i = 0; i < FX_ArraySize(vals); ++i) { | 496 for (size_t i = 0; i < FX_ArraySize(vals); ++i) { |
| 490 TestArrayAccessors(string_array.get(), i, // Array and index. | 497 TestArrayAccessors(string_array.get(), i, // Array and index. |
| 491 vals[i], // String value. | 498 vals[i], // String value. |
| 492 vals[i], // Const string value. | 499 vals[i], // Const string value. |
| 493 0, // Integer value. | 500 0, // Integer value. |
| 494 0, // Float value. | 501 0, // Float value. |
| 495 nullptr, // Array value. | 502 nullptr, // Array value. |
| 496 nullptr, // Dictionary value. | 503 nullptr, // Dictionary value. |
| 497 nullptr); // Stream value. | 504 nullptr); // Stream value. |
| 498 TestArrayAccessors(name_array.get(), i, // Array and index. | 505 TestArrayAccessors(name_array.get(), i, // Array and index. |
| 499 vals[i], // String value. | 506 vals[i], // String value. |
| 500 vals[i], // Const string value. | 507 vals[i], // Const string value. |
| 501 0, // Integer value. | 508 0, // Integer value. |
| 502 0, // Float value. | 509 0, // Float value. |
| 503 nullptr, // Array value. | 510 nullptr, // Array value. |
| 504 nullptr, // Dictionary value. | 511 nullptr, // Dictionary value. |
| 505 nullptr); // Stream value. | 512 nullptr); // Stream value. |
| 506 } | 513 } |
| 507 } | 514 } |
| 508 { | 515 { |
| 509 // Null element array. | 516 // Null element array. |
| 510 std::unique_ptr<CPDF_Array> arr(new CPDF_Array); | 517 ScopedArray arr(new CPDF_Array); |
| 511 for (size_t i = 0; i < 3; ++i) | 518 for (size_t i = 0; i < 3; ++i) |
| 512 arr->InsertAt(i, new CPDF_Null); | 519 arr->InsertAt(i, new CPDF_Null); |
| 513 for (size_t i = 0; i < 3; ++i) { | 520 for (size_t i = 0; i < 3; ++i) { |
| 514 TestArrayAccessors(arr.get(), i, // Array and index. | 521 TestArrayAccessors(arr.get(), i, // Array and index. |
| 515 "", // String value. | 522 "", // String value. |
| 516 nullptr, // Const string value. | 523 nullptr, // Const string value. |
| 517 0, // Integer value. | 524 0, // Integer value. |
| 518 0, // Float value. | 525 0, // Float value. |
| 519 nullptr, // Array value. | 526 nullptr, // Array value. |
| 520 nullptr, // Dictionary value. | 527 nullptr, // Dictionary value. |
| 521 nullptr); // Stream value. | 528 nullptr); // Stream value. |
| 522 } | 529 } |
| 523 } | 530 } |
| 524 { | 531 { |
| 525 // Array of array. | 532 // Array of array. |
| 526 CPDF_Array* vals[3]; | 533 CPDF_Array* vals[3]; |
| 527 std::unique_ptr<CPDF_Array> arr(new CPDF_Array); | 534 ScopedArray arr(new CPDF_Array); |
| 528 for (size_t i = 0; i < 3; ++i) { | 535 for (size_t i = 0; i < 3; ++i) { |
| 529 vals[i] = new CPDF_Array; | 536 vals[i] = new CPDF_Array; |
| 530 for (size_t j = 0; j < 3; ++j) { | 537 for (size_t j = 0; j < 3; ++j) { |
| 531 int value = j + 100; | 538 int value = j + 100; |
| 532 vals[i]->InsertAt(i, new CPDF_Number(value)); | 539 vals[i]->InsertAt(i, new CPDF_Number(value)); |
| 533 } | 540 } |
| 534 arr->InsertAt(i, vals[i]); | 541 arr->InsertAt(i, vals[i]); |
| 535 } | 542 } |
| 536 for (size_t i = 0; i < 3; ++i) { | 543 for (size_t i = 0; i < 3; ++i) { |
| 537 TestArrayAccessors(arr.get(), i, // Array and index. | 544 TestArrayAccessors(arr.get(), i, // Array and index. |
| 538 "", // String value. | 545 "", // String value. |
| 539 nullptr, // Const string value. | 546 nullptr, // Const string value. |
| 540 0, // Integer value. | 547 0, // Integer value. |
| 541 0, // Float value. | 548 0, // Float value. |
| 542 vals[i], // Array value. | 549 vals[i], // Array value. |
| 543 nullptr, // Dictionary value. | 550 nullptr, // Dictionary value. |
| 544 nullptr); // Stream value. | 551 nullptr); // Stream value. |
| 545 } | 552 } |
| 546 } | 553 } |
| 547 { | 554 { |
| 548 // Dictionary array. | 555 // Dictionary array. |
| 549 CPDF_Dictionary* vals[3]; | 556 CPDF_Dictionary* vals[3]; |
| 550 std::unique_ptr<CPDF_Array> arr(new CPDF_Array); | 557 ScopedArray arr(new CPDF_Array); |
| 551 for (size_t i = 0; i < 3; ++i) { | 558 for (size_t i = 0; i < 3; ++i) { |
| 552 vals[i] = new CPDF_Dictionary(); | 559 vals[i] = new CPDF_Dictionary(); |
| 553 for (size_t j = 0; j < 3; ++j) { | 560 for (size_t j = 0; j < 3; ++j) { |
| 554 std::string key("key"); | 561 std::string key("key"); |
| 555 char buf[33]; | 562 char buf[33]; |
| 556 key.append(FXSYS_itoa(j, buf, 10)); | 563 key.append(FXSYS_itoa(j, buf, 10)); |
| 557 int value = j + 200; | 564 int value = j + 200; |
| 558 vals[i]->SetFor(key.c_str(), new CPDF_Number(value)); | 565 vals[i]->SetFor(key.c_str(), new CPDF_Number(value)); |
| 559 } | 566 } |
| 560 arr->InsertAt(i, vals[i]); | 567 arr->InsertAt(i, vals[i]); |
| 561 } | 568 } |
| 562 for (size_t i = 0; i < 3; ++i) { | 569 for (size_t i = 0; i < 3; ++i) { |
| 563 TestArrayAccessors(arr.get(), i, // Array and index. | 570 TestArrayAccessors(arr.get(), i, // Array and index. |
| 564 "", // String value. | 571 "", // String value. |
| 565 nullptr, // Const string value. | 572 nullptr, // Const string value. |
| 566 0, // Integer value. | 573 0, // Integer value. |
| 567 0, // Float value. | 574 0, // Float value. |
| 568 nullptr, // Array value. | 575 nullptr, // Array value. |
| 569 vals[i], // Dictionary value. | 576 vals[i], // Dictionary value. |
| 570 nullptr); // Stream value. | 577 nullptr); // Stream value. |
| 571 } | 578 } |
| 572 } | 579 } |
| 573 { | 580 { |
| 574 // Stream array. | 581 // Stream array. |
| 575 CPDF_Dictionary* vals[3]; | 582 CPDF_Dictionary* vals[3]; |
| 576 CPDF_Stream* stream_vals[3]; | 583 CPDF_Stream* stream_vals[3]; |
| 577 std::unique_ptr<CPDF_Array> arr(new CPDF_Array); | 584 ScopedArray arr(new CPDF_Array); |
| 578 for (size_t i = 0; i < 3; ++i) { | 585 for (size_t i = 0; i < 3; ++i) { |
| 579 vals[i] = new CPDF_Dictionary(); | 586 vals[i] = new CPDF_Dictionary(); |
| 580 for (size_t j = 0; j < 3; ++j) { | 587 for (size_t j = 0; j < 3; ++j) { |
| 581 std::string key("key"); | 588 std::string key("key"); |
| 582 char buf[33]; | 589 char buf[33]; |
| 583 key.append(FXSYS_itoa(j, buf, 10)); | 590 key.append(FXSYS_itoa(j, buf, 10)); |
| 584 int value = j + 200; | 591 int value = j + 200; |
| 585 vals[i]->SetFor(key.c_str(), new CPDF_Number(value)); | 592 vals[i]->SetFor(key.c_str(), new CPDF_Number(value)); |
| 586 } | 593 } |
| 587 uint8_t content[] = "content: this is a stream"; | 594 uint8_t content[] = "content: this is a stream"; |
| 588 size_t data_size = FX_ArraySize(content); | 595 size_t data_size = FX_ArraySize(content); |
| 589 uint8_t* data = reinterpret_cast<uint8_t*>(malloc(data_size)); | 596 uint8_t* data = reinterpret_cast<uint8_t*>(malloc(data_size)); |
| 590 memcpy(data, content, data_size); | 597 memcpy(data, content, data_size); |
| 591 stream_vals[i] = new CPDF_Stream(data, data_size, vals[i]); | 598 stream_vals[i] = new CPDF_Stream(data, data_size, vals[i]); |
| 592 arr->InsertAt(i, stream_vals[i]); | 599 arr->InsertAt(i, stream_vals[i]); |
| 593 } | 600 } |
| 594 for (size_t i = 0; i < 3; ++i) { | 601 for (size_t i = 0; i < 3; ++i) { |
| 595 TestArrayAccessors(arr.get(), i, // Array and index. | 602 TestArrayAccessors(arr.get(), i, // Array and index. |
| 596 "", // String value. | 603 "", // String value. |
| 597 nullptr, // Const string value. | 604 nullptr, // Const string value. |
| 598 0, // Integer value. | 605 0, // Integer value. |
| 599 0, // Float value. | 606 0, // Float value. |
| 600 nullptr, // Array value. | 607 nullptr, // Array value. |
| 601 vals[i], // Dictionary value. | 608 vals[i], // Dictionary value. |
| 602 stream_vals[i]); // Stream value. | 609 stream_vals[i]); // Stream value. |
| 603 } | 610 } |
| 604 } | 611 } |
| 605 { | 612 { |
| 606 // Mixed array. | 613 // Mixed array. |
| 607 std::unique_ptr<CPDF_Array> arr(new CPDF_Array); | 614 ScopedArray arr(new CPDF_Array); |
| 608 // Array arr will take ownership of all the objects inserted. | 615 // Array arr will take ownership of all the objects inserted. |
| 609 arr->InsertAt(0, new CPDF_Boolean(true)); | 616 arr->InsertAt(0, new CPDF_Boolean(true)); |
| 610 arr->InsertAt(1, new CPDF_Boolean(false)); | 617 arr->InsertAt(1, new CPDF_Boolean(false)); |
| 611 arr->InsertAt(2, new CPDF_Number(0)); | 618 arr->InsertAt(2, new CPDF_Number(0)); |
| 612 arr->InsertAt(3, new CPDF_Number(-1234)); | 619 arr->InsertAt(3, new CPDF_Number(-1234)); |
| 613 arr->InsertAt(4, new CPDF_Number(2345.0f)); | 620 arr->InsertAt(4, new CPDF_Number(2345.0f)); |
| 614 arr->InsertAt(5, new CPDF_Number(0.05f)); | 621 arr->InsertAt(5, new CPDF_Number(0.05f)); |
| 615 arr->InsertAt(6, new CPDF_String("", false)); | 622 arr->InsertAt(6, new CPDF_String("", false)); |
| 616 arr->InsertAt(7, new CPDF_String("It is a test!", false)); | 623 arr->InsertAt(7, new CPDF_String("It is a test!", false)); |
| 617 arr->InsertAt(8, new CPDF_Name("NAME")); | 624 arr->InsertAt(8, new CPDF_Name("NAME")); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 662 else | 669 else |
| 663 EXPECT_EQ(nullptr, arr->GetDictAt(i)); | 670 EXPECT_EQ(nullptr, arr->GetDictAt(i)); |
| 664 } | 671 } |
| 665 } | 672 } |
| 666 } | 673 } |
| 667 } | 674 } |
| 668 | 675 |
| 669 TEST(PDFArrayTest, AddNumber) { | 676 TEST(PDFArrayTest, AddNumber) { |
| 670 float vals[] = {1.0f, -1.0f, 0, 0.456734f, | 677 float vals[] = {1.0f, -1.0f, 0, 0.456734f, |
| 671 12345.54321f, 0.5f, 1000, 0.000045f}; | 678 12345.54321f, 0.5f, 1000, 0.000045f}; |
| 672 std::unique_ptr<CPDF_Array> arr(new CPDF_Array); | 679 ScopedArray arr(new CPDF_Array); |
| 673 for (size_t i = 0; i < FX_ArraySize(vals); ++i) | 680 for (size_t i = 0; i < FX_ArraySize(vals); ++i) |
| 674 arr->AddNumber(vals[i]); | 681 arr->AddNumber(vals[i]); |
| 675 for (size_t i = 0; i < FX_ArraySize(vals); ++i) { | 682 for (size_t i = 0; i < FX_ArraySize(vals); ++i) { |
| 676 EXPECT_EQ(CPDF_Object::NUMBER, arr->GetObjectAt(i)->GetType()); | 683 EXPECT_EQ(CPDF_Object::NUMBER, arr->GetObjectAt(i)->GetType()); |
| 677 EXPECT_EQ(vals[i], arr->GetObjectAt(i)->GetNumber()); | 684 EXPECT_EQ(vals[i], arr->GetObjectAt(i)->GetNumber()); |
| 678 } | 685 } |
| 679 } | 686 } |
| 680 | 687 |
| 681 TEST(PDFArrayTest, AddInteger) { | 688 TEST(PDFArrayTest, AddInteger) { |
| 682 int vals[] = {0, 1, 934435456, 876, 10000, -1, -24354656, -100}; | 689 int vals[] = {0, 1, 934435456, 876, 10000, -1, -24354656, -100}; |
| 683 std::unique_ptr<CPDF_Array> arr(new CPDF_Array); | 690 ScopedArray arr(new CPDF_Array); |
| 684 for (size_t i = 0; i < FX_ArraySize(vals); ++i) | 691 for (size_t i = 0; i < FX_ArraySize(vals); ++i) |
| 685 arr->AddInteger(vals[i]); | 692 arr->AddInteger(vals[i]); |
| 686 for (size_t i = 0; i < FX_ArraySize(vals); ++i) { | 693 for (size_t i = 0; i < FX_ArraySize(vals); ++i) { |
| 687 EXPECT_EQ(CPDF_Object::NUMBER, arr->GetObjectAt(i)->GetType()); | 694 EXPECT_EQ(CPDF_Object::NUMBER, arr->GetObjectAt(i)->GetType()); |
| 688 EXPECT_EQ(vals[i], arr->GetObjectAt(i)->GetNumber()); | 695 EXPECT_EQ(vals[i], arr->GetObjectAt(i)->GetNumber()); |
| 689 } | 696 } |
| 690 } | 697 } |
| 691 | 698 |
| 692 TEST(PDFArrayTest, AddStringAndName) { | 699 TEST(PDFArrayTest, AddStringAndName) { |
| 693 const char* vals[] = {"", "a", "ehjhRIOYTTFdfcdnv", "122323", | 700 const char* vals[] = {"", "a", "ehjhRIOYTTFdfcdnv", "122323", |
| 694 "$#%^&**", " ", "This is a test.\r\n"}; | 701 "$#%^&**", " ", "This is a test.\r\n"}; |
| 695 std::unique_ptr<CPDF_Array> string_array(new CPDF_Array); | 702 ScopedArray string_array(new CPDF_Array); |
| 696 std::unique_ptr<CPDF_Array> name_array(new CPDF_Array); | 703 ScopedArray name_array(new CPDF_Array); |
| 697 for (size_t i = 0; i < FX_ArraySize(vals); ++i) { | 704 for (size_t i = 0; i < FX_ArraySize(vals); ++i) { |
| 698 string_array->AddString(vals[i]); | 705 string_array->AddString(vals[i]); |
| 699 name_array->AddName(vals[i]); | 706 name_array->AddName(vals[i]); |
| 700 } | 707 } |
| 701 for (size_t i = 0; i < FX_ArraySize(vals); ++i) { | 708 for (size_t i = 0; i < FX_ArraySize(vals); ++i) { |
| 702 EXPECT_EQ(CPDF_Object::STRING, string_array->GetObjectAt(i)->GetType()); | 709 EXPECT_EQ(CPDF_Object::STRING, string_array->GetObjectAt(i)->GetType()); |
| 703 EXPECT_STREQ(vals[i], string_array->GetObjectAt(i)->GetString().c_str()); | 710 EXPECT_STREQ(vals[i], string_array->GetObjectAt(i)->GetString().c_str()); |
| 704 EXPECT_EQ(CPDF_Object::NAME, name_array->GetObjectAt(i)->GetType()); | 711 EXPECT_EQ(CPDF_Object::NAME, name_array->GetObjectAt(i)->GetType()); |
| 705 EXPECT_STREQ(vals[i], name_array->GetObjectAt(i)->GetString().c_str()); | 712 EXPECT_STREQ(vals[i], name_array->GetObjectAt(i)->GetString().c_str()); |
| 706 } | 713 } |
| 707 } | 714 } |
| 708 | 715 |
| 709 TEST(PDFArrayTest, AddReferenceAndGetObjectAt) { | 716 TEST(PDFArrayTest, AddReferenceAndGetObjectAt) { |
| 710 std::unique_ptr<CPDF_IndirectObjectHolder> holder( | 717 std::unique_ptr<CPDF_IndirectObjectHolder> holder( |
| 711 new CPDF_IndirectObjectHolder()); | 718 new CPDF_IndirectObjectHolder()); |
| 712 CPDF_Boolean* boolean_obj = new CPDF_Boolean(true); | 719 CPDF_Boolean* boolean_obj = new CPDF_Boolean(true); |
| 713 CPDF_Number* int_obj = new CPDF_Number(-1234); | 720 CPDF_Number* int_obj = new CPDF_Number(-1234); |
| 714 CPDF_Number* float_obj = new CPDF_Number(2345.089f); | 721 CPDF_Number* float_obj = new CPDF_Number(2345.089f); |
| 715 CPDF_String* str_obj = new CPDF_String("Adsfdsf 343434 %&&*\n", false); | 722 CPDF_String* str_obj = new CPDF_String("Adsfdsf 343434 %&&*\n", false); |
| 716 CPDF_Name* name_obj = new CPDF_Name("Title:"); | 723 CPDF_Name* name_obj = new CPDF_Name("Title:"); |
| 717 CPDF_Null* null_obj = new CPDF_Null(); | 724 CPDF_Null* null_obj = new CPDF_Null(); |
| 718 CPDF_Object* indirect_objs[] = {boolean_obj, int_obj, float_obj, | 725 CPDF_Object* indirect_objs[] = {boolean_obj, int_obj, float_obj, |
| 719 str_obj, name_obj, null_obj}; | 726 str_obj, name_obj, null_obj}; |
| 720 unsigned int obj_nums[] = {2, 4, 7, 2345, 799887, 1}; | 727 unsigned int obj_nums[] = {2, 4, 7, 2345, 799887, 1}; |
| 721 std::unique_ptr<CPDF_Array> arr(new CPDF_Array); | 728 ScopedArray arr(new CPDF_Array); |
| 722 std::unique_ptr<CPDF_Array> arr1(new CPDF_Array); | 729 ScopedArray arr1(new CPDF_Array); |
| 723 // Create two arrays of references by different AddReference() APIs. | 730 // Create two arrays of references by different AddReference() APIs. |
| 724 for (size_t i = 0; i < FX_ArraySize(indirect_objs); ++i) { | 731 for (size_t i = 0; i < FX_ArraySize(indirect_objs); ++i) { |
| 725 // All the indirect objects inserted will be owned by holder. | 732 // All the indirect objects inserted will be owned by holder. |
| 726 holder->ReplaceIndirectObjectIfHigherGeneration(obj_nums[i], | 733 holder->ReplaceIndirectObjectIfHigherGeneration(obj_nums[i], |
| 727 indirect_objs[i]); | 734 indirect_objs[i]); |
| 728 arr->AddReference(holder.get(), obj_nums[i]); | 735 arr->AddReference(holder.get(), obj_nums[i]); |
| 729 arr1->AddReference(holder.get(), indirect_objs[i]->GetObjNum()); | 736 arr1->AddReference(holder.get(), indirect_objs[i]->GetObjNum()); |
| 730 } | 737 } |
| 731 // Check indirect objects. | 738 // Check indirect objects. |
| 732 for (size_t i = 0; i < FX_ArraySize(obj_nums); ++i) | 739 for (size_t i = 0; i < FX_ArraySize(obj_nums); ++i) |
| 733 EXPECT_EQ(indirect_objs[i], holder->GetOrParseIndirectObject(obj_nums[i])); | 740 EXPECT_EQ(indirect_objs[i], holder->GetOrParseIndirectObject(obj_nums[i])); |
| 734 // Check arrays. | 741 // Check arrays. |
| 735 EXPECT_EQ(arr->GetCount(), arr1->GetCount()); | 742 EXPECT_EQ(arr->GetCount(), arr1->GetCount()); |
| 736 for (size_t i = 0; i < arr->GetCount(); ++i) { | 743 for (size_t i = 0; i < arr->GetCount(); ++i) { |
| 737 EXPECT_EQ(CPDF_Object::REFERENCE, arr->GetObjectAt(i)->GetType()); | 744 EXPECT_EQ(CPDF_Object::REFERENCE, arr->GetObjectAt(i)->GetType()); |
| 738 EXPECT_EQ(indirect_objs[i], arr->GetObjectAt(i)->GetDirect()); | 745 EXPECT_EQ(indirect_objs[i], arr->GetObjectAt(i)->GetDirect()); |
| 739 EXPECT_EQ(indirect_objs[i], arr->GetDirectObjectAt(i)); | 746 EXPECT_EQ(indirect_objs[i], arr->GetDirectObjectAt(i)); |
| 740 EXPECT_EQ(CPDF_Object::REFERENCE, arr1->GetObjectAt(i)->GetType()); | 747 EXPECT_EQ(CPDF_Object::REFERENCE, arr1->GetObjectAt(i)->GetType()); |
| 741 EXPECT_EQ(indirect_objs[i], arr1->GetObjectAt(i)->GetDirect()); | 748 EXPECT_EQ(indirect_objs[i], arr1->GetObjectAt(i)->GetDirect()); |
| 742 EXPECT_EQ(indirect_objs[i], arr1->GetDirectObjectAt(i)); | 749 EXPECT_EQ(indirect_objs[i], arr1->GetDirectObjectAt(i)); |
| 743 } | 750 } |
| 744 } | 751 } |
| 745 | 752 |
| 746 TEST(PDFArrayTest, CloneDirectObject) { | 753 TEST(PDFArrayTest, CloneDirectObject) { |
| 747 CPDF_IndirectObjectHolder objects_holder; | 754 CPDF_IndirectObjectHolder objects_holder; |
| 748 std::unique_ptr<CPDF_Array> array(new CPDF_Array); | 755 ScopedArray array(new CPDF_Array); |
| 749 array->AddReference(&objects_holder, 1234); | 756 array->AddReference(&objects_holder, 1234); |
| 750 ASSERT_EQ(1U, array->GetCount()); | 757 ASSERT_EQ(1U, array->GetCount()); |
| 751 CPDF_Object* obj = array->GetObjectAt(0); | 758 CPDF_Object* obj = array->GetObjectAt(0); |
| 752 ASSERT_TRUE(obj); | 759 ASSERT_TRUE(obj); |
| 753 EXPECT_TRUE(obj->IsReference()); | 760 EXPECT_TRUE(obj->IsReference()); |
| 754 | 761 |
| 755 CPDF_Object* cloned_array_object = array->CloneDirectObject(); | 762 CPDF_Object* cloned_array_object = array->CloneDirectObject(); |
| 756 ASSERT_TRUE(cloned_array_object); | 763 ASSERT_TRUE(cloned_array_object); |
| 757 ASSERT_TRUE(cloned_array_object->IsArray()); | 764 ASSERT_TRUE(cloned_array_object->IsArray()); |
| 758 | 765 |
| 759 std::unique_ptr<CPDF_Array> cloned_array(cloned_array_object->AsArray()); | 766 ScopedArray cloned_array(cloned_array_object->AsArray()); |
| 760 ASSERT_EQ(1U, cloned_array->GetCount()); | 767 ASSERT_EQ(1U, cloned_array->GetCount()); |
| 761 CPDF_Object* cloned_obj = cloned_array->GetObjectAt(0); | 768 CPDF_Object* cloned_obj = cloned_array->GetObjectAt(0); |
| 762 EXPECT_FALSE(cloned_obj); | 769 EXPECT_FALSE(cloned_obj); |
| 763 } | 770 } |
| 764 | 771 |
| 765 TEST(PDFArrayTest, ConvertIndirect) { | 772 TEST(PDFArrayTest, ConvertIndirect) { |
| 766 CPDF_IndirectObjectHolder objects_holder; | 773 CPDF_IndirectObjectHolder objects_holder; |
| 767 std::unique_ptr<CPDF_Array> array(new CPDF_Array); | 774 ScopedArray array(new CPDF_Array); |
| 768 CPDF_Object* pObj = new CPDF_Number(42); | 775 CPDF_Object* pObj = new CPDF_Number(42); |
| 769 array->Add(pObj); | 776 array->Add(pObj); |
| 770 array->ConvertToIndirectObjectAt(0, &objects_holder); | 777 array->ConvertToIndirectObjectAt(0, &objects_holder); |
| 771 CPDF_Object* pRef = array->GetObjectAt(0); | 778 CPDF_Object* pRef = array->GetObjectAt(0); |
| 772 CPDF_Object* pNum = array->GetDirectObjectAt(0); | 779 CPDF_Object* pNum = array->GetDirectObjectAt(0); |
| 773 EXPECT_TRUE(pRef->IsReference()); | 780 EXPECT_TRUE(pRef->IsReference()); |
| 774 EXPECT_TRUE(pNum->IsNumber()); | 781 EXPECT_TRUE(pNum->IsNumber()); |
| 775 EXPECT_NE(pObj, pRef); | 782 EXPECT_NE(pObj, pRef); |
| 776 EXPECT_EQ(pObj, pNum); | 783 EXPECT_EQ(pObj, pNum); |
| 777 EXPECT_EQ(42, array->GetIntegerAt(0)); | 784 EXPECT_EQ(42, array->GetIntegerAt(0)); |
| 778 } | 785 } |
| 779 | 786 |
| 780 TEST(PDFDictionaryTest, CloneDirectObject) { | 787 TEST(PDFDictionaryTest, CloneDirectObject) { |
| 781 CPDF_IndirectObjectHolder objects_holder; | 788 CPDF_IndirectObjectHolder objects_holder; |
| 782 std::unique_ptr<CPDF_Dictionary> dict(new CPDF_Dictionary()); | 789 ScopedDict dict(new CPDF_Dictionary()); |
| 783 dict->SetReferenceFor("foo", &objects_holder, 1234); | 790 dict->SetReferenceFor("foo", &objects_holder, 1234); |
| 784 ASSERT_EQ(1U, dict->GetCount()); | 791 ASSERT_EQ(1U, dict->GetCount()); |
| 785 CPDF_Object* obj = dict->GetObjectFor("foo"); | 792 CPDF_Object* obj = dict->GetObjectFor("foo"); |
| 786 ASSERT_TRUE(obj); | 793 ASSERT_TRUE(obj); |
| 787 EXPECT_TRUE(obj->IsReference()); | 794 EXPECT_TRUE(obj->IsReference()); |
| 788 | 795 |
| 789 CPDF_Object* cloned_dict_object = dict->CloneDirectObject(); | 796 CPDF_Object* cloned_dict_object = dict->CloneDirectObject(); |
| 790 ASSERT_TRUE(cloned_dict_object); | 797 ASSERT_TRUE(cloned_dict_object); |
| 791 ASSERT_TRUE(cloned_dict_object->IsDictionary()); | 798 ASSERT_TRUE(cloned_dict_object->IsDictionary()); |
| 792 | 799 |
| 793 std::unique_ptr<CPDF_Dictionary> cloned_dict( | 800 ScopedDict cloned_dict(cloned_dict_object->AsDictionary()); |
| 794 cloned_dict_object->AsDictionary()); | |
| 795 ASSERT_EQ(1U, cloned_dict->GetCount()); | 801 ASSERT_EQ(1U, cloned_dict->GetCount()); |
| 796 CPDF_Object* cloned_obj = cloned_dict->GetObjectFor("foo"); | 802 CPDF_Object* cloned_obj = cloned_dict->GetObjectFor("foo"); |
| 797 EXPECT_FALSE(cloned_obj); | 803 EXPECT_FALSE(cloned_obj); |
| 798 } | 804 } |
| 799 | 805 |
| 800 TEST(PDFObjectTest, CloneCheckLoop) { | 806 TEST(PDFObjectTest, CloneCheckLoop) { |
| 801 { | 807 { |
| 802 // Create a dictionary/array pair with a reference loop. | 808 // Create a dictionary/array pair with a reference loop. |
| 803 CPDF_Dictionary* dict_obj = new CPDF_Dictionary(); | 809 CPDF_Dictionary* dict_obj = new CPDF_Dictionary(); |
| 804 std::unique_ptr<CPDF_Array> arr_obj(new CPDF_Array); | 810 ScopedArray arr_obj(new CPDF_Array); |
| 805 dict_obj->SetFor("arr", arr_obj.get()); | 811 dict_obj->SetFor("arr", arr_obj.get()); |
| 806 arr_obj->InsertAt(0, dict_obj); | 812 arr_obj->InsertAt(0, dict_obj); |
| 807 | 813 |
| 808 // Clone this object to see whether stack overflow will be triggered. | 814 // Clone this object to see whether stack overflow will be triggered. |
| 809 std::unique_ptr<CPDF_Array> cloned_array(arr_obj->Clone()->AsArray()); | 815 ScopedArray cloned_array(arr_obj->Clone()->AsArray()); |
| 810 // Cloned object should be the same as the original. | 816 // Cloned object should be the same as the original. |
| 811 ASSERT_TRUE(cloned_array); | 817 ASSERT_TRUE(cloned_array); |
| 812 EXPECT_EQ(1u, cloned_array->GetCount()); | 818 EXPECT_EQ(1u, cloned_array->GetCount()); |
| 813 CPDF_Object* cloned_dict = cloned_array->GetObjectAt(0); | 819 CPDF_Object* cloned_dict = cloned_array->GetObjectAt(0); |
| 814 ASSERT_TRUE(cloned_dict); | 820 ASSERT_TRUE(cloned_dict); |
| 815 ASSERT_TRUE(cloned_dict->IsDictionary()); | 821 ASSERT_TRUE(cloned_dict->IsDictionary()); |
| 816 // Recursively referenced object is not cloned. | 822 // Recursively referenced object is not cloned. |
| 817 EXPECT_EQ(nullptr, cloned_dict->AsDictionary()->GetObjectFor("arr")); | 823 EXPECT_EQ(nullptr, cloned_dict->AsDictionary()->GetObjectFor("arr")); |
| 818 } | 824 } |
| 819 { | 825 { |
| 820 // Create a dictionary/stream pair with a reference loop. | 826 // Create a dictionary/stream pair with a reference loop. |
| 821 CPDF_Dictionary* dict_obj = new CPDF_Dictionary(); | 827 CPDF_Dictionary* dict_obj = new CPDF_Dictionary(); |
| 822 std::unique_ptr<CPDF_Stream> stream_obj( | 828 ScopedStream stream_obj(new CPDF_Stream(nullptr, 0, dict_obj)); |
| 823 new CPDF_Stream(nullptr, 0, dict_obj)); | |
| 824 dict_obj->SetFor("stream", stream_obj.get()); | 829 dict_obj->SetFor("stream", stream_obj.get()); |
| 825 | 830 |
| 826 // Clone this object to see whether stack overflow will be triggered. | 831 // Clone this object to see whether stack overflow will be triggered. |
| 827 std::unique_ptr<CPDF_Stream> cloned_stream(stream_obj->Clone()->AsStream()); | 832 ScopedStream cloned_stream(stream_obj->Clone()->AsStream()); |
| 828 // Cloned object should be the same as the original. | 833 // Cloned object should be the same as the original. |
| 829 ASSERT_TRUE(cloned_stream); | 834 ASSERT_TRUE(cloned_stream); |
| 830 CPDF_Object* cloned_dict = cloned_stream->GetDict(); | 835 CPDF_Object* cloned_dict = cloned_stream->GetDict(); |
| 831 ASSERT_TRUE(cloned_dict); | 836 ASSERT_TRUE(cloned_dict); |
| 832 ASSERT_TRUE(cloned_dict->IsDictionary()); | 837 ASSERT_TRUE(cloned_dict->IsDictionary()); |
| 833 // Recursively referenced object is not cloned. | 838 // Recursively referenced object is not cloned. |
| 834 EXPECT_EQ(nullptr, cloned_dict->AsDictionary()->GetObjectFor("stream")); | 839 EXPECT_EQ(nullptr, cloned_dict->AsDictionary()->GetObjectFor("stream")); |
| 835 } | 840 } |
| 836 { | 841 { |
| 837 CPDF_IndirectObjectHolder objects_holder; | 842 CPDF_IndirectObjectHolder objects_holder; |
| 838 // Create an object with a reference loop. | 843 // Create an object with a reference loop. |
| 839 CPDF_Dictionary* dict_obj = new CPDF_Dictionary(); | 844 CPDF_Dictionary* dict_obj = new CPDF_Dictionary(); |
| 840 CPDF_Array* arr_obj = new CPDF_Array; | 845 CPDF_Array* arr_obj = new CPDF_Array; |
| 841 objects_holder.AddIndirectObject(dict_obj); | 846 objects_holder.AddIndirectObject(dict_obj); |
| 842 EXPECT_EQ(1u, dict_obj->GetObjNum()); | 847 EXPECT_EQ(1u, dict_obj->GetObjNum()); |
| 843 dict_obj->SetFor("arr", arr_obj); | 848 dict_obj->SetFor("arr", arr_obj); |
| 844 arr_obj->InsertAt( | 849 arr_obj->InsertAt( |
| 845 0, new CPDF_Reference(&objects_holder, dict_obj->GetObjNum())); | 850 0, new CPDF_Reference(&objects_holder, dict_obj->GetObjNum())); |
| 846 CPDF_Object* elem0 = arr_obj->GetObjectAt(0); | 851 CPDF_Object* elem0 = arr_obj->GetObjectAt(0); |
| 847 ASSERT_TRUE(elem0); | 852 ASSERT_TRUE(elem0); |
| 848 ASSERT_TRUE(elem0->IsReference()); | 853 ASSERT_TRUE(elem0->IsReference()); |
| 849 EXPECT_EQ(1u, elem0->AsReference()->GetRefObjNum()); | 854 EXPECT_EQ(1u, elem0->AsReference()->GetRefObjNum()); |
| 850 EXPECT_EQ(dict_obj, elem0->AsReference()->GetDirect()); | 855 EXPECT_EQ(dict_obj, elem0->AsReference()->GetDirect()); |
| 851 | 856 |
| 852 // Clone this object to see whether stack overflow will be triggered. | 857 // Clone this object to see whether stack overflow will be triggered. |
| 853 std::unique_ptr<CPDF_Dictionary> cloned_dict( | 858 ScopedDict cloned_dict(ToDictionary(dict_obj->CloneDirectObject())); |
| 854 ToDictionary(dict_obj->CloneDirectObject())); | |
| 855 // Cloned object should be the same as the original. | 859 // Cloned object should be the same as the original. |
| 856 ASSERT_TRUE(cloned_dict); | 860 ASSERT_TRUE(cloned_dict); |
| 857 CPDF_Object* cloned_arr = cloned_dict->GetObjectFor("arr"); | 861 CPDF_Object* cloned_arr = cloned_dict->GetObjectFor("arr"); |
| 858 ASSERT_TRUE(cloned_arr); | 862 ASSERT_TRUE(cloned_arr); |
| 859 ASSERT_TRUE(cloned_arr->IsArray()); | 863 ASSERT_TRUE(cloned_arr->IsArray()); |
| 860 EXPECT_EQ(1u, cloned_arr->AsArray()->GetCount()); | 864 EXPECT_EQ(1u, cloned_arr->AsArray()->GetCount()); |
| 861 // Recursively referenced object is not cloned. | 865 // Recursively referenced object is not cloned. |
| 862 EXPECT_EQ(nullptr, cloned_arr->AsArray()->GetObjectAt(0)); | 866 EXPECT_EQ(nullptr, cloned_arr->AsArray()->GetObjectAt(0)); |
| 863 } | 867 } |
| 864 } | 868 } |
| 865 | 869 |
| 866 TEST(PDFDictionaryTest, ConvertIndirect) { | 870 TEST(PDFDictionaryTest, ConvertIndirect) { |
| 867 CPDF_IndirectObjectHolder objects_holder; | 871 CPDF_IndirectObjectHolder objects_holder; |
| 868 std::unique_ptr<CPDF_Dictionary> dict(new CPDF_Dictionary); | 872 ScopedDict dict(new CPDF_Dictionary); |
| 869 CPDF_Object* pObj = new CPDF_Number(42); | 873 CPDF_Object* pObj = new CPDF_Number(42); |
| 870 dict->SetFor("clams", pObj); | 874 dict->SetFor("clams", pObj); |
| 871 dict->ConvertToIndirectObjectFor("clams", &objects_holder); | 875 dict->ConvertToIndirectObjectFor("clams", &objects_holder); |
| 872 CPDF_Object* pRef = dict->GetObjectFor("clams"); | 876 CPDF_Object* pRef = dict->GetObjectFor("clams"); |
| 873 CPDF_Object* pNum = dict->GetDirectObjectFor("clams"); | 877 CPDF_Object* pNum = dict->GetDirectObjectFor("clams"); |
| 874 EXPECT_TRUE(pRef->IsReference()); | 878 EXPECT_TRUE(pRef->IsReference()); |
| 875 EXPECT_TRUE(pNum->IsNumber()); | 879 EXPECT_TRUE(pNum->IsNumber()); |
| 876 EXPECT_NE(pObj, pRef); | 880 EXPECT_NE(pObj, pRef); |
| 877 EXPECT_EQ(pObj, pNum); | 881 EXPECT_EQ(pObj, pNum); |
| 878 EXPECT_EQ(42, dict->GetIntegerFor("clams")); | 882 EXPECT_EQ(42, dict->GetIntegerFor("clams")); |
| 879 } | 883 } |
| OLD | NEW |