Add test for FPDF_GetPageSizeByIndex()

Ensure that FPDF_GetPageSizeByIndex() doesn't do a full page parse.
Issue was noticed on CL https://pdfium-review.googlesource.com/32830

Change-Id: I51966e0b91e1a002d33ee51f00c0428fa1cda04d
Reviewed-on: https://pdfium-review.googlesource.com/33792
Commit-Queue: dsinclair <dsinclair@chromium.org>
Reviewed-by: dsinclair <dsinclair@chromium.org>
diff --git a/core/fpdfapi/page/cpdf_pageobjectholder.cpp b/core/fpdfapi/page/cpdf_pageobjectholder.cpp
index 87a1aeb..4d4fc56 100644
--- a/core/fpdfapi/page/cpdf_pageobjectholder.cpp
+++ b/core/fpdfapi/page/cpdf_pageobjectholder.cpp
@@ -14,6 +14,7 @@
 #include "core/fpdfapi/page/cpdf_contentparser.h"
 #include "core/fpdfapi/page/cpdf_pageobject.h"
 #include "core/fpdfapi/parser/cpdf_dictionary.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
 
 CPDF_PageObjectHolder::CPDF_PageObjectHolder(CPDF_Document* pDoc,
                                              CPDF_Dictionary* pFormDict)
@@ -38,6 +39,8 @@
     return;
 
   m_ParseState = CONTENT_PARSED;
+  m_pDocument->IncrementParsedPageCount();
+
   if (m_pParser->GetCurStates())
     m_LastCTM = m_pParser->GetCurStates()->m_CTM;
 
diff --git a/core/fpdfapi/parser/cpdf_document.h b/core/fpdfapi/parser/cpdf_document.h
index fe3f170..a34b25d 100644
--- a/core/fpdfapi/parser/cpdf_document.h
+++ b/core/fpdfapi/parser/cpdf_document.h
@@ -106,6 +106,9 @@
   void CreateNewDoc();
   CPDF_Dictionary* CreateNewPage(int iPage);
 
+  void IncrementParsedPageCount() { ++m_ParsedPageCount; }
+  uint32_t GetParsedPageCountForTesting() { return m_ParsedPageCount; }
+
   CPDF_Font* AddStandardFont(const char* font, CPDF_FontEncoding* pEncoding);
   CPDF_Font* AddFont(CFX_Font* pFont, int charset, bool bVert);
 #if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
@@ -165,6 +168,7 @@
   bool m_bLinearized;
   int m_iFirstPageNo;
   uint32_t m_dwFirstPageObjNum;
+  uint32_t m_ParsedPageCount = 0;
   std::unique_ptr<CPDF_DocPageData> m_pDocPage;
   std::unique_ptr<CPDF_DocRenderData> m_pDocRender;
   std::unique_ptr<JBig2_DocumentContext> m_pCodecContext;
diff --git a/fpdfsdk/fpdf_doc_embeddertest.cpp b/fpdfsdk/fpdf_doc_embeddertest.cpp
index c1f5e02..a9eb4b8 100644
--- a/fpdfsdk/fpdf_doc_embeddertest.cpp
+++ b/fpdfsdk/fpdf_doc_embeddertest.cpp
@@ -7,7 +7,9 @@
 #include <string>
 #include <vector>
 
+#include "core/fpdfapi/parser/cpdf_document.h"
 #include "core/fxcrt/fx_string.h"
+#include "fpdfsdk/cpdfsdk_helpers.h"
 #include "public/cpp/fpdf_scopers.h"
 #include "public/fpdf_doc.h"
 #include "public/fpdf_edit.h"
@@ -20,6 +22,7 @@
 
 TEST_F(FPDFDocEmbeddertest, MultipleSamePage) {
   EXPECT_TRUE(OpenDocument("hello_world.pdf"));
+  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document());
 
   std::set<FPDF_PAGE> unique_pages;
   std::vector<ScopedFPDFPage> owned_pages(4);
@@ -29,8 +32,10 @@
   }
 #ifdef PDF_ENABLE_XFA
   EXPECT_EQ(1u, unique_pages.size());
+  EXPECT_EQ(1u, pDoc->GetParsedPageCountForTesting());
 #else   // PDF_ENABLE_XFA
   EXPECT_EQ(4u, unique_pages.size());
+  EXPECT_EQ(4u, pDoc->GetParsedPageCountForTesting());
 #endif  // PDF_ENABLE_XFA
 }
 
diff --git a/fpdfsdk/fpdf_view_embeddertest.cpp b/fpdfsdk/fpdf_view_embeddertest.cpp
index 7cc5478..cef5e9a 100644
--- a/fpdfsdk/fpdf_view_embeddertest.cpp
+++ b/fpdfsdk/fpdf_view_embeddertest.cpp
@@ -7,6 +7,8 @@
 #include <memory>
 #include <string>
 
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "fpdfsdk/cpdfsdk_helpers.h"
 #include "fpdfsdk/fpdf_view_c_api_test.h"
 #include "public/cpp/fpdf_scopers.h"
 #include "public/fpdfview.h"
@@ -589,6 +591,40 @@
   UnloadPage(page);
 }
 
+TEST_F(FPDFViewEmbeddertest, FPDF_GetPageSizeByIndex) {
+  EXPECT_TRUE(OpenDocument("rectangles.pdf"));
+  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document());
+
+  double width = 0;
+  double height = 0;
+
+  // Page -1 doesn't exist.
+  EXPECT_FALSE(FPDF_GetPageSizeByIndex(document(), -1, &width, &height));
+
+  // Page 1 doesn't exist.
+  EXPECT_FALSE(FPDF_GetPageSizeByIndex(document(), 1, &width, &height));
+
+  // Page 0 exists.
+  EXPECT_TRUE(FPDF_GetPageSizeByIndex(document(), 0, &width, &height));
+  EXPECT_EQ(200.0, width);
+  EXPECT_EQ(300.0, height);
+
+#ifdef PDF_ENABLE_XFA
+  // TODO(tsepez): XFA must obtain this size without parsing.
+  EXPECT_EQ(1u, pDoc->GetParsedPageCountForTesting());
+#else   // PDF_ENABLE_XFA
+  EXPECT_EQ(0u, pDoc->GetParsedPageCountForTesting());
+#endif  // PDF_ENABLE_XFA
+
+  // Double-check against values from when page is actually parsed.
+  FPDF_PAGE page = LoadPage(0);
+  ASSERT_TRUE(page);
+  EXPECT_EQ(width, FPDF_GetPageWidth(page));
+  EXPECT_EQ(height, FPDF_GetPageHeight(page));
+  EXPECT_EQ(1u, pDoc->GetParsedPageCountForTesting());
+  UnloadPage(page);
+}
+
 class UnSupRecordDelegate : public EmbedderTest::Delegate {
  public:
   UnSupRecordDelegate() : type_(-1) {}