Fix crashes in FPDFClipPath_CountPaths() and friends.

FPDFClipPath_CountPaths(), FPDFClipPath_CountPathSegments(), and
FPDFClipPath_GetPathSegment() all need to verify the FPDF_CLIPPATH
passed in has a reference.

Bug: pdfium:1399
Change-Id: Ib89eff933882e2ccb1736828799547fb9ac0d29b
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/61090
Commit-Queue: dsinclair <dsinclair@chromium.org>
Reviewed-by: dsinclair <dsinclair@chromium.org>
diff --git a/fpdfsdk/fpdf_edit_embeddertest.cpp b/fpdfsdk/fpdf_edit_embeddertest.cpp
index addaac8..4c08626 100644
--- a/fpdfsdk/fpdf_edit_embeddertest.cpp
+++ b/fpdfsdk/fpdf_edit_embeddertest.cpp
@@ -533,6 +533,45 @@
   UnloadPage(page);
 }
 
+TEST_F(FPDFEditEmbedderTest, BUG_1399) {
+  // Load document with a clipped rectangle.
+  EXPECT_TRUE(OpenDocument("bug_1399.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  ASSERT_TRUE(page);
+
+  ASSERT_EQ(7, FPDFPage_CountObjects(page));
+
+  FPDF_PAGEOBJECT obj = FPDFPage_GetObject(page, 0);
+  ASSERT_TRUE(obj);
+
+  ASSERT_EQ(2, FPDFPath_CountSegments(obj));
+
+  FPDF_PATHSEGMENT segment = FPDFPath_GetPathSegment(obj, 0);
+  float x;
+  float y;
+  EXPECT_TRUE(FPDFPathSegment_GetPoint(segment, &x, &y));
+  EXPECT_FLOAT_EQ(107.718f, x);
+  EXPECT_FLOAT_EQ(719.922f, y);
+  EXPECT_EQ(FPDF_SEGMENT_MOVETO, FPDFPathSegment_GetType(segment));
+  EXPECT_FALSE(FPDFPathSegment_GetClose(segment));
+
+  segment = FPDFPath_GetPathSegment(obj, 1);
+  EXPECT_TRUE(FPDFPathSegment_GetPoint(segment, &x, &y));
+  EXPECT_FLOAT_EQ(394.718f, x);
+  EXPECT_FLOAT_EQ(719.922f, y);
+  EXPECT_EQ(FPDF_SEGMENT_LINETO, FPDFPathSegment_GetType(segment));
+  EXPECT_FALSE(FPDFPathSegment_GetClose(segment));
+
+  FPDF_CLIPPATH clip_path = FPDFPageObj_GetClipPath(obj);
+  ASSERT_TRUE(clip_path);
+
+  EXPECT_EQ(-1, FPDFClipPath_CountPaths(clip_path));
+  EXPECT_EQ(-1, FPDFClipPath_CountPathSegments(clip_path, 0));
+  EXPECT_FALSE(FPDFClipPath_GetPathSegment(clip_path, 0, 0));
+
+  UnloadPage(page);
+}
+
 // TODO(crbug.com/pdfium/11): Fix this test and enable.
 #if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_)
 #define MAYBE_SetText DISABLED_SetText
diff --git a/fpdfsdk/fpdf_transformpage.cpp b/fpdfsdk/fpdf_transformpage.cpp
index 788c393..bc8aea8 100644
--- a/fpdfsdk/fpdf_transformpage.cpp
+++ b/fpdfsdk/fpdf_transformpage.cpp
@@ -281,7 +281,7 @@
 
 FPDF_EXPORT int FPDF_CALLCONV FPDFClipPath_CountPaths(FPDF_CLIPPATH clip_path) {
   CPDF_ClipPath* pClipPath = CPDFClipPathFromFPDFClipPath(clip_path);
-  if (!pClipPath)
+  if (!pClipPath || !pClipPath->HasRef())
     return -1;
 
   return pClipPath->GetPathCount();
@@ -290,7 +290,7 @@
 FPDF_EXPORT int FPDF_CALLCONV
 FPDFClipPath_CountPathSegments(FPDF_CLIPPATH clip_path, int path_index) {
   CPDF_ClipPath* pClipPath = CPDFClipPathFromFPDFClipPath(clip_path);
-  if (!pClipPath)
+  if (!pClipPath || !pClipPath->HasRef())
     return -1;
 
   if (path_index < 0 ||
@@ -307,7 +307,7 @@
                             int path_index,
                             int segment_index) {
   CPDF_ClipPath* pClipPath = CPDFClipPathFromFPDFClipPath(clip_path);
-  if (!pClipPath)
+  if (!pClipPath || !pClipPath->HasRef())
     return nullptr;
 
   if (path_index < 0 ||
diff --git a/testing/resources/bug_1399.pdf b/testing/resources/bug_1399.pdf
new file mode 100644
index 0000000..1b2e30c
--- /dev/null
+++ b/testing/resources/bug_1399.pdf
Binary files differ