Add a return type to FPDFBitmap_FillRect()

Let callers know whether the bitmap rect was actually filled or not.
Change all the callers to check the return result.

Note that this adds a return type to a stable API.

Change-Id: I452848bf039e50a7d536b594edd2c3f8a46a88a7
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/123054
Reviewed-by: Tom Sepez <tsepez@google.com>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/render/fpdf_progressive_render_embeddertest.cpp b/core/fpdfapi/render/fpdf_progressive_render_embeddertest.cpp
index 013fe6f..9db75fd 100644
--- a/core/fpdfapi/render/fpdf_progressive_render_embeddertest.cpp
+++ b/core/fpdfapi/render/fpdf_progressive_render_embeddertest.cpp
@@ -153,8 +153,10 @@
   progressive_render_bitmap_ =
       ScopedFPDFBitmap(FPDFBitmap_Create(width, height, alpha));
   FPDF_DWORD fill_color = alpha ? 0x00000000 : 0xFFFFFFFF;
-  FPDFBitmap_FillRect(progressive_render_bitmap_.get(), 0, 0, width, height,
-                      fill_color);
+  if (!FPDFBitmap_FillRect(progressive_render_bitmap_.get(), 0, 0, width,
+                           height, fill_color)) {
+    return false;
+  }
   int rv = FPDF_RenderPageBitmap_Start(progressive_render_bitmap_.get(), page,
                                        0, 0, width, height, 0,
                                        progressive_render_flags_, pause);
@@ -175,8 +177,10 @@
   progressive_render_bitmap_ =
       ScopedFPDFBitmap(FPDFBitmap_Create(width, height, alpha));
   DCHECK(progressive_render_bitmap_);
-  FPDFBitmap_FillRect(progressive_render_bitmap_.get(), 0, 0, width, height,
-                      background_color);
+  if (!FPDFBitmap_FillRect(progressive_render_bitmap_.get(), 0, 0, width,
+                           height, background_color)) {
+    return false;
+  }
   int rv = FPDF_RenderPageBitmapWithColorScheme_Start(
       progressive_render_bitmap_.get(), page, 0, 0, width, height, 0,
       progressive_render_flags_, color_scheme, pause);
diff --git a/core/fxge/skia/fx_skia_device_embeddertest.cpp b/core/fxge/skia/fx_skia_device_embeddertest.cpp
index 3682d11..1b98bf9 100644
--- a/core/fxge/skia/fx_skia_device_embeddertest.cpp
+++ b/core/fxge/skia/fx_skia_device_embeddertest.cpp
@@ -154,7 +154,8 @@
   constexpr int kHeight = 1;
   ScopedFPDFBitmap bitmap(FPDFBitmap_Create(kWidth, kHeight, 1));
   ASSERT_TRUE(bitmap);
-  FPDFBitmap_FillRect(bitmap.get(), 0, 0, kWidth, kHeight, 0x00000000);
+  ASSERT_TRUE(
+      FPDFBitmap_FillRect(bitmap.get(), 0, 0, kWidth, kHeight, 0x00000000));
   RetainPtr<CFX_DIBitmap> pBitmap(CFXDIBitmapFromFPDFBitmap(bitmap.get()));
   auto driver = CFX_SkiaDeviceDriver::Create(pBitmap, false, nullptr, false);
   ASSERT_TRUE(driver);
diff --git a/fpdfsdk/fpdf_annot_embeddertest.cpp b/fpdfsdk/fpdf_annot_embeddertest.cpp
index dc4dd1d..8e7d0db 100644
--- a/fpdfsdk/fpdf_annot_embeddertest.cpp
+++ b/fpdfsdk/fpdf_annot_embeddertest.cpp
@@ -1445,8 +1445,8 @@
 
     // Add a solid-color translucent image object to the new annotation.
     image_bitmap = FPDFBitmap_Create(kBitmapSize, kBitmapSize, 1);
-    FPDFBitmap_FillRect(image_bitmap, 0, 0, kBitmapSize, kBitmapSize,
-                        0xeeeecccc);
+    ASSERT_TRUE(FPDFBitmap_FillRect(image_bitmap, 0, 0, kBitmapSize,
+                                    kBitmapSize, 0xeeeecccc));
     EXPECT_EQ(kBitmapSize, FPDFBitmap_GetWidth(image_bitmap));
     EXPECT_EQ(kBitmapSize, FPDFBitmap_GetHeight(image_bitmap));
     FPDF_PAGEOBJECT image_object = FPDFPageObj_NewImageObj(document());
