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