From 7d8544ad898255fc4dffab0a36c6cb69fce421a1 Mon Sep 17 00:00:00 2001 From: Artem Strygin Date: Sat, 29 Jul 2017 00:57:23 +0300 Subject: Implement read Session. Helper for validate read problems locally, Change-Id: I2bfbbaab8a67c0fd0cee3dadcd0f9cad5953101c Reviewed-on: https://pdfium-review.googlesource.com/9552 Reviewed-by: Lei Zhang Commit-Queue: Art Snake --- core/fpdfapi/parser/cpdf_read_validator.cpp | 13 ++++ core/fpdfapi/parser/cpdf_read_validator.h | 11 +++ .../parser/cpdf_read_validator_unittest.cpp | 80 ++++++++++++++++++++++ 3 files changed, 104 insertions(+) diff --git a/core/fpdfapi/parser/cpdf_read_validator.cpp b/core/fpdfapi/parser/cpdf_read_validator.cpp index 148ecfd424..be20f18f33 100644 --- a/core/fpdfapi/parser/cpdf_read_validator.cpp +++ b/core/fpdfapi/parser/cpdf_read_validator.cpp @@ -26,6 +26,19 @@ FX_FILESIZE AlignUp(FX_FILESIZE offset) { } // namespace +CPDF_ReadValidator::Session::Session(CPDF_ReadValidator* validator) + : validator_(validator) { + ASSERT(validator_); + saved_read_error_ = validator_->read_error_; + saved_has_unavailable_data_ = validator_->has_unavailable_data_; + validator_->ResetErrors(); +} + +CPDF_ReadValidator::Session::~Session() { + validator_->read_error_ |= saved_read_error_; + validator_->has_unavailable_data_ |= saved_has_unavailable_data_; +} + CPDF_ReadValidator::CPDF_ReadValidator( const CFX_RetainPtr& file_read, CPDF_DataAvail::FileAvail* file_avail) diff --git a/core/fpdfapi/parser/cpdf_read_validator.h b/core/fpdfapi/parser/cpdf_read_validator.h index da8acfe23b..9cc22c1ccc 100644 --- a/core/fpdfapi/parser/cpdf_read_validator.h +++ b/core/fpdfapi/parser/cpdf_read_validator.h @@ -12,6 +12,17 @@ class CPDF_ReadValidator : public IFX_SeekableReadStream { template friend CFX_RetainPtr pdfium::MakeRetain(Args&&... args); + class Session { + public: + explicit Session(CPDF_ReadValidator* validator); + ~Session(); + + private: + CFX_UnownedPtr validator_; + bool saved_read_error_; + bool saved_has_unavailable_data_; + }; + void SetDownloadHints(CPDF_DataAvail::DownloadHints* hints) { hints_ = hints; } diff --git a/core/fpdfapi/parser/cpdf_read_validator_unittest.cpp b/core/fpdfapi/parser/cpdf_read_validator_unittest.cpp index f0e47f552c..cb6c07ecb6 100644 --- a/core/fpdfapi/parser/cpdf_read_validator_unittest.cpp +++ b/core/fpdfapi/parser/cpdf_read_validator_unittest.cpp @@ -178,3 +178,83 @@ TEST(CPDF_ReadValidatorTest, IntOverflow) { EXPECT_FALSE(validator->read_error()); EXPECT_FALSE(validator->has_unavailable_data()); } + +TEST(CPDF_ReadValidatorTest, Session) { + std::vector test_data(kTestDataSize); + + auto file = pdfium::MakeRetain(); + MockFileAvail file_avail; + MockDownloadHints hints; + auto validator = pdfium::MakeRetain(file, &file_avail); + validator->SetDownloadHints(&hints); + + const CPDF_ReadValidator::Session read_session(validator.Get()); + ASSERT_FALSE(validator->has_read_problems()); + + // Data is unavailable + validator->ReadBlock(test_data.data(), 0, 100); + + EXPECT_TRUE(validator->has_read_problems()); + EXPECT_TRUE(validator->has_unavailable_data()); + EXPECT_FALSE(validator->read_error()); + + { + const CPDF_ReadValidator::Session read_subsession(validator.Get()); + // The read problems should be hidden. + EXPECT_FALSE(validator->has_read_problems()); + + file_avail.SetAvailableRange(0, 100); + // Read fail. + validator->ReadBlock(test_data.data(), 0, 100); + EXPECT_TRUE(validator->has_read_problems()); + EXPECT_TRUE(validator->has_unavailable_data()); + EXPECT_TRUE(validator->read_error()); + } + + // The problems should be merged + EXPECT_TRUE(validator->has_read_problems()); + EXPECT_TRUE(validator->has_unavailable_data()); + EXPECT_TRUE(validator->read_error()); +} + +TEST(CPDF_ReadValidatorTest, SessionReset) { + std::vector test_data(kTestDataSize); + + auto file = pdfium::MakeRetain(); + MockFileAvail file_avail; + MockDownloadHints hints; + auto validator = pdfium::MakeRetain(file, &file_avail); + validator->SetDownloadHints(&hints); + + const CPDF_ReadValidator::Session read_session(validator.Get()); + ASSERT_FALSE(validator->has_read_problems()); + + // Data is unavailable + validator->ReadBlock(test_data.data(), 0, 100); + + EXPECT_TRUE(validator->has_read_problems()); + EXPECT_TRUE(validator->has_unavailable_data()); + EXPECT_FALSE(validator->read_error()); + + { + const CPDF_ReadValidator::Session read_subsession(validator.Get()); + // The read problems should be hidden. + EXPECT_FALSE(validator->has_read_problems()); + + file_avail.SetAvailableRange(0, 100); + // Read fail. + validator->ReadBlock(test_data.data(), 0, 100); + EXPECT_TRUE(validator->has_read_problems()); + EXPECT_TRUE(validator->has_unavailable_data()); + EXPECT_TRUE(validator->read_error()); + + // Reset session. + validator->ResetErrors(); + EXPECT_FALSE(validator->has_read_problems()); + } + + // The problems should be restored. + EXPECT_TRUE(validator->has_read_problems()); + EXPECT_TRUE(validator->has_unavailable_data()); + EXPECT_FALSE(validator->read_error()); +} -- cgit v1.2.3