Fix unusable FPDFBitmap_GetBuffer() return values

FPDFBitmap_GetBuffer() can return a bitmap with a color palette, yet
there is no public API to access to palette. Avoid this situation by
converting the bitmap to one without a palette.

Bug: pdfium:1190
Change-Id: Ic3a3d49647e358c5be96106d4b3acc55578948de
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/111752
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/fpdfsdk/fpdf_edit_embeddertest.cpp b/fpdfsdk/fpdf_edit_embeddertest.cpp
index d29a2d3..f22aa86 100644
--- a/fpdfsdk/fpdf_edit_embeddertest.cpp
+++ b/fpdfsdk/fpdf_edit_embeddertest.cpp
@@ -4004,8 +4004,8 @@
     obj = FPDFPage_GetObject(page, 35);
     ASSERT_EQ(FPDF_PAGEOBJ_IMAGE, FPDFPageObj_GetType(obj));
     ScopedFPDFBitmap bitmap(FPDFImageObj_GetBitmap(obj));
-    EXPECT_EQ(FPDFBitmap_Gray, FPDFBitmap_GetFormat(bitmap.get()));
-    CompareBitmap(bitmap.get(), 92, 68, "9c6d76cb1e37ef8514f9455d759391f3");
+    EXPECT_EQ(FPDFBitmap_BGR, FPDFBitmap_GetFormat(bitmap.get()));
+    CompareBitmap(bitmap.get(), 92, 68, "7e34551035943e30a9f353db17de62ab");
   }
 
   {
@@ -4096,8 +4096,8 @@
   {
     ScopedFPDFBitmap bitmap(FPDFImageObj_GetBitmap(obj));
     ASSERT_TRUE(bitmap);
-    EXPECT_EQ(FPDFBitmap_Gray, FPDFBitmap_GetFormat(bitmap.get()));
-    CompareBitmap(bitmap.get(), 1152, 720, "3f6a48e2b3e91b799bf34567f55cb4de");
+    EXPECT_EQ(FPDFBitmap_BGR, FPDFBitmap_GetFormat(bitmap.get()));
+    CompareBitmap(bitmap.get(), 1152, 720, "0b67a5d69f3f1052abddd5cdd882a126");
   }
 
   UnloadPage(page);
diff --git a/fpdfsdk/fpdf_editimg.cpp b/fpdfsdk/fpdf_editimg.cpp
index 8e3402f..f26c1eb 100644
--- a/fpdfsdk/fpdf_editimg.cpp
+++ b/fpdfsdk/fpdf_editimg.cpp
@@ -27,6 +27,7 @@
 #include "core/fxge/dib/cfx_dibitmap.h"
 #include "fpdfsdk/cpdfsdk_customaccess.h"
 #include "fpdfsdk/cpdfsdk_helpers.h"
+#include "third_party/base/notreached.h"
 
 namespace {
 
@@ -198,13 +199,35 @@
   if (!pSource)
     return nullptr;
 
-  // If the source image has a representation of 1 bit per pixel, then convert
-  // it to a grayscale bitmap having 1 byte per pixel, since bitmaps have no
-  // concept of bits. Otherwise, convert the source image to a bitmap directly,
+  // If the source image has a representation of 1 bit per pixel, or if the
+  // source image has a color palette, convert it to a color representation if
+  // needed to get rid of the palette, as there is no public API to access to
+  // palette.
+  //
+  // Otherwise, convert the source image to a bitmap directly,
   // retaining its color representation.
-  RetainPtr<CFX_DIBitmap> pBitmap =
-      pSource->GetBPP() == 1 ? pSource->ConvertTo(FXDIB_Format::k8bppRgb)
-                             : pSource->Realize();
+  //
+  // Only return FPDF_BITMAPs in formats that FPDFBitmap_CreateEx() would
+  // return.
+  RetainPtr<CFX_DIBitmap> pBitmap;
+  switch (pSource->GetFormat()) {
+    case FXDIB_Format::k1bppMask:
+    case FXDIB_Format::k1bppRgb:
+    case FXDIB_Format::k8bppMask:
+    case FXDIB_Format::k8bppRgb:
+      pBitmap = pSource->ConvertTo(FXDIB_Format::kRgb);
+      break;
+
+    case FXDIB_Format::kArgb:
+    case FXDIB_Format::kRgb:
+    case FXDIB_Format::kRgb32:
+      pBitmap = pSource->Realize();
+      break;
+
+    case FXDIB_Format::kInvalid: {
+      NOTREACHED_NORETURN();
+    }
+  }
 
   return FPDFBitmapFromCFXDIBitmap(pBitmap.Leak());
 }