@@ -1473,8 +1473,8 @@
     EXPECT_EQ(FPDF_PAGEOBJ_IMAGE, FPDFPageObj_GetType(image_object));
 
     // Modify the image in the new annotation.
-    FPDFBitmap_FillRect(image_bitmap, 0, 0, kBitmapSize, kBitmapSize,
-                        0xff000000);
+    ASSERT_TRUE(FPDFBitmap_FillRect(image_bitmap, 0, 0, kBitmapSize,
+                                    kBitmapSize, 0xff000000));
     ASSERT_TRUE(FPDFImageObj_SetBitmap(&page, 0, image_object, image_bitmap));
     EXPECT_TRUE(FPDFAnnot_UpdateObject(annot.get(), image_object));
   }
diff --git a/fpdfsdk/fpdf_edit_embeddertest.cpp b/fpdfsdk/fpdf_edit_embeddertest.cpp
index 3bdd76d..0b1d327 100644
--- a/fpdfsdk/fpdf_edit_embeddertest.cpp
+++ b/fpdfsdk/fpdf_edit_embeddertest.cpp
@@ -5250,8 +5250,8 @@
   constexpr int kBitmapWidth = 50;
   constexpr int kBitmapHeight = 100;
   ScopedFPDFBitmap bitmap(FPDFBitmap_Create(kBitmapWidth, kBitmapHeight, 0));
-  FPDFBitmap_FillRect(bitmap.get(), 0, 0, kBitmapWidth, kBitmapHeight,
-                      0x00000000);
+  ASSERT_TRUE(FPDFBitmap_FillRect(bitmap.get(), 0, 0, kBitmapWidth,
+                                  kBitmapHeight, 0x00000000));
   ScopedFPDFPageObject page_image(FPDFPageObj_NewImageObj(doc.get()));
   ASSERT_TRUE(
       FPDFImageObj_SetBitmap(nullptr, 0, page_image.get(), bitmap.get()));
diff --git a/fpdfsdk/fpdf_editimg_embeddertest.cpp b/fpdfsdk/fpdf_editimg_embeddertest.cpp
index c7716ee..2c3efdb 100644
--- a/fpdfsdk/fpdf_editimg_embeddertest.cpp
+++ b/fpdfsdk/fpdf_editimg_embeddertest.cpp
@@ -42,7 +42,8 @@
 
   constexpr int kBitmapSize = 50;
   ScopedFPDFBitmap bitmap(FPDFBitmap_Create(kBitmapSize, kBitmapSize, 0));
-  FPDFBitmap_FillRect(bitmap.get(), 0, 0, kBitmapSize, kBitmapSize, 0x00000000);
+  ASSERT_TRUE(FPDFBitmap_FillRect(bitmap.get(), 0, 0, kBitmapSize, kBitmapSize,
+                                  0x00000000));
   EXPECT_EQ(kBitmapSize, FPDFBitmap_GetWidth(bitmap.get()));
   EXPECT_EQ(kBitmapSize, FPDFBitmap_GetHeight(bitmap.get()));
 
diff --git a/fpdfsdk/fpdf_view.cpp b/fpdfsdk/fpdf_view.cpp
index 1d24fa0..458b604 100644
--- a/fpdfsdk/fpdf_view.cpp
+++ b/fpdfsdk/fpdf_view.cpp
@@ -955,28 +955,28 @@
   }
 }
 
