Add UNSAFE_BUFFER annotations to fx_dib.h
But stop well short of actually enforcing these during any builds.
Convert some macros to inline functions to allow propagating the
unsafe requirement to callers.
-- Fix const issue in skia test hidden by c-style cast in macro.
Change-Id: Ic9c4338eba4807cf0c25e2d993b9684617d6eedc
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/116551
Reviewed-by: Thomas Sepez <tsepez@google.com>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/render/cpdf_rendershading.cpp b/core/fpdfapi/render/cpdf_rendershading.cpp
index 5575205..8f4d6cb 100644
--- a/core/fpdfapi/render/cpdf_rendershading.cpp
+++ b/core/fpdfapi/render/cpdf_rendershading.cpp
@@ -409,7 +409,7 @@
r_result += r_unit;
g_result += g_unit;
b_result += b_unit;
- FXARGB_SETDIB(dib_buf, ArgbEncode(alpha, static_cast<int>(r_result * 255),
+ FXARGB_SetDIB(dib_buf, ArgbEncode(alpha, static_cast<int>(r_result * 255),
static_cast<int>(g_result * 255),
static_cast<int>(b_result * 255)));
dib_span = dib_span.subspan(4);
diff --git a/core/fxcodec/progressive_decoder.cpp b/core/fxcodec/progressive_decoder.cpp
index 669949e..5e3c695 100644
--- a/core/fxcodec/progressive_decoder.cpp
+++ b/core/fxcodec/progressive_decoder.cpp
@@ -430,7 +430,7 @@
}
case 12: {
for (int col = 0; col < sizeX; col++) {
- FXARGB_SETDIB(pScanline, argb);
+ FXARGB_SetDIB(pScanline, argb);
pScanline += 4;
}
break;
diff --git a/core/fxge/agg/fx_agg_driver.cpp b/core/fxge/agg/fx_agg_driver.cpp
index 0be44eb..a380a78 100644
--- a/core/fxge/agg/fx_agg_driver.cpp
+++ b/core/fxge/agg/fx_agg_driver.cpp
@@ -99,7 +99,7 @@
for (int col = 0; col < width; col++) {
uint8_t back_alpha = dest_scan[3];
if (back_alpha == 0) {
- FXARGB_SETRGBORDERDIB(dest_scan, argb);
+ FXARGB_SetRGBOrderDIB(dest_scan, argb);
dest_scan += 4;
continue;
}
@@ -162,7 +162,7 @@
pSrcBitmap->GetScanline(src_top + row).subspan(src_x_offset).data();
if (Bpp == 4) {
for (int col = 0; col < width; col++) {
- FXARGB_SETRGBORDERDIB(dest_scan,
+ FXARGB_SetRGBOrderDIB(dest_scan,
*reinterpret_cast<const uint32_t*>(src_scan));
dest_scan += 4;
src_scan += 4;
@@ -212,7 +212,7 @@
const uint8_t* src_scan =
pSrcBitmap->GetScanline(src_top + row).subspan(src_x_offset).data();
for (int col = 0; col < width; col++) {
- FXARGB_SETDIB(dest_scan,
+ FXARGB_SetDIB(dest_scan,
ArgbEncode(0xff, src_scan[0], src_scan[1], src_scan[2]));
dest_scan += 4;
src_scan += 3;
@@ -230,7 +230,7 @@
const uint8_t* src_scan =
pSrcBitmap->GetScanline(src_top + row).subspan(src_x_offset).data();
for (int col = 0; col < width; col++) {
- FXARGB_SETDIB(dest_scan,
+ FXARGB_SetDIB(dest_scan,
ArgbEncode(0xff, src_scan[0], src_scan[1], src_scan[2]));
src_scan += 4;
dest_scan += 4;
diff --git a/core/fxge/cfx_renderdevice.cpp b/core/fxge/cfx_renderdevice.cpp
index 4dc06a8..8e96719 100644
--- a/core/fxge/cfx_renderdevice.cpp
+++ b/core/fxge/cfx_renderdevice.cpp
@@ -160,7 +160,7 @@
int src_alpha) {
uint8_t back_alpha = dest[3];
if (back_alpha == 0)
- FXARGB_SETDIB(dest, ArgbEncode(src_alpha, r, g, b));
+ FXARGB_SetDIB(dest, ArgbEncode(src_alpha, r, g, b));
else if (src_alpha != 0)
ApplyDestAlpha(back_alpha, src_alpha, r, g, b, dest);
}
diff --git a/core/fxge/dib/cfx_dibitmap.cpp b/core/fxge/dib/cfx_dibitmap.cpp
index ec91d70..aa1996a 100644
--- a/core/fxge/dib/cfx_dibitmap.cpp
+++ b/core/fxge/dib/cfx_dibitmap.cpp
@@ -430,9 +430,9 @@
: ArgbEncode(0xff, *pos, *pos, *pos);
case FXDIB_Format::kRgb:
case FXDIB_Format::kRgb32:
- return FXARGB_GETDIB(pos) | 0xff000000;
+ return FXARGB_GetDIB(pos) | 0xff000000;
case FXDIB_Format::kArgb:
- return FXARGB_GETDIB(pos);
+ return FXARGB_GetDIB(pos);
default:
break;
}
@@ -794,7 +794,7 @@
for (int col = 0; col < width; col++) {
uint8_t back_alpha = dest_scan[3];
if (back_alpha == 0) {
- FXARGB_SETDIB(dest_scan, ArgbEncode(src_alpha, color_p[2], color_p[1],
+ FXARGB_SetDIB(dest_scan, ArgbEncode(src_alpha, color_p[2], color_p[1],
color_p[0]));
dest_scan += 4;
continue;
diff --git a/core/fxge/dib/cfx_dibitmap_unittest.cpp b/core/fxge/dib/cfx_dibitmap_unittest.cpp
index 5473ce0..2c7de3e 100644
--- a/core/fxge/dib/cfx_dibitmap_unittest.cpp
+++ b/core/fxge/dib/cfx_dibitmap_unittest.cpp
@@ -121,7 +121,7 @@
TEST(CFX_DIBitmap, UnPreMultiply_FromCleared) {
auto bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
ASSERT_TRUE(bitmap->Create(1, 1, FXDIB_Format::kArgb));
- FXARGB_SETDIB(bitmap->GetBuffer().data(), 0x7f'7f'7f'7f);
+ FXARGB_SetDIB(bitmap->GetWritableBuffer().data(), 0x7f'7f'7f'7f);
bitmap->UnPreMultiply();
@@ -132,7 +132,7 @@
auto bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
ASSERT_TRUE(bitmap->Create(1, 1, FXDIB_Format::kArgb));
bitmap->ForcePreMultiply();
- FXARGB_SETDIB(bitmap->GetBuffer().data(), 0x7f'7f'7f'7f);
+ FXARGB_SetDIB(bitmap->GetWritableBuffer().data(), 0x7f'7f'7f'7f);
bitmap->UnPreMultiply();
@@ -143,7 +143,7 @@
auto bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
ASSERT_TRUE(bitmap->Create(1, 1, FXDIB_Format::kArgb));
bitmap->UnPreMultiply();
- FXARGB_SETDIB(bitmap->GetBuffer().data(), 0x7f'ff'ff'ff);
+ FXARGB_SetDIB(bitmap->GetWritableBuffer().data(), 0x7f'ff'ff'ff);
bitmap->UnPreMultiply();
diff --git a/core/fxge/dib/cfx_scanlinecompositor.cpp b/core/fxge/dib/cfx_scanlinecompositor.cpp
index b15cedc..4cb5b91 100644
--- a/core/fxge/dib/cfx_scanlinecompositor.cpp
+++ b/core/fxge/dib/cfx_scanlinecompositor.cpp
@@ -246,8 +246,8 @@
uint8_t src_alpha = GetAlpha(src_scan[3], clip_scan, col);
if (back_alpha == 0) {
if (clip_scan) {
- FXARGB_SETDIB(dest_scan,
- (FXARGB_GETDIB(src_scan) & 0xffffff) | (src_alpha << 24));
+ FXARGB_SetDIB(dest_scan,
+ (FXARGB_GetDIB(src_scan) & 0xffffff) | (src_alpha << 24));
} else {
memcpy(dest_scan, src_scan, 4);
}
@@ -298,9 +298,9 @@
uint8_t back_alpha = *dest_alpha;
if (back_alpha == 0) {
if (src_Bpp == 4) {
- FXARGB_SETDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
+ FXARGB_SetDIB(dest_scan, 0xff000000 | FXARGB_GetDIB(src_scan));
} else {
- FXARGB_SETDIB(dest_scan,
+ FXARGB_SetDIB(dest_scan,
ArgbEncode(0xff, src_scan[2], src_scan[1], src_scan[0]));
}
dest_scan += 4;
@@ -416,9 +416,9 @@
const uint8_t* src_scan = src_span.data();
for (int col = 0; col < width; col++) {
if (src_Bpp == 4) {
- FXARGB_SETDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
+ FXARGB_SetDIB(dest_scan, 0xff000000 | FXARGB_GetDIB(src_scan));
} else {
- FXARGB_SETDIB(dest_scan,
+ FXARGB_SetDIB(dest_scan,
ArgbEncode(0xff, src_scan[2], src_scan[1], src_scan[0]));
}
dest_scan += 4;
@@ -902,7 +902,7 @@
int src_alpha = GetAlphaWithSrc(mask_alpha, clip_scan, src_scan, col);
uint8_t back_alpha = dest_scan[3];
if (back_alpha == 0) {
- FXARGB_SETDIB(dest_scan, ArgbEncode(src_alpha, src_r, src_g, src_b));
+ FXARGB_SetDIB(dest_scan, ArgbEncode(src_alpha, src_r, src_g, src_b));
dest_scan += 4;
continue;
}
@@ -1055,7 +1055,7 @@
FX_ARGB argb = ArgbEncode(0xff, src_r, src_g, src_b);
for (int col = 0; col < pixel_count; col++) {
if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
- FXARGB_SETDIB(dest_scan, argb);
+ FXARGB_SetDIB(dest_scan, argb);
}
dest_scan += 4;
}
@@ -1069,7 +1069,7 @@
int src_alpha = GetAlpha(mask_alpha, clip_scan, col);
uint8_t back_alpha = dest_scan[3];
if (back_alpha == 0) {
- FXARGB_SETDIB(dest_scan, ArgbEncode(src_alpha, src_r, src_g, src_b));
+ FXARGB_SetDIB(dest_scan, ArgbEncode(src_alpha, src_r, src_g, src_b));
dest_scan += 4;
continue;
}
@@ -1301,9 +1301,9 @@
uint8_t back_alpha = dest_scan[3];
if (back_alpha == 0) {
if (src_Bpp == 4) {
- FXARGB_SETRGBORDERDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
+ FXARGB_SetRGBOrderDIB(dest_scan, 0xff000000 | FXARGB_GetDIB(src_scan));
} else {
- FXARGB_SETRGBORDERDIB(
+ FXARGB_SetRGBOrderDIB(
dest_scan, ArgbEncode(0xff, src_scan[2], src_scan[1], src_scan[0]));
}
dest_scan += 4;
@@ -1382,9 +1382,9 @@
const uint8_t* src_scan = src_span.data();
for (int col = 0; col < width; col++) {
if (src_Bpp == 4) {
- FXARGB_SETRGBORDERDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
+ FXARGB_SetRGBOrderDIB(dest_scan, 0xff000000 | FXARGB_GetDIB(src_scan));
} else {
- FXARGB_SETRGBORDERDIB(
+ FXARGB_SetRGBOrderDIB(
dest_scan, ArgbEncode(0xff, src_scan[2], src_scan[1], src_scan[0]));
}
dest_scan += 4;
@@ -1851,7 +1851,7 @@
int src_alpha = GetAlphaWithSrc(mask_alpha, clip_scan, src_scan, col);
uint8_t back_alpha = dest_scan[3];
if (back_alpha == 0) {
- FXARGB_SETRGBORDERDIB(dest_scan,
+ FXARGB_SetRGBOrderDIB(dest_scan,
ArgbEncode(src_alpha, src_r, src_g, src_b));
dest_scan += 4;
continue;
@@ -1964,7 +1964,7 @@
FX_ARGB argb = ArgbEncode(0xff, src_r, src_g, src_b);
for (int col = 0; col < pixel_count; col++) {
if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
- FXARGB_SETRGBORDERDIB(dest_scan, argb);
+ FXARGB_SetRGBOrderDIB(dest_scan, argb);
}
dest_scan += 4;
}
@@ -1978,7 +1978,7 @@
int src_alpha = GetAlpha(mask_alpha, clip_scan, col);
uint8_t back_alpha = dest_scan[3];
if (back_alpha == 0) {
- FXARGB_SETRGBORDERDIB(dest_scan,
+ FXARGB_SetRGBOrderDIB(dest_scan,
ArgbEncode(src_alpha, src_r, src_g, src_b));
dest_scan += 4;
continue;
diff --git a/core/fxge/dib/fx_dib.h b/core/fxge/dib/fx_dib.h
index bd458f9..895b453 100644
--- a/core/fxge/dib/fx_dib.h
+++ b/core/fxge/dib/fx_dib.h
@@ -12,6 +12,8 @@
#include <tuple>
#include <utility>
+#include "third_party/base/compiler_specific.h"
+
// Encoding:
// - Bits-per-pixel: value & 0xFF
// - Is mask: value & 0x100
@@ -102,24 +104,22 @@
FXDIB_Format MakeRGBFormat(int bpp);
-constexpr FX_CMYK CmykEncode(uint32_t c, uint32_t m, uint32_t y, uint32_t k) {
- return (c << 24) | (m << 16) | (y << 8) | k;
-}
-
// Returns (a, r, g, b)
std::tuple<int, int, int, int> ArgbDecode(FX_ARGB argb);
// Returns (a, FX_COLORREF)
std::pair<int, FX_COLORREF> ArgbToAlphaAndColorRef(FX_ARGB argb);
-// Returns FX_COLORREF.
FX_COLORREF ArgbToColorRef(FX_ARGB argb);
+FX_ARGB AlphaAndColorRefToArgb(int a, FX_COLORREF colorref);
constexpr FX_ARGB ArgbEncode(uint32_t a, uint32_t r, uint32_t g, uint32_t b) {
return (a << 24) | (r << 16) | (g << 8) | b;
}
-FX_ARGB AlphaAndColorRefToArgb(int a, FX_COLORREF colorref);
+constexpr FX_CMYK CmykEncode(uint32_t c, uint32_t m, uint32_t y, uint32_t k) {
+ return (c << 24) | (m << 16) | (y << 8) | k;
+}
#define FXARGB_A(argb) ((uint8_t)((argb) >> 24))
#define FXARGB_R(argb) ((uint8_t)((argb) >> 16))
@@ -131,19 +131,7 @@
#define FXRGB2GRAY(r, g, b) (((b)*11 + (g)*59 + (r)*30) / 100)
#define FXDIB_ALPHA_MERGE(backdrop, source, source_alpha) \
(((backdrop) * (255 - (source_alpha)) + (source) * (source_alpha)) / 255)
-#define FXARGB_GETDIB(p) \
- ((((uint8_t*)(p))[0]) | (((uint8_t*)(p))[1] << 8) | \
- (((uint8_t*)(p))[2] << 16) | (((uint8_t*)(p))[3] << 24))
-#define FXARGB_SETDIB(p, argb) \
- ((uint8_t*)(p))[0] = (uint8_t)(argb), \
- ((uint8_t*)(p))[1] = (uint8_t)((argb) >> 8), \
- ((uint8_t*)(p))[2] = (uint8_t)((argb) >> 16), \
- ((uint8_t*)(p))[3] = (uint8_t)((argb) >> 24)
-#define FXARGB_SETRGBORDERDIB(p, argb) \
- ((uint8_t*)(p))[3] = (uint8_t)(argb >> 24), \
- ((uint8_t*)(p))[0] = (uint8_t)((argb) >> 16), \
- ((uint8_t*)(p))[1] = (uint8_t)((argb) >> 8), \
- ((uint8_t*)(p))[2] = (uint8_t)(argb)
+
#define FXCMYK_TODIB(cmyk) \
((uint8_t)((cmyk) >> 24) | ((uint8_t)((cmyk) >> 16)) << 8 | \
((uint8_t)((cmyk) >> 8)) << 16 | ((uint8_t)(cmyk) << 24))
@@ -151,10 +139,35 @@
((uint8_t)(argb >> 16) | ((uint8_t)(argb >> 8)) << 8 | \
((uint8_t)(argb)) << 16 | ((uint8_t)(argb >> 24) << 24))
-inline void ReverseCopy3Bytes(uint8_t* dest, const uint8_t* src) {
- dest[2] = src[0];
- dest[1] = src[1];
- dest[0] = src[2];
+// SAFETY: Caller must ensure 4 valid bytes at `p`.
+UNSAFE_BUFFER_USAGE inline FX_ARGB FXARGB_GetDIB(const uint8_t* p) {
+ return ArgbEncode(UNSAFE_BUFFERS(p[3]), UNSAFE_BUFFERS(p[2]),
+ UNSAFE_BUFFERS(p[1]), UNSAFE_BUFFERS(p[0]));
+}
+
+// SAFETY: Caller must ensure 4 valid bytes at `p`.
+UNSAFE_BUFFER_USAGE inline void FXARGB_SetDIB(uint8_t* p, uint32_t argb) {
+ UNSAFE_BUFFERS(p[0]) = FXARGB_B(argb);
+ UNSAFE_BUFFERS(p[1]) = FXARGB_G(argb);
+ UNSAFE_BUFFERS(p[2]) = FXARGB_R(argb);
+ UNSAFE_BUFFERS(p[3]) = FXARGB_A(argb);
+}
+
+// SAFETY: Caller must ensure 4 valid bytes at `p`.
+UNSAFE_BUFFER_USAGE inline void FXARGB_SetRGBOrderDIB(uint8_t* p,
+ uint32_t argb) {
+ UNSAFE_BUFFERS(p[0]) = FXARGB_R(argb);
+ UNSAFE_BUFFERS(p[1]) = FXARGB_G(argb);
+ UNSAFE_BUFFERS(p[2]) = FXARGB_B(argb);
+ UNSAFE_BUFFERS(p[3]) = FXARGB_A(argb);
+}
+
+// SAFETY: Caller must ensure 3 valid bytes at `dest` and `src`.
+UNSAFE_BUFFER_USAGE inline void ReverseCopy3Bytes(uint8_t* dest,
+ const uint8_t* src) {
+ UNSAFE_BUFFERS(dest[2] = src[0]);
+ UNSAFE_BUFFERS(dest[1] = src[1]);
+ UNSAFE_BUFFERS(dest[0] = src[2]);
}
#endif // CORE_FXGE_DIB_FX_DIB_H_