Convert some memset(x, 0, sz) calls to aggregate initializations.
Avoid future unsafe-buffer markings.
-- Add asserts() in cases where modification to a "distant" declaration
of a type might subtly change the meaning.
Change-Id: I5d5c9ed80a3074e415f289ea972c393c196332a7
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/118930
Reviewed-by: Thomas Sepez <tsepez@google.com>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_security_handler_embeddertest.cpp b/core/fpdfapi/parser/cpdf_security_handler_embeddertest.cpp
index 4c9a016..0bef0f8 100644
--- a/core/fpdfapi/parser/cpdf_security_handler_embeddertest.cpp
+++ b/core/fpdfapi/parser/cpdf_security_handler_embeddertest.cpp
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include <string>
+#include <type_traits>
#include "build/build_config.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
@@ -176,8 +177,8 @@
UnloadPage(page);
}
std::string new_file = GetString();
- FPDF_FILEACCESS file_access;
- memset(&file_access, 0, sizeof(file_access));
+ FPDF_FILEACCESS file_access = {}; // Aggregate initialization.
+ static_assert(std::is_aggregate_v<decltype(file_access)>);
file_access.m_FileLen = new_file.size();
file_access.m_GetBlock = GetBlockFromString;
file_access.m_Param = &new_file;
diff --git a/core/fpdfdoc/cpdf_interactiveform.cpp b/core/fpdfdoc/cpdf_interactiveform.cpp
index b305fa2..fdffed2 100644
--- a/core/fpdfdoc/cpdf_interactiveform.cpp
+++ b/core/fpdfdoc/cpdf_interactiveform.cpp
@@ -7,6 +7,7 @@
#include "core/fpdfdoc/cpdf_interactiveform.h"
#include <optional>
+#include <type_traits>
#include <utility>
#include <vector>
@@ -60,9 +61,7 @@
return 1;
PDF_FONTDATA* pData = (PDF_FONTDATA*)lParam;
- // TODO(tsepez): investigate safety.
- UNSAFE_BUFFERS(
- FXSYS_memcpy(&pData->lf, &lpelfe->elfLogFont, sizeof(LOGFONTA)));
+ pData->lf = lpelfe->elfLogFont;
pData->bFind = true;
return 0;
}
@@ -70,7 +69,8 @@
bool RetrieveSpecificFont(FX_Charset charSet,
LPCSTR pcsFontName,
LOGFONTA& lf) {
- memset(&lf, 0, sizeof(LOGFONTA));
+ lf = {}; // Aggregate initialization, not construction.
+ static_assert(std::is_aggregate_v<std::remove_reference_t<decltype(lf)>>);
lf.lfCharSet = static_cast<int>(charSet);
lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
if (pcsFontName) {
@@ -79,8 +79,8 @@
strcpy(lf.lfFaceName, pcsFontName);
}
- PDF_FONTDATA fd;
- memset(&fd, 0, sizeof(PDF_FONTDATA));
+ PDF_FONTDATA fd = {}; // Aggregate initialization, not construction.
+ static_assert(std::is_aggregate_v<decltype(fd)>);
HDC hDC = ::GetDC(nullptr);
EnumFontFamiliesExA(hDC, &lf, (FONTENUMPROCA)EnumFontFamExProc, (LPARAM)&fd,
0);
diff --git a/core/fxcodec/gif/cfx_gifcontext_unittest.cpp b/core/fxcodec/gif/cfx_gifcontext_unittest.cpp
index 97a9b91..b97e2de 100644
--- a/core/fxcodec/gif/cfx_gifcontext_unittest.cpp
+++ b/core/fxcodec/gif/cfx_gifcontext_unittest.cpp
@@ -161,8 +161,7 @@
}
// LSD with all the values zero'd
{
- uint8_t lsd[sizeof(CFX_GifLocalScreenDescriptor)];
- memset(&lsd, 0, sizeof(CFX_GifLocalScreenDescriptor));
+ uint8_t lsd[sizeof(CFX_GifLocalScreenDescriptor)] = {};
context.SetTestInputBuffer(lsd);
EXPECT_EQ(GifDecoder::Status::kSuccess,
diff --git a/core/fxcodec/gif/lzw_decompressor_unittest.cpp b/core/fxcodec/gif/lzw_decompressor_unittest.cpp
index c97e92e..7d0cde9 100644
--- a/core/fxcodec/gif/lzw_decompressor_unittest.cpp
+++ b/core/fxcodec/gif/lzw_decompressor_unittest.cpp
@@ -130,8 +130,7 @@
uint32_t image_size = std::size(image_data);
uint8_t expected_data[] = {0x00};
- uint8_t output_data[std::size(expected_data)];
- memset(output_data, 0, sizeof(output_data));
+ uint8_t output_data[std::size(expected_data)] = {};
uint32_t output_size = std::size(output_data);
decompressor->SetSource(image_data, image_size);
@@ -162,8 +161,7 @@
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00};
- uint8_t output_data[std::size(kExpectedData)];
- memset(output_data, 0, sizeof(output_data));
+ uint8_t output_data[std::size(kExpectedData)] = {};
uint32_t output_size = std::size(output_data);
decompressor->SetSource(kImageData, image_size);
@@ -196,8 +194,7 @@
0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01,
0x01, 0x01, 0x01, 0x01};
- uint8_t output_data[std::size(kExpectedData)];
- memset(output_data, 0, sizeof(output_data));
+ uint8_t output_data[std::size(kExpectedData)] = {};
uint32_t output_size = std::size(output_data);
decompressor->SetSource(kImageData, image_size);
@@ -246,8 +243,7 @@
0xE2, 0xBE, 0xB0, 0x20, 0xCF, 0x74, 0x61, 0xDF, 0x78, 0x04};
uint32_t image_size = std::size(kImageData);
- uint8_t output_data[100]; // The uncompressed data is for a 10x10 image
- memset(output_data, 0, sizeof(output_data));
+ uint8_t output_data[100] = {}; // The uncompressed data is for a 10x10 image
uint32_t output_size = std::size(output_data);
decompressor->SetSource(kImageData, image_size);
diff --git a/core/fxcodec/jpeg/jpegmodule.cpp b/core/fxcodec/jpeg/jpegmodule.cpp
index 59aa2b3..e86e598 100644
--- a/core/fxcodec/jpeg/jpegmodule.cpp
+++ b/core/fxcodec/jpeg/jpegmodule.cpp
@@ -17,6 +17,7 @@
#include <memory>
#include <optional>
+#include <type_traits>
#include <utility>
#include "build/build_config.h"
@@ -160,22 +161,22 @@
static constexpr size_t kSofMarkerByteOffset = 5;
jmp_buf m_JmpBuf;
- jpeg_decompress_struct m_Cinfo;
- jpeg_error_mgr m_Jerr;
- jpeg_source_mgr m_Src;
+ jpeg_decompress_struct m_Cinfo = {};
+ jpeg_error_mgr m_Jerr = {};
+ jpeg_source_mgr m_Src = {};
pdfium::raw_span<const uint8_t> m_SrcSpan;
DataVector<uint8_t> m_ScanlineBuf;
bool m_bInited = false;
bool m_bStarted = false;
bool m_bJpegTransform = false;
uint32_t m_nDefaultScaleDenom = 1;
+
+ static_assert(std::is_aggregate_v<decltype(m_Cinfo)>);
+ static_assert(std::is_aggregate_v<decltype(m_Jerr)>);
+ static_assert(std::is_aggregate_v<decltype(m_Src)>);
};
-JpegDecoder::JpegDecoder() {
- memset(&m_Cinfo, 0, sizeof(m_Cinfo));
- memset(&m_Jerr, 0, sizeof(m_Jerr));
- memset(&m_Src, 0, sizeof(m_Src));
-}
+JpegDecoder::JpegDecoder() = default;
JpegDecoder::~JpegDecoder() {
if (m_bInited)
@@ -419,8 +420,8 @@
jerr.format_message = error_do_nothing_char;
jerr.reset_error_mgr = error_do_nothing;
- jpeg_compress_struct cinfo;
- memset(&cinfo, 0, sizeof(cinfo));
+ jpeg_compress_struct cinfo = {}; // Aggregate initialization.
+ static_assert(std::is_aggregate_v<decltype(cinfo)>);
cinfo.err = &jerr;
jpeg_create_compress(&cinfo);
int Bpp = pSource->GetBPP() / 8;
diff --git a/core/fxcodec/jpx/jpx_unittest.cpp b/core/fxcodec/jpx/jpx_unittest.cpp
index 316d73d..c4bfc10 100644
--- a/core/fxcodec/jpx/jpx_unittest.cpp
+++ b/core/fxcodec/jpx/jpx_unittest.cpp
@@ -11,6 +11,7 @@
#include <stdint.h>
#include <limits>
+#include <type_traits>
#include "core/fxcodec/jpx/cjpx_decoder.h"
#include "core/fxcodec/jpx/jpx_decode_utils.h"
@@ -387,30 +388,30 @@
}
TEST(fxcodec, YUV420ToRGB) {
- opj_image_comp_t u;
- memset(&u, 0, sizeof(u));
+ opj_image_comp_t u = {};
+ static_assert(std::is_aggregate_v<decltype(u)>);
u.dx = 1;
u.dy = 1;
u.w = 16;
u.h = 16;
u.prec = 8;
u.bpp = 8;
- opj_image_comp_t v;
- memset(&v, 0, sizeof(v));
+ opj_image_comp_t v = {};
+ static_assert(std::is_aggregate_v<decltype(v)>);
v.dx = 1;
v.dy = 1;
v.w = 16;
v.h = 16;
v.prec = 8;
v.bpp = 8;
- opj_image_comp_t y;
- memset(&y, 0, sizeof(y));
+ opj_image_comp_t y = {};
+ static_assert(std::is_aggregate_v<decltype(y)>);
y.dx = 1;
y.dy = 1;
y.prec = 8;
y.bpp = 8;
- opj_image_t img;
- memset(&img, 0, sizeof(img));
+ opj_image_t img = {};
+ static_assert(std::is_aggregate_v<decltype(img)>);
img.numcomps = 3;
img.color_space = OPJ_CLRSPC_SYCC;
img.comps = FX_Alloc(opj_image_comp_t, 3);
diff --git a/core/fxcrt/cfx_fileaccess_posix.cpp b/core/fxcrt/cfx_fileaccess_posix.cpp
index 1976a5f..c9f5ce3 100644
--- a/core/fxcrt/cfx_fileaccess_posix.cpp
+++ b/core/fxcrt/cfx_fileaccess_posix.cpp
@@ -51,15 +51,16 @@
close(m_nFD);
m_nFD = -1;
}
+
FX_FILESIZE CFX_FileAccess_Posix::GetSize() const {
if (m_nFD < 0) {
return 0;
}
- struct stat s;
- memset(&s, 0, sizeof(s));
+ struct stat s = {};
fstat(m_nFD, &s);
return pdfium::checked_cast<FX_FILESIZE>(s.st_size);
}
+
FX_FILESIZE CFX_FileAccess_Posix::GetPosition() const {
if (m_nFD < 0) {
return (FX_FILESIZE)-1;
diff --git a/core/fxge/win32/cgdi_device_driver.cpp b/core/fxge/win32/cgdi_device_driver.cpp
index 721ca76..7166c5c 100644
--- a/core/fxge/win32/cgdi_device_driver.cpp
+++ b/core/fxge/win32/cgdi_device_driver.cpp
@@ -492,8 +492,7 @@
struct {
BITMAPINFOHEADER bmiHeader;
uint32_t bmiColors[2];
- } bmi;
- memset(&bmi.bmiHeader, 0, sizeof(BITMAPINFOHEADER));
+ } bmi = {};
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biBitCount = 1;
bmi.bmiHeader.biCompression = BI_RGB;
diff --git a/core/fxge/win32/cgdi_display_driver.cpp b/core/fxge/win32/cgdi_display_driver.cpp
index 23c998f..8508208 100644
--- a/core/fxge/win32/cgdi_display_driver.cpp
+++ b/core/fxge/win32/cgdi_display_driver.cpp
@@ -45,8 +45,7 @@
HBITMAP holdbmp = (HBITMAP)SelectObject(hDCMemory, hbmp);
BitBlt(hDCMemory, 0, 0, width, height, m_hDC, left, top, SRCCOPY);
SelectObject(hDCMemory, holdbmp);
- BITMAPINFO bmi;
- memset(&bmi, 0, sizeof bmi);
+ BITMAPINFO bmi = {};
bmi.bmiHeader.biSize = sizeof bmi.bmiHeader;
bmi.bmiHeader.biBitCount = bitmap->GetBPP();
bmi.bmiHeader.biHeight = -height;
diff --git a/core/fxge/win32/cwin32_platform.cpp b/core/fxge/win32/cwin32_platform.cpp
index da60945..b07c026 100644
--- a/core/fxge/win32/cwin32_platform.cpp
+++ b/core/fxge/win32/cwin32_platform.cpp
@@ -13,6 +13,7 @@
#include <iterator>
#include <memory>
+#include <type_traits>
#include <utility>
#include "core/fxcrt/byteorder.h"
@@ -200,8 +201,8 @@
bool CFX_Win32FontInfo::EnumFontList(CFX_FontMapper* pMapper) {
m_pMapper = pMapper;
- LOGFONTA lf;
- memset(&lf, 0, sizeof(LOGFONTA));
+ LOGFONTA lf = {}; // Aggregate initialization.
+ static_assert(std::is_aggregate_v<decltype(lf)>);
lf.lfCharSet = static_cast<int>(FX_Charset::kDefault);
lf.lfFaceName[0] = 0;
lf.lfPitchAndFamily = 0;
diff --git a/fpdfsdk/fpdf_annot_embeddertest.cpp b/fpdfsdk/fpdf_annot_embeddertest.cpp
index 66198c6..9d1c00c 100644
--- a/fpdfsdk/fpdf_annot_embeddertest.cpp
+++ b/fpdfsdk/fpdf_annot_embeddertest.cpp
@@ -13,6 +13,7 @@
#include <algorithm>
#include <string>
+#include <type_traits>
#include <vector>
#include "build/build_config.h"
@@ -1116,8 +1117,8 @@
// TODO(npm): VerifySavedRendering changes annot rect dimensions by 1??
// Open the saved document.
std::string new_file = GetString();
- FPDF_FILEACCESS file_access;
- memset(&file_access, 0, sizeof(file_access));
+ FPDF_FILEACCESS file_access = {}; // Aggregate initialization
+ static_assert(std::is_aggregate_v<decltype(file_access)>);
file_access.m_FileLen = new_file.size();
file_access.m_GetBlock = GetBlockFromString;
file_access.m_Param = &new_file;
diff --git a/fpdfsdk/fpdf_structtree_embeddertest.cpp b/fpdfsdk/fpdf_structtree_embeddertest.cpp
index 7d220d9..0df7829 100644
--- a/fpdfsdk/fpdf_structtree_embeddertest.cpp
+++ b/fpdfsdk/fpdf_structtree_embeddertest.cpp
@@ -58,8 +58,7 @@
EXPECT_EQ(-1, FPDF_StructElement_GetMarkedContentID(gchild_element));
ASSERT_EQ(24U, FPDF_StructElement_GetAltText(gchild_element, nullptr, 0));
- unsigned short buffer[12];
- memset(buffer, 0, sizeof(buffer));
+ unsigned short buffer[12] = {};
// Deliberately pass in a small buffer size to make sure |buffer| remains
// untouched.
ASSERT_EQ(24U, FPDF_StructElement_GetAltText(gchild_element, buffer, 1));
@@ -456,12 +455,11 @@
ASSERT_TRUE(element);
// test nullptr inputs
- unsigned short buffer[12];
+ unsigned short buffer[12] = {};
ASSERT_EQ(0U, FPDF_StructElement_GetType(nullptr, buffer, sizeof(buffer)));
ASSERT_EQ(0U, FPDF_StructElement_GetType(nullptr, nullptr, 0));
ASSERT_EQ(18U, FPDF_StructElement_GetType(element, nullptr, 0));
- memset(buffer, 0, sizeof(buffer));
// Deliberately pass in a small buffer size to make sure |buffer| remains
// untouched.
ASSERT_EQ(18U, FPDF_StructElement_GetType(element, buffer, 1));
@@ -574,7 +572,7 @@
ASSERT_TRUE(element);
// test nullptr inputs
- unsigned short buffer[13];
+ unsigned short buffer[13] = {};
ASSERT_EQ(0U, FPDF_StructElement_GetTitle(nullptr, buffer, sizeof(buffer)));
ASSERT_EQ(0U, FPDF_StructElement_GetTitle(nullptr, nullptr, 0));
ASSERT_EQ(20U, FPDF_StructElement_GetTitle(element, nullptr, 0));
diff --git a/fpdfsdk/fpdf_text_embeddertest.cpp b/fpdfsdk/fpdf_text_embeddertest.cpp
index 4d55f0e..afff1ed 100644
--- a/fpdfsdk/fpdf_text_embeddertest.cpp
+++ b/fpdfsdk/fpdf_text_embeddertest.cpp
@@ -793,10 +793,9 @@
EXPECT_EQ(kNumLinks, FPDFLink_CountWebLinks(pagelink));
- unsigned short buffer[128];
for (int i = 0; i < kNumLinks; i++) {
+ unsigned short buffer[128] = {};
const size_t expected_len = strlen(kExpectedUrls[i]) + 1;
- memset(buffer, 0, sizeof(buffer));
EXPECT_EQ(static_cast<int>(expected_len),
FPDFLink_GetURL(pagelink, i, nullptr, 0));
EXPECT_EQ(static_cast<int>(expected_len),
@@ -1205,9 +1204,7 @@
0x0073, 0x0065, 0x0072, 0x0075, 0x006D, 0x0000};
{
constexpr int count = std::size(soft_expected) - 1;
- unsigned short buffer[std::size(soft_expected)];
- memset(buffer, 0, sizeof(buffer));
-
+ unsigned short buffer[std::size(soft_expected)] = {};
EXPECT_EQ(count + 1, FPDFText_GetText(textpage, 0, count, buffer));
for (int i = 0; i < count; i++)
EXPECT_EQ(soft_expected[i], buffer[i]);
diff --git a/xfa/fgas/font/cfgas_fontmgr.cpp b/xfa/fgas/font/cfgas_fontmgr.cpp
index 131fabf..c3a347e 100644
--- a/xfa/fgas/font/cfgas_fontmgr.cpp
+++ b/xfa/fgas/font/cfgas_fontmgr.cpp
@@ -16,6 +16,7 @@
#include <algorithm>
#include <iterator>
#include <memory>
+#include <type_traits>
#include <utility>
#include "build/build_config.h"
@@ -188,8 +189,8 @@
const LOGFONTW& lf = ((LPENUMLOGFONTEXW)lpelfe)->elfLogFont;
if (lf.lfFaceName[0] == L'@')
return 1;
- FX_FONTDESCRIPTOR font;
- memset(&font, 0, sizeof(FX_FONTDESCRIPTOR));
+ FX_FONTDESCRIPTOR font = {}; // Aggregate initialization.
+ static_assert(std::is_aggregate_v<decltype(font)>);
font.uCharSet = FX_GetCharsetFromInt(lf.lfCharSet);
font.dwFontStyles = GetGdiFontStyles(lf);
FXSYS_wcsncpy(font.wsFontFace, (const wchar_t*)lf.lfFaceName, 31);
@@ -209,8 +210,8 @@
return fonts;
}
- LOGFONTW lfFind;
- memset(&lfFind, 0, sizeof(lfFind));
+ LOGFONTW lfFind = {}; // Aggregate initialization.
+ static_assert(std::is_aggregate_v<decltype(lfFind)>);
lfFind.lfCharSet = DEFAULT_CHARSET;
if (pwsFaceName) {
FXSYS_wcsncpy(lfFind.lfFaceName, pwsFaceName, 31);
@@ -271,8 +272,8 @@
FX_CodePage wCodePage,
uint32_t dwUSB,
wchar_t wUnicode) {
- FX_FONTMATCHPARAMS params;
- memset(¶ms, 0, sizeof(params));
+ FX_FONTMATCHPARAMS params = {}; // Aggregate initialization.
+ static_assert(std::is_aggregate_v<decltype(params)>);
params.dwUSB = dwUSB;
params.wUnicode = wUnicode;
params.wCodePage = wCodePage;
@@ -528,8 +529,8 @@
ftStream->read = ftStreamRead;
ftStream->close = ftStreamClose;
- FT_Open_Args ftArgs;
- memset(&ftArgs, 0, sizeof(FT_Open_Args));
+ FT_Open_Args ftArgs = {}; // Aggregate initialization.
+ static_assert(std::is_aggregate_v<decltype(ftArgs)>);
ftArgs.flags |= FT_OPEN_STREAM;
ftArgs.stream = ftStream;