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 |