Make FPDFImageObj_SetBitmap() behavior match comments.

This makes the behavior match FPDFImageObj_LoadJpegFile() as well. Add
unit test. Also add ScopedFPDFPageObject and use it in the test.

Change-Id: I7d149cf939857ed1e4d087d62bbc35098cbaa7b3
Reviewed-on: https://pdfium-review.googlesource.com/c/48456
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/fpdfsdk/fpdf_editimg.cpp b/fpdfsdk/fpdf_editimg.cpp
index eae3f32..fccd9cb 100644
--- a/fpdfsdk/fpdf_editimg.cpp
+++ b/fpdfsdk/fpdf_editimg.cpp
@@ -160,9 +160,6 @@
                        int count,
                        FPDF_PAGEOBJECT image_object,
                        FPDF_BITMAP bitmap) {
-  if (!pages)
-    return false;
-
   CPDF_ImageObject* pImgObj = CPDFImageObjectFromFPDFPageObject(image_object);
   if (!pImgObj)
     return false;
@@ -170,11 +167,14 @@
   if (!bitmap)
     return false;
 
-  for (int index = 0; index < count; index++) {
-    CPDF_Page* pPage = CPDFPageFromFPDFPage(pages[index]);
-    if (pPage)
-      pImgObj->GetImage()->ResetCache(pPage);
+  if (pages) {
+    for (int index = 0; index < count; index++) {
+      CPDF_Page* pPage = CPDFPageFromFPDFPage(pages[index]);
+      if (pPage)
+        pImgObj->GetImage()->ResetCache(pPage);
+    }
   }
+
   RetainPtr<CFX_DIBitmap> holder(CFXDIBitmapFromFPDFBitmap(bitmap));
   pImgObj->GetImage()->SetImage(holder);
   pImgObj->CalcBoundingBox();
diff --git a/fpdfsdk/fpdf_editimg_unittest.cpp b/fpdfsdk/fpdf_editimg_unittest.cpp
index 16e464d..fa04758 100644
--- a/fpdfsdk/fpdf_editimg_unittest.cpp
+++ b/fpdfsdk/fpdf_editimg_unittest.cpp
@@ -5,6 +5,7 @@
 #include "public/fpdf_edit.h"
 
 #include "core/fpdfapi/cpdf_modulemgr.h"
+#include "public/cpp/fpdf_scopers.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 class PDFEditImgTest : public testing::Test {
@@ -70,6 +71,20 @@
   FPDF_CloseDocument(doc);
 }
 
+TEST_F(PDFEditImgTest, SetBitmap) {
+  ScopedFPDFDocument doc(FPDF_CreateNewDocument());
+  ScopedFPDFPage page(FPDFPage_New(doc.get(), 0, 100, 100));
+  ScopedFPDFPageObject image(FPDFPageObj_NewImageObj(doc.get()));
+  ScopedFPDFBitmap bitmap(FPDFBitmap_Create(100, 100, 0));
+
+  FPDF_PAGE page_ptr = page.get();
+  FPDF_PAGE* pages = &page_ptr;
+  EXPECT_TRUE(FPDFImageObj_SetBitmap(nullptr, 1, image.get(), bitmap.get()));
+  EXPECT_TRUE(FPDFImageObj_SetBitmap(pages, 0, image.get(), bitmap.get()));
+  EXPECT_FALSE(FPDFImageObj_SetBitmap(pages, 1, nullptr, bitmap.get()));
+  EXPECT_FALSE(FPDFImageObj_SetBitmap(pages, 1, image.get(), nullptr));
+}
+
 TEST_F(PDFEditImgTest, GetSetImageMatrix) {
   FPDF_DOCUMENT doc = FPDF_CreateNewDocument();
   FPDF_PAGEOBJECT image = FPDFPageObj_NewImageObj(doc);
diff --git a/public/cpp/fpdf_deleters.h b/public/cpp/fpdf_deleters.h
index d9d95cd..5275381 100644
--- a/public/cpp/fpdf_deleters.h
+++ b/public/cpp/fpdf_deleters.h
@@ -31,16 +31,16 @@
   inline void operator()(FPDF_DOCUMENT doc) { FPDF_CloseDocument(doc); }
 };
 
+struct FPDFFontDeleter {
+  inline void operator()(FPDF_FONT font) { FPDFFont_Close(font); }
+};
+
 struct FPDFFormHandleDeleter {
   inline void operator()(FPDF_FORMHANDLE form) {
     FPDFDOC_ExitFormFillEnvironment(form);
   }
 };
 
-struct FPDFTextPageDeleter {
-  inline void operator()(FPDF_TEXTPAGE text) { FPDFText_ClosePage(text); }
-};
-
 struct FPDFPageDeleter {
   inline void operator()(FPDF_PAGE page) { FPDF_ClosePage(page); }
 };
@@ -51,12 +51,18 @@
   }
 };
 
+struct FPDFPageObjectDeleter {
+  inline void operator()(FPDF_PAGEOBJECT object) {
+    FPDFPageObj_Destroy(object);
+  }
+};
+
 struct FPDFStructTreeDeleter {
   inline void operator()(FPDF_STRUCTTREE tree) { FPDF_StructTree_Close(tree); }
 };
 
-struct FPDFFontDeleter {
-  inline void operator()(FPDF_FONT font) { FPDFFont_Close(font); }
+struct FPDFTextPageDeleter {
+  inline void operator()(FPDF_TEXTPAGE text) { FPDFText_ClosePage(text); }
 };
 
 #endif  // PUBLIC_CPP_FPDF_DELETERS_H_
diff --git a/public/cpp/fpdf_scopers.h b/public/cpp/fpdf_scopers.h
index 3601f47..3fe63e3 100644
--- a/public/cpp/fpdf_scopers.h
+++ b/public/cpp/fpdf_scopers.h
@@ -33,14 +33,13 @@
     std::unique_ptr<std::remove_pointer<FPDF_DOCUMENT>::type,
                     FPDFDocumentDeleter>;
 
+using ScopedFPDFFont =
+    std::unique_ptr<std::remove_pointer<FPDF_FONT>::type, FPDFFontDeleter>;
+
 using ScopedFPDFFormHandle =
     std::unique_ptr<std::remove_pointer<FPDF_FORMHANDLE>::type,
                     FPDFFormHandleDeleter>;
 
-using ScopedFPDFTextPage =
-    std::unique_ptr<std::remove_pointer<FPDF_TEXTPAGE>::type,
-                    FPDFTextPageDeleter>;
-
 using ScopedFPDFPage =
     std::unique_ptr<std::remove_pointer<FPDF_PAGE>::type, FPDFPageDeleter>;
 
@@ -48,11 +47,16 @@
     std::unique_ptr<std::remove_pointer<FPDF_PAGELINK>::type,
                     FPDFPageLinkDeleter>;
 
+using ScopedFPDFPageObject =
+    std::unique_ptr<std::remove_pointer<FPDF_PAGEOBJECT>::type,
+                    FPDFPageObjectDeleter>;
+
 using ScopedFPDFStructTree =
     std::unique_ptr<std::remove_pointer<FPDF_STRUCTTREE>::type,
                     FPDFStructTreeDeleter>;
 
-using ScopedFPDFFont =
-    std::unique_ptr<std::remove_pointer<FPDF_FONT>::type, FPDFFontDeleter>;
+using ScopedFPDFTextPage =
+    std::unique_ptr<std::remove_pointer<FPDF_TEXTPAGE>::type,
+                    FPDFTextPageDeleter>;
 
 #endif  // PUBLIC_CPP_FPDF_SCOPERS_H_