Do page load/unload checks in EmbedderTest for saved pages.

Change-Id: I9286b24957f9d96da10869098eb0e04991bd6571
Reviewed-on: https://pdfium-review.googlesource.com/25570
Reviewed-by: dsinclair <dsinclair@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/testing/embedder_test.cpp b/testing/embedder_test.cpp
index 32c761e..e49f289 100644
--- a/testing/embedder_test.cpp
+++ b/testing/embedder_test.cpp
@@ -8,6 +8,7 @@
 
 #include <fstream>
 #include <list>
+#include <map>
 #include <memory>
 #include <string>
 #include <utility>
@@ -81,6 +82,7 @@
   // Use an EXPECT_EQ() here and continue to let TearDown() finish as cleanly as
   // possible. This can fail when an ASSERT test fails in a test case.
   EXPECT_EQ(0U, page_map_.size());
+  EXPECT_EQ(0U, saved_page_map_.size());
 
   if (document_) {
     FORM_DoDocumentAAction(form_handle_, FPDFDOC_AACTION_WC);
@@ -260,7 +262,6 @@
 
   FORM_OnAfterLoadPage(page, form_handle_);
   FORM_DoPageAAction(page, form_handle_, FPDFPAGE_AACTION_OPEN);
-  // Cache the page.
   page_map_[page_number] = page;
   return page;
 }
@@ -307,6 +308,10 @@
 std::unique_ptr<void, FPDFBitmapDeleter> EmbedderTest::RenderSavedPageWithFlags(
     FPDF_PAGE page,
     int flags) {
+  if (GetPageNumberForSavedPage(page) < 0) {
+    NOTREACHED();
+    return nullptr;
+  }
   return RenderPageWithFlags(page, saved_form_handle_, flags);
 }
 
@@ -362,18 +367,34 @@
 }
 
 FPDF_PAGE EmbedderTest::LoadSavedPage(int page_number) {
-  ASSERT(saved_document_);
+  ASSERT(saved_form_handle_);
+  ASSERT(page_number >= 0);
+  ASSERT(!pdfium::ContainsKey(saved_page_map_, page_number));
 
-  EXPECT_LT(page_number, FPDF_GetPageCount(saved_document_));
   FPDF_PAGE page = FPDF_LoadPage(saved_document_, page_number);
+  if (!page)
+    return nullptr;
 
-  ASSERT(page);
+  FORM_OnAfterLoadPage(page, saved_form_handle_);
+  FORM_DoPageAAction(page, saved_form_handle_, FPDFPAGE_AACTION_OPEN);
+  saved_page_map_[page_number] = page;
   return page;
 }
 
 void EmbedderTest::CloseSavedPage(FPDF_PAGE page) {
-  ASSERT(page);
+  ASSERT(saved_form_handle_);
+
+  int page_number = GetPageNumberForSavedPage(page);
+  if (page_number < 0) {
+    NOTREACHED();
+    return;
+  }
+
+  FORM_DoPageAAction(page, saved_form_handle_, FPDFPAGE_AACTION_CLOSE);
+  FORM_OnBeforeClosePage(page, saved_form_handle_);
   FPDF_ClosePage(page);
+
+  saved_page_map_.erase(page_number);
 }
 
 void EmbedderTest::VerifySavedRendering(FPDF_PAGE page,
@@ -531,8 +552,10 @@
   return 1;
 }
 
-int EmbedderTest::GetPageNumberForLoadedPage(FPDF_PAGE page) const {
-  for (const auto& it : page_map_) {
+// static
+int EmbedderTest::GetPageNumberForPage(const PageNumberToHandleMap& page_map,
+                                       FPDF_PAGE page) {
+  for (const auto& it : page_map) {
     if (it.second == page) {
       int page_number = it.first;
       ASSERT(page_number >= 0);
@@ -541,3 +564,11 @@
   }
   return -1;
 }
+
+int EmbedderTest::GetPageNumberForLoadedPage(FPDF_PAGE page) const {
+  return GetPageNumberForPage(page_map_, page);
+}
+
+int EmbedderTest::GetPageNumberForSavedPage(FPDF_PAGE page) const {
+  return GetPageNumberForPage(saved_page_map_, page);
+}
diff --git a/testing/embedder_test.h b/testing/embedder_test.h
index c8fce48..25896dc 100644
--- a/testing/embedder_test.h
+++ b/testing/embedder_test.h
@@ -163,6 +163,8 @@
   RenderPageWithFlags(FPDF_PAGE page, FPDF_FORMHANDLE handle, int flags);
 
  protected:
+  using PageNumberToHandleMap = std::map<int, FPDF_PAGE>;
+
   bool OpenDocumentHelper(const char* password,
                           bool must_linearize,
                           FakeFileAccess* network_simulator,
@@ -195,10 +197,12 @@
                                 unsigned char* buf,
                                 unsigned long size);
 
+  // See comments in the respective non-Saved versions of these methods.
   FPDF_DOCUMENT OpenSavedDocument(const char* password = nullptr);
   void CloseSavedDocument();
   FPDF_PAGE LoadSavedPage(int page_number);
   void CloseSavedPage(FPDF_PAGE page);
+
   void VerifySavedRendering(FPDF_PAGE page,
                             int width,
                             int height,
@@ -220,7 +224,7 @@
   TestLoader* loader_ = nullptr;
   size_t file_length_ = 0;
   std::unique_ptr<char, pdfium::FreeDeleter> file_contents_;
-  std::map<int, FPDF_PAGE> page_map_;
+  PageNumberToHandleMap page_map_;
 
   FPDF_DOCUMENT saved_document_ = nullptr;
   FPDF_FORMHANDLE saved_form_handle_ = nullptr;
@@ -228,6 +232,7 @@
   FPDF_FILEACCESS saved_file_access_;  // must outlive |saved_avail_|.
   // must outlive |saved_avail_|.
   std::unique_ptr<FakeFileAccess> saved_fake_file_access_;
+  PageNumberToHandleMap saved_page_map_;
 
  private:
   static void UnsupportedHandlerTrampoline(UNSUPPORT_INFO*, int type);
@@ -247,10 +252,16 @@
                                 const void* data,
                                 unsigned long size);
 
+  // Helper method for the methods below.
+  static int GetPageNumberForPage(const PageNumberToHandleMap& page_map,
+                                  FPDF_PAGE page);
   // Find |page| inside |page_map_| and return the associated page number, or -1
   // if |page| cannot be found.
   int GetPageNumberForLoadedPage(FPDF_PAGE page) const;
 
+  // Same as GetPageNumberForLoadedPage(), but with |saved_page_map_|.
+  int GetPageNumberForSavedPage(FPDF_PAGE page) const;
+
   std::string data_string_;
 };