diff options
author | Artem Strygin <art-snake@yandex-team.ru> | 2017-08-29 00:26:42 +0300 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2017-08-29 22:59:01 +0000 |
commit | 304eefb58759e56be3fb357c78204accd4fa98fc (patch) | |
tree | d7640b3ba8a473856457feba0f41da2453ef6b16 /core/fpdfapi/parser/cpdf_page_object_avail_unittest.cpp | |
parent | 3fab4e35539e29c4ded08a424db3b1c7fbfa03fc (diff) | |
download | pdfium-304eefb58759e56be3fb357c78204accd4fa98fc.tar.xz |
Implement CPDF_ObjectAvail.
This is non recursive replacement for CPDF_DataAvail::AreObjectsAvailable.
Also added tests.
Change-Id: I546289fc0963d2343253755850f55af8c0bd8e4c
Reviewed-on: https://pdfium-review.googlesource.com/11430
Reviewed-by: dsinclair <dsinclair@chromium.org>
Commit-Queue: Art Snake <art-snake@yandex-team.ru>
Diffstat (limited to 'core/fpdfapi/parser/cpdf_page_object_avail_unittest.cpp')
-rw-r--r-- | core/fpdfapi/parser/cpdf_page_object_avail_unittest.cpp | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/core/fpdfapi/parser/cpdf_page_object_avail_unittest.cpp b/core/fpdfapi/parser/cpdf_page_object_avail_unittest.cpp new file mode 100644 index 0000000000..a6454cd9fe --- /dev/null +++ b/core/fpdfapi/parser/cpdf_page_object_avail_unittest.cpp @@ -0,0 +1,137 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/fpdfapi/parser/cpdf_page_object_avail.h" + +#include <map> +#include <memory> +#include <utility> + +#include "core/fpdfapi/parser/cpdf_array.h" +#include "core/fpdfapi/parser/cpdf_dictionary.h" +#include "core/fpdfapi/parser/cpdf_indirect_object_holder.h" +#include "core/fpdfapi/parser/cpdf_read_validator.h" +#include "core/fpdfapi/parser/cpdf_reference.h" +#include "core/fpdfapi/parser/cpdf_string.h" +#include "core/fxcrt/fx_stream.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/base/ptr_util.h" + +namespace { + +class InvalidReader : public IFX_SeekableReadStream { + public: + template <typename T, typename... Args> + friend CFX_RetainPtr<T> pdfium::MakeRetain(Args&&... args); + + // IFX_SeekableReadStream overrides: + bool ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override { + return false; + } + FX_FILESIZE GetSize() override { return 100; } + + private: + InvalidReader() {} + ~InvalidReader() override {} +}; + +class TestReadValidator : public CPDF_ReadValidator { + public: + template <typename T, typename... Args> + friend CFX_RetainPtr<T> pdfium::MakeRetain(Args&&... args); + + void SimulateReadError() { ReadBlock(nullptr, 0, 1); } + + protected: + TestReadValidator() + : CPDF_ReadValidator(pdfium::MakeRetain<InvalidReader>(), nullptr) {} + ~TestReadValidator() override {} +}; + +class TestHolder : public CPDF_IndirectObjectHolder { + public: + enum class ObjectState { + Unavailable, + Available, + }; + TestHolder() : validator_(pdfium::MakeRetain<TestReadValidator>()) {} + ~TestHolder() override {} + + // CPDF_IndirectObjectHolder overrides: + CPDF_Object* GetOrParseIndirectObject(uint32_t objnum) override { + auto it = objects_data_.find(objnum); + if (it == objects_data_.end()) + return nullptr; + + ObjectData& obj_data = it->second; + if (obj_data.state == ObjectState::Unavailable) { + validator_->SimulateReadError(); + return nullptr; + } + return obj_data.object.get(); + } + + CFX_RetainPtr<CPDF_ReadValidator> GetValidator() { return validator_; } + + void AddObject(uint32_t objnum, + std::unique_ptr<CPDF_Object> object, + ObjectState state) { + ObjectData object_data; + object_data.object = std::move(object); + object_data.state = state; + ASSERT(objects_data_.find(objnum) == objects_data_.end()); + objects_data_[objnum] = std::move(object_data); + } + + void SetObjectState(uint32_t objnum, ObjectState state) { + auto it = objects_data_.find(objnum); + ASSERT(it != objects_data_.end()); + ObjectData& obj_data = it->second; + obj_data.state = state; + } + + CPDF_Object* GetTestObject(uint32_t objnum) { + auto it = objects_data_.find(objnum); + if (it == objects_data_.end()) + return nullptr; + return it->second.object.get(); + } + + private: + struct ObjectData { + std::unique_ptr<CPDF_Object> object; + ObjectState state = ObjectState::Unavailable; + }; + std::map<uint32_t, ObjectData> objects_data_; + CFX_RetainPtr<TestReadValidator> validator_; +}; + +} // namespace + +TEST(CPDF_PageObjectAvailTest, ExcludePages) { + TestHolder holder; + holder.AddObject(1, pdfium::MakeUnique<CPDF_Dictionary>(), + TestHolder::ObjectState::Available); + holder.GetTestObject(1)->GetDict()->SetNewFor<CPDF_Reference>("Kids", &holder, + 2); + holder.AddObject(2, pdfium::MakeUnique<CPDF_Array>(), + TestHolder::ObjectState::Available); + holder.GetTestObject(2)->AsArray()->AddNew<CPDF_Reference>(&holder, 3); + + holder.AddObject(3, pdfium::MakeUnique<CPDF_Dictionary>(), + TestHolder::ObjectState::Available); + holder.GetTestObject(3)->GetDict()->SetFor( + "Type", pdfium::MakeUnique<CPDF_String>(nullptr, "Page", false)); + holder.GetTestObject(3)->GetDict()->SetNewFor<CPDF_Reference>("OtherPageData", + &holder, 4); + // Add unavailable object related to other page. + holder.AddObject( + 4, pdfium::MakeUnique<CPDF_String>(nullptr, "Other page data", false), + TestHolder::ObjectState::Unavailable); + + CPDF_PageObjectAvail avail(holder.GetValidator().Get(), &holder, 1); + // Now object should be available, although the object '4' is not available, + // because it is in skipped other page. + EXPECT_EQ(CPDF_DataAvail::DocAvailStatus::DataAvailable, avail.CheckAvail()); +} |