-FPDF_EXPORT void FPDF_CALLCONV FPDFBitmap_FillRect(FPDF_BITMAP bitmap,
-                                                   int left,
-                                                   int top,
-                                                   int width,
-                                                   int height,
-                                                   FPDF_DWORD color) {
+FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFBitmap_FillRect(FPDF_BITMAP bitmap,
+                                                        int left,
+                                                        int top,
+                                                        int width,
+                                                        int height,
+                                                        FPDF_DWORD color) {
   RetainPtr<CFX_DIBitmap> pBitmap(CFXDIBitmapFromFPDFBitmap(bitmap));
   if (!pBitmap) {
-    return;
+    return false;
   }
   CHECK(!pBitmap->IsPremultiplied());
 
   FX_SAFE_INT32 right = left;
   right += width;
   if (!right.IsValid()) {
-    return;
+    return false;
   }
 
   FX_SAFE_INT32 bottom = top;
   bottom += height;
   if (!bottom.IsValid()) {
-    return;
+    return false;
   }
 
   FX_RECT fill_rect(left, top, right.ValueOrDie(), bottom.ValueOrDie());
@@ -990,8 +990,7 @@
   if (bpp == 8) {
     CFX_DefaultRenderDevice device;
     device.Attach(std::move(pBitmap));
-    device.FillRect(fill_rect, static_cast<uint32_t>(color));
-    return;
+    return device.FillRect(fill_rect, static_cast<uint32_t>(color));
   }
 
   // Handle filling 24/32-bit bitmaps directly without CFX_DefaultRenderDevice.
@@ -1000,7 +999,8 @@
   // `pBitmap` to 32 BPP and back.
   fill_rect.Intersect(FX_RECT(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight()));
   if (fill_rect.IsEmpty()) {
-    return;
+    // CFX_DefaultRenderDevice treats this as success. Match that.
+    return true;
   }
 
   const int row_end = fill_rect.top + fill_rect.Height();
@@ -1010,7 +1010,7 @@
           fill_rect.left, fill_rect.Width());
       fxcrt::Fill(span32, static_cast<uint32_t>(color));
     }
-    return;
+    return true;
   }
 
   CHECK_EQ(bpp, 24);
@@ -1023,6 +1023,7 @@
             fill_rect.left, fill_rect.Width());
     fxcrt::Fill(bgr_span, bgr);
   }
+  return true;
 }
 
 FPDF_EXPORT void* FPDF_CALLCONV FPDFBitmap_GetBuffer(FPDF_BITMAP bitmap) {
diff --git a/fpdfsdk/fpdf_view_embeddertest.cpp b/fpdfsdk/fpdf_view_embeddertest.cpp
index 004cce0..789b641 100644
--- a/fpdfsdk/fpdf_view_embeddertest.cpp
+++ b/fpdfsdk/fpdf_view_embeddertest.cpp
@@ -166,8 +166,8 @@
                                       const FS_RECTF& rect,
                                       const char* expected_checksum) {
     ScopedFPDFBitmap bitmap(FPDFBitmap_Create(bitmap_width, bitmap_height, 0));
-    FPDFBitmap_FillRect(bitmap.get(), 0, 0, bitmap_width, bitmap_height,
-                        0xFFFFFFFF);
+    ASSERT_TRUE(FPDFBitmap_FillRect(bitmap.get(), 0, 0, bitmap_width,
+                                    bitmap_height, 0xFFFFFFFF));
     FPDF_RenderPageBitmapWithMatrix(bitmap.get(), page, &matrix, &rect, 0);
     CompareBitmap(bitmap.get(), bitmap_width, bitmap_height, expected_checksum);
   }
@@ -178,8 +178,8 @@
     int bitmap_width = static_cast<int>(FPDF_GetPageWidth(page));
     int bitmap_height = static_cast<int>(FPDF_GetPageHeight(page));
     ScopedFPDFBitmap bitmap(FPDFBitmap_Create(bitmap_width, bitmap_height, 0));
-    FPDFBitmap_FillRect(bitmap.get(), 0, 0, bitmap_width, bitmap_height,
-                        0xFFFFFFFF);
+    ASSERT_TRUE(FPDFBitmap_FillRect(bitmap.get(), 0, 0, bitmap_width,
+                                    bitmap_height, 0xFFFFFFFF));
     FPDF_RenderPageBitmap(bitmap.get(), page, 0, 0, bitmap_width, bitmap_height,
                           0, flags);
     CompareBitmap(bitmap.get(), bitmap_width, bitmap_height, expected_checksum);
@@ -273,7 +273,8 @@
     int bitmap_height = FPDFBitmap_GetHeight(bitmap);
     EXPECT_EQ(bitmap_width, static_cast<int>(FPDF_GetPageWidth(page)));
     EXPECT_EQ(bitmap_height, static_cast<int>(FPDF_GetPageHeight(page)));
