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