summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/fpdfapi/parser/cpdf_read_validator.cpp13
-rw-r--r--core/fpdfapi/parser/cpdf_read_validator.h11
-rw-r--r--core/fpdfapi/parser/cpdf_read_validator_unittest.cpp80
3 files changed, 104 insertions, 0 deletions
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<IFX_SeekableReadStream>& 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 <typename T, typename... Args>
friend CFX_RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+ class Session {
+ public:
+ explicit Session(CPDF_ReadValidator* validator);
+ ~Session();
+
+ private:
+ CFX_UnownedPtr<CPDF_ReadValidator> 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<uint8_t> test_data(kTestDataSize);
+
+ auto file = pdfium::MakeRetain<InvalidReader>();
+ MockFileAvail file_avail;
+ MockDownloadHints hints;
+ auto validator = pdfium::MakeRetain<CPDF_ReadValidator>(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<uint8_t> test_data(kTestDataSize);
+
+ auto file = pdfium::MakeRetain<InvalidReader>();
+ MockFileAvail file_avail;
+ MockDownloadHints hints;
+ auto validator = pdfium::MakeRetain<CPDF_ReadValidator>(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());
+}