-    FPDFBitmap_FillRect(bitmap, 0, 0, bitmap_width, bitmap_height, 0xFFFFFFFF);
+    ASSERT_TRUE(FPDFBitmap_FillRect(bitmap, 0, 0, bitmap_width, bitmap_height,
+                                    0xFFFFFFFF));
     FPDF_RenderPageBitmap(bitmap, page, 0, 0, bitmap_width, bitmap_height, 0,
                           FPDF_ANNOT);
     CompareBitmap(bitmap, bitmap_width, bitmap_height, expected_checksum);
@@ -2157,7 +2158,8 @@
   EXPECT_EQ(kHeight, static_cast<int>(FPDF_GetPageHeightF(page.get())));
   EXPECT_TRUE(FPDFPage_HasTransparency(page.get()));
   ScopedFPDFBitmap bitmap(FPDFBitmap_Create(kWidth, kHeight, /*alpha=*/true));
-  FPDFBitmap_FillRect(bitmap.get(), 0, 0, kWidth, kHeight, 0xFFFFFFFF);
+  ASSERT_TRUE(
+      FPDFBitmap_FillRect(bitmap.get(), 0, 0, kWidth, kHeight, 0xFFFFFFFF));
   FPDF_RenderPageBitmap(bitmap.get(), page.get(), /*start_x=*/0,
                         /*start_y=*/0, kWidth, kHeight, /*rotate=*/0,
                         /*flags=*/0);
@@ -2202,26 +2204,30 @@
   constexpr int kHeight = 200;
   constexpr char kExpectedChecksum[] = "acc736435c9f84aa82941ba561bc5dbc";
   ScopedFPDFBitmap bitmap(FPDFBitmap_Create(200, 200, /*alpha=*/true));
-  FPDFBitmap_FillRect(bitmap.get(), /*left=*/0, /*top=*/0, /*width=*/kWidth,
-                      /*height=*/kHeight, 0xFFFF0000);
+  ASSERT_TRUE(FPDFBitmap_FillRect(bitmap.get(), /*left=*/0, /*top=*/0,
+                                  /*width=*/kWidth,
+                                  /*height=*/kHeight, 0xFFFF0000));
   EXPECT_EQ(kExpectedChecksum, HashBitmap(bitmap.get()));
 
   // Empty rect dimensions is a no-op.
-  FPDFBitmap_FillRect(bitmap.get(), /*left=*/0, /*top=*/0, /*width=*/0,
-                      /*height=*/0, 0xFF0000FF);
+  ASSERT_TRUE(FPDFBitmap_FillRect(bitmap.get(), /*left=*/0, /*top=*/0,
+                                  /*width=*/0,
+                                  /*height=*/0, 0xFF0000FF));
   EXPECT_EQ(kExpectedChecksum, HashBitmap(bitmap.get()));
 
   // Rect dimension overflows are also no-ops.
-  FPDFBitmap_FillRect(bitmap.get(), /*left=*/std::numeric_limits<int>::max(),
-                      /*top=*/0, /*width=*/std::numeric_limits<int>::max(),
-                      /*height=*/kHeight, 0xFF0000FF);
+  ASSERT_FALSE(FPDFBitmap_FillRect(
+      bitmap.get(), /*left=*/std::numeric_limits<int>::max(),
+      /*top=*/0, /*width=*/std::numeric_limits<int>::max(),
+      /*height=*/kHeight, 0xFF0000FF));
   EXPECT_EQ(kExpectedChecksum, HashBitmap(bitmap.get()));
 
-  FPDFBitmap_FillRect(bitmap.get(), /*left=*/0,
-                      /*top=*/std::numeric_limits<int>::max(), /*width=*/kWidth,
-                      /*height=*/std::numeric_limits<int>::max(), 0xFF0000FF);
+  ASSERT_FALSE(FPDFBitmap_FillRect(
+      bitmap.get(), /*left=*/0,
+      /*top=*/std::numeric_limits<int>::max(), /*width=*/kWidth,
+      /*height=*/std::numeric_limits<int>::max(), 0xFF0000FF));
   EXPECT_EQ(kExpectedChecksum, HashBitmap(bitmap.get()));
 
   // Make sure null bitmap handle does not trigger a crash.
-  FPDFBitmap_FillRect(nullptr, 0, 0, kWidth, kHeight, 0xFF0000FF);
+  ASSERT_FALSE(FPDFBitmap_FillRect(nullptr, 0, 0, kWidth, kHeight, 0xFF0000FF));
 }
