| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium 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 "content/browser/download/base_file.h" | 5 #include "content/browser/download/base_file.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 528 | 528 |
| 529 base_file_->Finish(); | 529 base_file_->Finish(); |
| 530 base_file_->Detach(); | 530 base_file_->Detach(); |
| 531 expect_file_survives_ = true; | 531 expect_file_survives_ = true; |
| 532 } | 532 } |
| 533 | 533 |
| 534 // Open an existing file and continue writing to it. The hash of the partial | 534 // Open an existing file and continue writing to it. The hash of the partial |
| 535 // file is known and matches the existing contents. | 535 // file is known and matches the existing contents. |
| 536 TEST_F(BaseFileTest, ExistingBaseFileKnownHash) { | 536 TEST_F(BaseFileTest, ExistingBaseFileKnownHash) { |
| 537 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); | 537 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); |
| 538 ASSERT_TRUE(base::WriteFile(file_path, kTestData1, kTestDataLength1)); | 538 ASSERT_EQ(kTestDataLength1, |
| 539 base::WriteFile(file_path, kTestData1, kTestDataLength1)); |
| 539 | 540 |
| 540 std::string hash_so_far(std::begin(kHashOfTestData1), | 541 std::string hash_so_far(std::begin(kHashOfTestData1), |
| 541 std::end(kHashOfTestData1)); | 542 std::end(kHashOfTestData1)); |
| 542 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, | 543 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 543 base_file_->Initialize(file_path, | 544 base_file_->Initialize(file_path, |
| 544 base::FilePath(), | 545 base::FilePath(), |
| 545 base::File(), | 546 base::File(), |
| 546 kTestDataLength1, | 547 kTestDataLength1, |
| 547 hash_so_far, | 548 hash_so_far, |
| 548 scoped_ptr<crypto::SecureHash>())); | 549 scoped_ptr<crypto::SecureHash>())); |
| 549 set_expected_data(kTestData1); | 550 set_expected_data(kTestData1); |
| 550 ASSERT_TRUE(AppendDataToFile(kTestData2)); | 551 ASSERT_TRUE(AppendDataToFile(kTestData2)); |
| 551 ASSERT_TRUE(AppendDataToFile(kTestData3)); | 552 ASSERT_TRUE(AppendDataToFile(kTestData3)); |
| 552 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish()); | 553 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish()); |
| 553 } | 554 } |
| 554 | 555 |
| 555 // Open an existing file and continue writing to it. The hash of the partial | 556 // Open an existing file and continue writing to it. The hash of the partial |
| 556 // file is unknown. | 557 // file is unknown. |
| 557 TEST_F(BaseFileTest, ExistingBaseFileUnknownHash) { | 558 TEST_F(BaseFileTest, ExistingBaseFileUnknownHash) { |
| 558 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); | 559 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); |
| 559 ASSERT_TRUE(base::WriteFile(file_path, kTestData1, kTestDataLength1)); | 560 ASSERT_EQ(kTestDataLength1, |
| 561 base::WriteFile(file_path, kTestData1, kTestDataLength1)); |
| 560 | 562 |
| 561 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, | 563 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 562 base_file_->Initialize(file_path, | 564 base_file_->Initialize(file_path, |
| 563 base::FilePath(), | 565 base::FilePath(), |
| 564 base::File(), | 566 base::File(), |
| 565 kTestDataLength1, | 567 kTestDataLength1, |
| 566 std::string(), | 568 std::string(), |
| 567 scoped_ptr<crypto::SecureHash>())); | 569 scoped_ptr<crypto::SecureHash>())); |
| 568 set_expected_data(kTestData1); | 570 set_expected_data(kTestData1); |
| 569 ASSERT_TRUE(AppendDataToFile(kTestData2)); | 571 ASSERT_TRUE(AppendDataToFile(kTestData2)); |
| 570 ASSERT_TRUE(AppendDataToFile(kTestData3)); | 572 ASSERT_TRUE(AppendDataToFile(kTestData3)); |
| 571 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish()); | 573 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish()); |
| 572 } | 574 } |
| 573 | 575 |
| 574 // Open an existing file. The contentsof the file doesn't match the known hash. | 576 // Open an existing file. The contentsof the file doesn't match the known hash. |
| 575 TEST_F(BaseFileTest, ExistingBaseFileIncorrectHash) { | 577 TEST_F(BaseFileTest, ExistingBaseFileIncorrectHash) { |
| 576 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); | 578 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); |
| 577 ASSERT_TRUE(base::WriteFile(file_path, kTestData2, kTestDataLength2)); | 579 ASSERT_EQ(kTestDataLength2, |
| 580 base::WriteFile(file_path, kTestData2, kTestDataLength2)); |
| 578 | 581 |
| 579 std::string hash_so_far(std::begin(kHashOfTestData1), | 582 std::string hash_so_far(std::begin(kHashOfTestData1), |
| 580 std::end(kHashOfTestData1)); | 583 std::end(kHashOfTestData1)); |
| 581 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH, | 584 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH, |
| 582 base_file_->Initialize(file_path, | 585 base_file_->Initialize(file_path, |
| 583 base::FilePath(), | 586 base::FilePath(), |
| 584 base::File(), | 587 base::File(), |
| 585 kTestDataLength2, | 588 kTestDataLength2, |
| 586 hash_so_far, | 589 hash_so_far, |
| 587 scoped_ptr<crypto::SecureHash>())); | 590 scoped_ptr<crypto::SecureHash>())); |
| 588 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH); | 591 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH); |
| 589 } | 592 } |
| 590 | 593 |
| 591 // Open a large existing file with a known hash and continue writing to it. | 594 // Open a large existing file with a known hash and continue writing to it. |
| 592 TEST_F(BaseFileTest, ExistingBaseFileLargeSizeKnownHash) { | 595 TEST_F(BaseFileTest, ExistingBaseFileLargeSizeKnownHash) { |
| 593 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); | 596 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); |
| 594 std::string big_buffer(1024 * 200, 'a'); | 597 std::string big_buffer(1024 * 200, 'a'); |
| 595 ASSERT_TRUE(base::WriteFile(file_path, big_buffer.data(), big_buffer.size())); | 598 ASSERT_EQ(static_cast<int>(big_buffer.size()), |
| 599 base::WriteFile(file_path, big_buffer.data(), big_buffer.size())); |
| 596 | 600 |
| 597 // Hash of partial file (1024*200 * 'a') | 601 // Hash of partial file (1024*200 * 'a') |
| 598 const uint8_t kExpectedPartialHash[] = { | 602 const uint8_t kExpectedPartialHash[] = { |
| 599 0x4b, 0x4f, 0x0f, 0x46, 0xac, 0x02, 0xd1, 0x77, 0xde, 0xa0, 0xab, | 603 0x4b, 0x4f, 0x0f, 0x46, 0xac, 0x02, 0xd1, 0x77, 0xde, 0xa0, 0xab, |
| 600 0x36, 0xa6, 0x6a, 0x65, 0x78, 0x40, 0xe2, 0xfb, 0x98, 0xb2, 0x0b, | 604 0x36, 0xa6, 0x6a, 0x65, 0x78, 0x40, 0xe2, 0xfb, 0x98, 0xb2, 0x0b, |
| 601 0xb2, 0x7a, 0x68, 0x8d, 0xb4, 0xd8, 0xea, 0x9c, 0xd2, 0x2c}; | 605 0xb2, 0x7a, 0x68, 0x8d, 0xb4, 0xd8, 0xea, 0x9c, 0xd2, 0x2c}; |
| 602 | 606 |
| 603 // Hash of entire file (1024*400 * 'a') | 607 // Hash of entire file (1024*400 * 'a') |
| 604 const uint8_t kExpectedFullHash[] = { | 608 const uint8_t kExpectedFullHash[] = { |
| 605 0x0c, 0xe9, 0xf6, 0x78, 0x6b, 0x0f, 0x58, 0x49, 0x36, 0xe8, 0x83, | 609 0x0c, 0xe9, 0xf6, 0x78, 0x6b, 0x0f, 0x58, 0x49, 0x36, 0xe8, 0x83, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 616 scoped_ptr<crypto::SecureHash>())); | 620 scoped_ptr<crypto::SecureHash>())); |
| 617 set_expected_data(big_buffer); // Contents of the file on Open. | 621 set_expected_data(big_buffer); // Contents of the file on Open. |
| 618 ASSERT_TRUE(AppendDataToFile(big_buffer)); | 622 ASSERT_TRUE(AppendDataToFile(big_buffer)); |
| 619 ExpectHashValue(kExpectedFullHash, base_file_->Finish()); | 623 ExpectHashValue(kExpectedFullHash, base_file_->Finish()); |
| 620 } | 624 } |
| 621 | 625 |
| 622 // Open a large existing file. The contents doesn't match the known hash. | 626 // Open a large existing file. The contents doesn't match the known hash. |
| 623 TEST_F(BaseFileTest, ExistingBaseFileLargeSizeIncorrectHash) { | 627 TEST_F(BaseFileTest, ExistingBaseFileLargeSizeIncorrectHash) { |
| 624 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); | 628 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); |
| 625 std::string big_buffer(1024 * 200, 'a'); | 629 std::string big_buffer(1024 * 200, 'a'); |
| 626 ASSERT_TRUE(base::WriteFile(file_path, big_buffer.data(), big_buffer.size())); | 630 ASSERT_EQ(static_cast<int>(big_buffer.size()), |
| 631 base::WriteFile(file_path, big_buffer.data(), big_buffer.size())); |
| 627 | 632 |
| 628 // Incorrect hash of partial file (1024*200 * 'a') | 633 // Incorrect hash of partial file (1024*200 * 'a') |
| 629 const uint8_t kExpectedPartialHash[] = { | 634 const uint8_t kExpectedPartialHash[] = { |
| 630 0xc2, 0xa9, 0x08, 0xd9, 0x8f, 0x5d, 0xf9, 0x87, 0xad, 0xe4, 0x1b, | 635 0xc2, 0xa9, 0x08, 0xd9, 0x8f, 0x5d, 0xf9, 0x87, 0xad, 0xe4, 0x1b, |
| 631 0x5f, 0xce, 0x21, 0x30, 0x67, 0xef, 0x6c, 0xc2, 0x1e, 0xf2, 0x24, | 636 0x5f, 0xce, 0x21, 0x30, 0x67, 0xef, 0x6c, 0xc2, 0x1e, 0xf2, 0x24, |
| 632 0x02, 0x12, 0xa4, 0x1e, 0x54, 0xb5, 0xe7, 0xc2, 0x8a, 0xe5}; | 637 0x02, 0x12, 0xa4, 0x1e, 0x54, 0xb5, 0xe7, 0xc2, 0x8a, 0xe5}; |
| 633 | 638 |
| 634 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH, | 639 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH, |
| 635 base_file_->Initialize(file_path, | 640 base_file_->Initialize(file_path, |
| 636 base::FilePath(), | 641 base::FilePath(), |
| 637 base::File(), | 642 base::File(), |
| 638 big_buffer.size(), | 643 big_buffer.size(), |
| 639 std::string(std::begin(kExpectedPartialHash), | 644 std::string(std::begin(kExpectedPartialHash), |
| 640 std::end(kExpectedPartialHash)), | 645 std::end(kExpectedPartialHash)), |
| 641 scoped_ptr<crypto::SecureHash>())); | 646 scoped_ptr<crypto::SecureHash>())); |
| 642 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH); | 647 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH); |
| 643 } | 648 } |
| 644 | 649 |
| 645 // Open an existing file. The size of the file is too short. | 650 // Open an existing file. The size of the file is too short. |
| 646 TEST_F(BaseFileTest, ExistingBaseFileTooShort) { | 651 TEST_F(BaseFileTest, ExistingBaseFileTooShort) { |
| 647 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); | 652 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); |
| 648 ASSERT_TRUE(base::WriteFile(file_path, kTestData1, kTestDataLength1)); | 653 ASSERT_EQ(kTestDataLength1, |
| 654 base::WriteFile(file_path, kTestData1, kTestDataLength1)); |
| 649 | 655 |
| 650 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT, | 656 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT, |
| 651 base_file_->Initialize(file_path, | 657 base_file_->Initialize(file_path, |
| 652 base::FilePath(), | 658 base::FilePath(), |
| 653 base::File(), | 659 base::File(), |
| 654 kTestDataLength1 + 1, | 660 kTestDataLength1 + 1, |
| 655 std::string(), | 661 std::string(), |
| 656 scoped_ptr<crypto::SecureHash>())); | 662 scoped_ptr<crypto::SecureHash>())); |
| 657 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT); | 663 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT); |
| 658 } | 664 } |
| 659 | 665 |
| 660 // Open an existing file. The size is larger than expected. | 666 // Open an existing file. The size is larger than expected. |
| 661 TEST_F(BaseFileTest, ExistingBaseFileKnownHashTooLong) { | 667 TEST_F(BaseFileTest, ExistingBaseFileKnownHashTooLong) { |
| 662 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); | 668 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); |
| 663 std::string contents; | 669 std::string contents; |
| 664 contents.append(kTestData1); | 670 contents.append(kTestData1); |
| 665 contents.append("Something extra"); | 671 contents.append("Something extra"); |
| 666 ASSERT_TRUE(base::WriteFile(file_path, contents.data(), contents.size())); | 672 ASSERT_EQ(static_cast<int>(contents.size()), |
| 673 base::WriteFile(file_path, contents.data(), contents.size())); |
| 667 | 674 |
| 668 std::string hash_so_far(std::begin(kHashOfTestData1), | 675 std::string hash_so_far(std::begin(kHashOfTestData1), |
| 669 std::end(kHashOfTestData1)); | 676 std::end(kHashOfTestData1)); |
| 670 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, | 677 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 671 base_file_->Initialize(file_path, | 678 base_file_->Initialize(file_path, |
| 672 base::FilePath(), | 679 base::FilePath(), |
| 673 base::File(), | 680 base::File(), |
| 674 kTestDataLength1, | 681 kTestDataLength1, |
| 675 hash_so_far, | 682 hash_so_far, |
| 676 scoped_ptr<crypto::SecureHash>())); | 683 scoped_ptr<crypto::SecureHash>())); |
| 677 set_expected_data(kTestData1); // Our starting position. | 684 set_expected_data(kTestData1); // Our starting position. |
| 678 ASSERT_TRUE(AppendDataToFile(kTestData2)); | 685 ASSERT_TRUE(AppendDataToFile(kTestData2)); |
| 679 ASSERT_TRUE(AppendDataToFile(kTestData3)); | 686 ASSERT_TRUE(AppendDataToFile(kTestData3)); |
| 680 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish()); | 687 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish()); |
| 681 } | 688 } |
| 682 | 689 |
| 683 // Open an existing file. The size is large than expected and the hash is | 690 // Open an existing file. The size is large than expected and the hash is |
| 684 // unknown. | 691 // unknown. |
| 685 TEST_F(BaseFileTest, ExistingBaseFileUnknownHashTooLong) { | 692 TEST_F(BaseFileTest, ExistingBaseFileUnknownHashTooLong) { |
| 686 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); | 693 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); |
| 687 std::string contents; | 694 std::string contents; |
| 688 contents.append(kTestData1); | 695 contents.append(kTestData1); |
| 689 contents.append("Something extra"); | 696 contents.append("Something extra"); |
| 690 ASSERT_TRUE(base::WriteFile(file_path, contents.data(), contents.size())); | 697 ASSERT_EQ(static_cast<int>(contents.size()), |
| 698 base::WriteFile(file_path, contents.data(), contents.size())); |
| 691 | 699 |
| 692 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, | 700 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 693 base_file_->Initialize(file_path, | 701 base_file_->Initialize(file_path, |
| 694 base::FilePath(), | 702 base::FilePath(), |
| 695 base::File(), | 703 base::File(), |
| 696 kTestDataLength1, | 704 kTestDataLength1, |
| 697 std::string(), | 705 std::string(), |
| 698 scoped_ptr<crypto::SecureHash>())); | 706 scoped_ptr<crypto::SecureHash>())); |
| 699 set_expected_data(kTestData1); | 707 set_expected_data(kTestData1); |
| 700 ASSERT_TRUE(AppendDataToFile(kTestData2)); | 708 ASSERT_TRUE(AppendDataToFile(kTestData2)); |
| 701 ASSERT_TRUE(AppendDataToFile(kTestData3)); | 709 ASSERT_TRUE(AppendDataToFile(kTestData3)); |
| 702 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish()); | 710 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish()); |
| 703 } | 711 } |
| 704 | 712 |
| 713 // Similar to ExistingBaseFileKnownHashTooLong test, but with a file large |
| 714 // enough to requre multiple Read()s to complete. This provides additional code |
| 715 // coverage for the CalculatePartialHash() logic. |
| 716 TEST_F(BaseFileTest, ExistingBaseFileUnknownHashTooLongForLargeFile) { |
| 717 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); |
| 718 const size_t kFileSize = 1024 * 1024; |
| 719 const size_t kIntermediateSize = kFileSize / 2 + 111; |
| 720 // |contents| is 100 bytes longer than kIntermediateSize. The latter is the |
| 721 // expected size. |
| 722 std::string contents(kIntermediateSize + 100, 'a'); |
| 723 ASSERT_EQ(static_cast<int>(contents.size()), |
| 724 base::WriteFile(file_path, contents.data(), contents.size())); |
| 725 |
| 726 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 727 base_file_->Initialize(file_path, base::FilePath(), base::File(), |
| 728 kIntermediateSize, std::string(), |
| 729 std::unique_ptr<crypto::SecureHash>())); |
| 730 // The extra bytes should be stripped during Initialize(). |
| 731 contents.resize(kIntermediateSize, 'a'); |
| 732 set_expected_data(contents); |
| 733 std::string new_data(kFileSize - kIntermediateSize, 'a'); |
| 734 ASSERT_TRUE(AppendDataToFile(new_data)); |
| 735 const uint8_t kExpectedHash[] = { |
| 736 0x9b, 0xc1, 0xb2, 0xa2, 0x88, 0xb2, 0x6a, 0xf7, 0x25, 0x7a, 0x36, |
| 737 0x27, 0x7a, 0xe3, 0x81, 0x6a, 0x7d, 0x4f, 0x16, 0xe8, 0x9c, 0x1e, |
| 738 0x7e, 0x77, 0xd0, 0xa5, 0xc4, 0x8b, 0xad, 0x62, 0xb3, 0x60, |
| 739 }; |
| 740 ExpectHashValue(kExpectedHash, base_file_->Finish()); |
| 741 } |
| 742 |
| 705 // Test that a temporary file is created in the default download directory. | 743 // Test that a temporary file is created in the default download directory. |
| 706 TEST_F(BaseFileTest, CreatedInDefaultDirectory) { | 744 TEST_F(BaseFileTest, CreatedInDefaultDirectory) { |
| 707 ASSERT_TRUE(base_file_->full_path().empty()); | 745 ASSERT_TRUE(base_file_->full_path().empty()); |
| 708 ASSERT_TRUE(InitializeFile()); | 746 ASSERT_TRUE(InitializeFile()); |
| 709 EXPECT_FALSE(base_file_->full_path().empty()); | 747 EXPECT_FALSE(base_file_->full_path().empty()); |
| 710 | 748 |
| 711 // On Windows, CreateTemporaryFileInDir() will cause a path with short names | 749 // On Windows, CreateTemporaryFileInDir() will cause a path with short names |
| 712 // to be expanded into a path with long names. Thus temp_dir.path() might not | 750 // to be expanded into a path with long names. Thus temp_dir.path() might not |
| 713 // be a string-wise match to base_file_->full_path().DirName() even though | 751 // be a string-wise match to base_file_->full_path().DirName() even though |
| 714 // they are in the same directory. | 752 // they are in the same directory. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 731 | 769 |
| 732 const char kData[] = "hello"; | 770 const char kData[] = "hello"; |
| 733 const int kDataLength = static_cast<int>(arraysize(kData) - 1); | 771 const int kDataLength = static_cast<int>(arraysize(kData) - 1); |
| 734 ASSERT_EQ(kDataLength, base::WriteFile(full_path, kData, kDataLength)); | 772 ASSERT_EQ(kDataLength, base::WriteFile(full_path, kData, kDataLength)); |
| 735 // The file that we created here should stick around when the BaseFile is | 773 // The file that we created here should stick around when the BaseFile is |
| 736 // destroyed during TearDown. | 774 // destroyed during TearDown. |
| 737 expect_file_survives_ = true; | 775 expect_file_survives_ = true; |
| 738 } | 776 } |
| 739 | 777 |
| 740 } // namespace content | 778 } // namespace content |
| OLD | NEW |