diff --git a/public/fpdfview.h b/public/fpdfview.h
index b374088..c7b644bc 100644
--- a/public/fpdfview.h
+++ b/public/fpdfview.h
@@ -1154,7 +1154,7 @@
 //          color       -   A 32-bit value specifing the color, in 8888 ARGB
 //                          format.
 // Return value:
-//          None.
+//          Returns whether the operation succeeded or not.
 // Comments:
 //          This function sets the color and (optionally) alpha value in the
 //          specified region of the bitmap.
@@ -1164,12 +1164,12 @@
 //          background will be replaced by the source color and the alpha.
 //
 //          If the alpha channel is not used, the alpha parameter is ignored.
-FPDF_EXPORT void FPDF_CALLCONV FPDFBitmap_FillRect(FPDF_BITMAP bitmap,
-                                                   int left,
-                                                   int top,
-                                                   int width,
-                                                   int height,
-                                                   FPDF_DWORD color);
+FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFBitmap_FillRect(FPDF_BITMAP bitmap,
+                                                        int left,
+                                                        int top,
+                                                        int width,
+                                                        int height,
+                                                        FPDF_DWORD color);
 
 // Function: FPDFBitmap_GetBuffer
 //          Get data buffer of a bitmap.
diff --git a/testing/embedder_test.cpp b/testing/embedder_test.cpp
index 6ed273b..3289c71 100644
--- a/testing/embedder_test.cpp
+++ b/testing/embedder_test.cpp
@@ -596,7 +596,9 @@
   int alpha = FPDFPage_HasTransparency(page) ? 1 : 0;
   ScopedFPDFBitmap bitmap(FPDFBitmap_Create(width, height, alpha));
   FPDF_DWORD fill_color = alpha ? 0x00000000 : 0xFFFFFFFF;
-  FPDFBitmap_FillRect(bitmap.get(), 0, 0, width, height, fill_color);
+  if (!FPDFBitmap_FillRect(bitmap.get(), 0, 0, width, height, fill_color)) {
+    return nullptr;
+  }
   FPDF_RenderPageBitmap(bitmap.get(), page, 0, 0, width, height, 0, flags);
   FPDF_FFLDraw(handle, bitmap.get(), page, 0, 0, width, height, 0, flags);
   return bitmap;
diff --git a/testing/fuzzers/pdfium_fuzzer_helper.cc b/testing/fuzzers/pdfium_fuzzer_helper.cc
index 90da782..8771262 100644
--- a/testing/fuzzers/pdfium_fuzzer_helper.cc
+++ b/testing/fuzzers/pdfium_fuzzer_helper.cc
@@ -224,7 +224,9 @@
   int height = static_cast<int>(FPDF_GetPageHeightF(page.get()) * scale);
   ScopedFPDFBitmap bitmap(FPDFBitmap_Create(width, height, 0));
   if (bitmap) {
-    FPDFBitmap_FillRect(bitmap.get(), 0, 0, width, height, 0xFFFFFFFF);
+    if (!FPDFBitmap_FillRect(bitmap.get(), 0, 0, width, height, 0xFFFFFFFF)) {
+      return false;
+    }
     FPDF_RenderPageBitmap(bitmap.get(), page.get(), 0, 0, width, height, 0,
                           render_flags);
     FPDF_FFLDraw(form, bitmap.get(), page.get(), 0, 0, width, height, 0,
diff --git a/testing/pdfium_test.cc b/testing/pdfium_test.cc
index 5246d05..85b4ca5 100644
--- a/testing/pdfium_test.cc
+++ b/testing/pdfium_test.cc
@@ -1000,9 +1000,9 @@
     }
 
     FPDF_DWORD fill_color = alpha ? 0x00000000 : 0xFFFFFFFF;
-    FPDFBitmap_FillRect(bitmap(), /*left=*/0, /*top=*/0, /*width=*/width(),
-                        /*height=*/height(), /*color=*/fill_color);
-    return true;
+    return FPDFBitmap_FillRect(bitmap(), /*left=*/0, /*top=*/0,
+                               /*width=*/width(),
+                               /*height=*/height(), /*color=*/fill_color);
   }
 
   void ResetBitmap() { bitmap_.reset(); }