Begin marking unsafe libc functions as UNSAFE_BUFFERS().
Prepare for a time when the plugin will start enforcing these.
This is not an exhaustive list, but covers many of the most common
cases.
Change-Id: I36fdf195e7716e9f8ccfeda5164b5ba71ec70cd0
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/127271
Reviewed-by: Lei Zhang <thestig@chromium.org>
Reviewed-by: Thomas Sepez <tsepez@google.com>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fdrm/fx_crypt_unittest.cpp b/core/fdrm/fx_crypt_unittest.cpp
index 91fe60e..8b856ff 100644
--- a/core/fdrm/fx_crypt_unittest.cpp
+++ b/core/fdrm/fx_crypt_unittest.cpp
@@ -524,7 +524,7 @@
static const char kInput[] =
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
- EXPECT_EQ(112u, strlen(kInput));
+ EXPECT_EQ(112u, UNSAFE_TODO(strlen(kInput)));
DataVector<uint8_t> actual =
CRYPT_SHA384Generate(ByteStringView(kInput).unsigned_span());
EXPECT_THAT(
@@ -573,7 +573,7 @@
static const char kInput[] =
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
- EXPECT_EQ(112u, strlen(kInput));
+ EXPECT_EQ(112u, UNSAFE_TODO(strlen(kInput)));
DataVector<uint8_t> actual =
CRYPT_SHA512Generate(ByteStringView(kInput).unsigned_span());
EXPECT_THAT(
diff --git a/core/fpdfapi/edit/cpdf_creator_embeddertest.cpp b/core/fpdfapi/edit/cpdf_creator_embeddertest.cpp
index da69d50..87d0154 100644
--- a/core/fpdfapi/edit/cpdf_creator_embeddertest.cpp
+++ b/core/fpdfapi/edit/cpdf_creator_embeddertest.cpp
@@ -57,7 +57,7 @@
size_t trailer_start = saved_data.find(kTrailerBeforeSecondID);
static constexpr size_t kIdLen = 32;
size_t trailer_continuation =
- trailer_start + strlen(kTrailerBeforeSecondID) + kIdLen;
+ trailer_start + UNSAFE_TODO(strlen(kTrailerBeforeSecondID)) + kIdLen;
std::string data_after_second_id = saved_data.substr(trailer_continuation);
EXPECT_THAT(data_after_second_id, testing::StartsWith(">]>>\r\n"));
}
diff --git a/core/fpdfapi/font/cpdf_truetypefont.cpp b/core/fpdfapi/font/cpdf_truetypefont.cpp
index 8703bc8..e3be907 100644
--- a/core/fpdfapi/font/cpdf_truetypefont.cpp
+++ b/core/fpdfapi/font/cpdf_truetypefont.cpp
@@ -101,7 +101,7 @@
!name) {
continue;
}
- if (strcmp(name, ".notdef") == 0) {
+ if (UNSAFE_TODO(strcmp(name, ".notdef")) == 0) {
m_GlyphIndex[charcode] = face->GetCharIndex(32);
continue;
}
diff --git a/core/fpdfapi/font/cpdf_type1font.cpp b/core/fpdfapi/font/cpdf_type1font.cpp
index 126a9e0..895ee61 100644
--- a/core/fpdfapi/font/cpdf_type1font.cpp
+++ b/core/fpdfapi/font/cpdf_type1font.cpp
@@ -13,6 +13,7 @@
#include "build/build_config.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
+#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/fx_memcpy_wrappers.h"
#include "core/fxcrt/fx_system.h"
#include "core/fxcrt/span_util.h"
@@ -189,7 +190,8 @@
#if BUILDFLAG(IS_APPLE)
CalcExtGID(charcode);
#endif
- if (m_GlyphIndex[charcode] == 0 && strcmp(name, ".notdef") == 0) {
+ if (m_GlyphIndex[charcode] == 0 &&
+ UNSAFE_TODO(strcmp(name, ".notdef")) == 0) {
m_Encoding.SetUnicode(charcode, 0x20);
m_GlyphIndex[charcode] = face->GetCharIndex(0x20);
#if BUILDFLAG(IS_APPLE)
@@ -298,7 +300,8 @@
if (m_GlyphIndex[charcode] != 0)
continue;
- if (strcmp(name, ".notdef") != 0 && strcmp(name, "space") != 0) {
+ if (UNSAFE_TODO(strcmp(name, ".notdef")) != 0 &&
+ UNSAFE_TODO(strcmp(name, "space")) != 0) {
m_GlyphIndex[charcode] =
face->GetCharIndex(bUnicode ? m_Encoding.UnicodeFromCharCode(charcode)
: static_cast<uint32_t>(charcode));
diff --git a/core/fpdfapi/page/cpdf_iccprofile.cpp b/core/fpdfapi/page/cpdf_iccprofile.cpp
index c469edd..1d813f6 100644
--- a/core/fpdfapi/page/cpdf_iccprofile.cpp
+++ b/core/fpdfapi/page/cpdf_iccprofile.cpp
@@ -10,12 +10,15 @@
#include "core/fpdfapi/parser/cpdf_stream_acc.h"
#include "core/fxcodec/icc/icc_transform.h"
+#include "core/fxcrt/compiler_specific.h"
namespace {
bool DetectSRGB(pdfium::span<const uint8_t> span) {
static const char kSRGB[] = "sRGB IEC61966-2.1";
- return span.size() == 3144 && memcmp(&span[400], kSRGB, strlen(kSRGB)) == 0;
+ // SAFETY: size checked on LHS of &&-expression.
+ return span.size() == 3144 &&
+ UNSAFE_BUFFERS(memcmp(&span[400], kSRGB, strlen(kSRGB))) == 0;
}
} // namespace
diff --git a/core/fpdfapi/parser/cpdf_object_unittest.cpp b/core/fpdfapi/parser/cpdf_object_unittest.cpp
index 5cd3b46..520e977 100644
--- a/core/fpdfapi/parser/cpdf_object_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_object_unittest.cpp
@@ -176,7 +176,8 @@
if (span1.size() != span2.size())
return false;
- return memcmp(span1.data(), span2.data(), span2.size()) == 0;
+ return UNSAFE_TODO(memcmp(span1.data(), span2.data(), span2.size())) ==
+ 0;
}
case CPDF_Object::kReference:
return obj1->AsReference()->GetRefObjNum() ==
diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp
index 3e8a13a..a15c47e 100644
--- a/core/fpdfapi/parser/cpdf_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_parser.cpp
@@ -295,7 +295,8 @@
FX_FILESIZE CPDF_Parser::ParseStartXRef() {
static constexpr char kStartXRefKeyword[] = "startxref";
- m_pSyntax->SetPos(m_pSyntax->GetDocumentSize() - strlen(kStartXRefKeyword));
+ m_pSyntax->SetPos(m_pSyntax->GetDocumentSize() -
+ UNSAFE_TODO(strlen(kStartXRefKeyword)));
if (!m_pSyntax->BackwardsSearchToWord(kStartXRefKeyword, 4096))
return 0;
diff --git a/core/fpdfapi/parser/cpdf_security_handler.cpp b/core/fpdfapi/parser/cpdf_security_handler.cpp
index 4e87fd8..ec62240 100644
--- a/core/fpdfapi/parser/cpdf_security_handler.cpp
+++ b/core/fpdfapi/parser/cpdf_security_handler.cpp
@@ -347,8 +347,9 @@
}
CRYPT_SHA256Finish(&sha, digest);
}
- if (memcmp(digest, pkey, 32) != 0)
+ if (UNSAFE_TODO(FXSYS_memcmp(digest, pkey, 32)) != 0) {
return false;
+ }
if (m_Revision >= 6) {
Revision6_Hash(password, UNSAFE_TODO(pkey + 40),
@@ -456,7 +457,7 @@
FXSYS_memcpy(ukeybuf, kDefaultPasscode, sizeof(kDefaultPasscode)));
CRYPT_ArcFourCryptBlock(ukeybuf,
pdfium::make_span(m_EncryptKey).first(m_KeyLen));
- return memcmp(ukey.c_str(), ukeybuf, 16) == 0;
+ return UNSAFE_TODO(memcmp(ukey.c_str(), ukeybuf, 16)) == 0;
}
uint8_t test[32] = {};
@@ -474,7 +475,7 @@
if (!m_FileId.IsEmpty())
CRYPT_MD5Update(&md5, m_FileId.unsigned_span());
CRYPT_MD5Finish(&md5, pdfium::make_span(ukeybuf).first(16u));
- return memcmp(test, ukeybuf, 16) == 0;
+ return UNSAFE_TODO(memcmp(test, ukeybuf, 16)) == 0;
}
ByteString CPDF_SecurityHandler::GetUserPassword(
diff --git a/core/fpdfapi/parser/cpdf_seekablemultistream_unittest.cpp b/core/fpdfapi/parser/cpdf_seekablemultistream_unittest.cpp
index fa36d39..5d6942c 100644
--- a/core/fpdfapi/parser/cpdf_seekablemultistream_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_seekablemultistream_unittest.cpp
@@ -73,21 +73,21 @@
fxcrt::Fill(output_buffer, 0xbd);
EXPECT_TRUE(fileread->ReadBlockAtOffset(
pdfium::make_span(output_buffer).first(1u), 0));
- EXPECT_EQ(0, memcmp(output_buffer, "o", 1));
+ EXPECT_EQ(0, UNSAFE_TODO(memcmp(output_buffer, "o", 1)));
EXPECT_EQ(0xbd, output_buffer[1]);
fxcrt::Fill(output_buffer, 0xbd);
EXPECT_TRUE(fileread->ReadBlockAtOffset(output_buffer, 0));
- EXPECT_EQ(0, memcmp(output_buffer, "one two three!!!", 16));
+ EXPECT_EQ(0, UNSAFE_TODO(memcmp(output_buffer, "one two three!!!", 16)));
fxcrt::Fill(output_buffer, 0xbd);
EXPECT_TRUE(fileread->ReadBlockAtOffset(
pdfium::make_span(output_buffer).first(10u), 2));
- EXPECT_EQ(0, memcmp(output_buffer, "e two thre", 10));
+ EXPECT_EQ(0, UNSAFE_TODO(memcmp(output_buffer, "e two thre", 10)));
EXPECT_EQ(0xbd, output_buffer[11]);
fxcrt::Fill(output_buffer, 0xbd);
EXPECT_FALSE(fileread->ReadBlockAtOffset(output_buffer, 1));
- EXPECT_EQ(0, memcmp(output_buffer, "ne two three!!!", 15));
+ EXPECT_EQ(0, UNSAFE_TODO(memcmp(output_buffer, "ne two three!!!", 15)));
EXPECT_EQ(0xbd, output_buffer[15]);
}
diff --git a/core/fpdfapi/parser/cpdf_syntax_parser.cpp b/core/fpdfapi/parser/cpdf_syntax_parser.cpp
index b8d1a19..f252339 100644
--- a/core/fpdfapi/parser/cpdf_syntax_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_syntax_parser.cpp
@@ -761,8 +761,9 @@
// Earlier version of PDF specification doesn't require EOL marker before
// 'endstream' keyword. If keyword 'endstream' follows the bytes in
// specified length, it signals the end of stream.
- if (memcmp(m_WordBuffer.data(), kEndStreamStr.unterminated_unsigned_str(),
- kEndStreamStr.GetLength()) != 0) {
+ if (UNSAFE_TODO(memcmp(m_WordBuffer.data(),
+ kEndStreamStr.unterminated_unsigned_str(),
+ kEndStreamStr.GetLength())) != 0) {
substream.Reset();
len = -1;
SetPos(streamStartPos);
@@ -827,8 +828,9 @@
int numMarkers = ReadEOLMarkers(GetPos());
if (m_WordSize == static_cast<unsigned int>(kEndObjStr.GetLength()) &&
numMarkers != 0 &&
- memcmp(m_WordBuffer.data(), kEndObjStr.unterminated_unsigned_str(),
- kEndObjStr.GetLength()) == 0) {
+ UNSAFE_TODO(memcmp(m_WordBuffer.data(),
+ kEndObjStr.unterminated_unsigned_str(),
+ kEndObjStr.GetLength())) == 0) {
SetPos(end_stream_offset);
}
return stream;
diff --git a/core/fpdfapi/parser/fpdf_parser_utility.cpp b/core/fpdfapi/parser/fpdf_parser_utility.cpp
index 441dfd1..04e998d 100644
--- a/core/fpdfapi/parser/fpdf_parser_utility.cpp
+++ b/core/fpdfapi/parser/fpdf_parser_utility.cpp
@@ -19,6 +19,7 @@
#include "core/fpdfapi/parser/cpdf_string.h"
#include "core/fpdfapi/parser/fpdf_parser_decode.h"
#include "core/fxcrt/check.h"
+#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_stream.h"
@@ -82,8 +83,10 @@
if (!pFile->ReadBlockAtOffset(buf, offset))
return std::nullopt;
- if (memcmp(buf, "%PDF", 4) == 0)
+ // SAFETY: string literal and `buf` can accommodate 4 byte comparisons.
+ if (UNSAFE_BUFFERS(memcmp(buf, "%PDF", 4)) == 0) {
return offset;
+ }
}
return std::nullopt;
}
diff --git a/core/fpdfdoc/cpdf_interactiveform.cpp b/core/fpdfdoc/cpdf_interactiveform.cpp
index 497551a..16a5a62 100644
--- a/core/fpdfdoc/cpdf_interactiveform.cpp
+++ b/core/fpdfdoc/cpdf_interactiveform.cpp
@@ -140,9 +140,10 @@
const size_t szCount = csStr.GetLength();
size_t m = 0;
ByteString csTmp;
- while (m < strlen(kDummyFontName) && m < szCount)
+ while (m < UNSAFE_TODO(strlen(kDummyFontName)) && m < szCount) {
csTmp += csStr[m++];
- while (m < strlen(kDummyFontName)) {
+ }
+ while (m < UNSAFE_TODO(strlen(kDummyFontName))) {
csTmp += '0' + m % 10;
m++;
}
diff --git a/core/fpdftext/cpdf_linkextract.cpp b/core/fpdftext/cpdf_linkextract.cpp
index 53d16bd..341b674 100644
--- a/core/fpdftext/cpdf_linkextract.cpp
+++ b/core/fpdftext/cpdf_linkextract.cpp
@@ -180,19 +180,15 @@
std::optional<CPDF_LinkExtract::Link> CPDF_LinkExtract::CheckWebLink(
const WideString& strBeCheck) {
- static const wchar_t kHttpScheme[] = L"http";
- static const wchar_t kWWWAddrStart[] = L"www.";
-
- const size_t kHttpSchemeLen = wcslen(kHttpScheme);
- const size_t kWWWAddrStartLen = wcslen(kWWWAddrStart);
-
+ const WideStringView kHttpScheme = L"http";
+ const WideStringView kWWWAddrStart = L"www.";
WideString str = strBeCheck;
str.MakeLower();
// First, try to find the scheme.
auto start = str.Find(kHttpScheme);
if (start.has_value()) {
- size_t off = start.value() + kHttpSchemeLen; // move after "http".
+ size_t off = start.value() + kHttpScheme.GetLength(); // move after "http".
if (str.GetLength() > off + 4) { // At least "://<char>" follows.
if (str[off] == L's') // "https" scheme is accepted.
off++;
@@ -214,7 +210,7 @@
// When there is no scheme, try to find url starting with "www.".
start = str.Find(kWWWAddrStart);
if (start.has_value()) {
- size_t off = start.value() + kWWWAddrStartLen;
+ size_t off = start.value() + kWWWAddrStart.GetLength();
if (str.GetLength() > off) {
const size_t end =
FindWebLinkEnding(str, start.value(),
diff --git a/core/fxcodec/fax/faxmodule.cpp b/core/fxcodec/fax/faxmodule.cpp
index 593202f..2fe0c2d 100644
--- a/core/fxcodec/fax/faxmodule.cpp
+++ b/core/fxcodec/fax/faxmodule.cpp
@@ -90,8 +90,8 @@
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
const uint8_t* skip_block = bit ? skip_block_0 : skip_block_1;
while (byte_pos < max_byte - kBulkReadSize &&
- memcmp(data_buf.subspan(byte_pos).data(), skip_block,
- kBulkReadSize) == 0) {
+ UNSAFE_TODO(memcmp(data_buf.subspan(byte_pos).data(), skip_block,
+ kBulkReadSize)) == 0) {
byte_pos += kBulkReadSize;
}
}
diff --git a/core/fxcodec/gif/cfx_gifcontext.cpp b/core/fxcodec/gif/cfx_gifcontext.cpp
index 993d545..aa64063 100644
--- a/core/fxcodec/gif/cfx_gifcontext.cpp
+++ b/core/fxcodec/gif/cfx_gifcontext.cpp
@@ -343,11 +343,10 @@
if (!ReadAllOrNone(pdfium::byte_span_from_ref(header))) {
return GifDecoder::Status::kUnfinished;
}
- if (strncmp(header.signature, kGifSignature87, 6) != 0 &&
- strncmp(header.signature, kGifSignature89, 6) != 0) {
+ if (UNSAFE_TODO(strncmp(header.signature, kGifSignature87, 6)) != 0 &&
+ UNSAFE_TODO(strncmp(header.signature, kGifSignature89, 6)) != 0) {
return GifDecoder::Status::kError;
}
-
return GifDecoder::Status::kSuccess;
}
diff --git a/core/fxcodec/gif/cfx_gifcontext_unittest.cpp b/core/fxcodec/gif/cfx_gifcontext_unittest.cpp
index f5a626a..9c75577 100644
--- a/core/fxcodec/gif/cfx_gifcontext_unittest.cpp
+++ b/core/fxcodec/gif/cfx_gifcontext_unittest.cpp
@@ -207,8 +207,9 @@
EXPECT_EQ(1u, context.global_palette_exp_);
EXPECT_EQ(1, context.global_sort_flag_);
EXPECT_EQ(2, context.global_color_resolution_);
- EXPECT_EQ(0, memcmp(data.palette, context.global_palette_.data(),
- sizeof(data.palette)));
+ EXPECT_EQ(0,
+ UNSAFE_TODO(memcmp(data.palette, context.global_palette_.data(),
+ sizeof(data.palette))));
context.SetTestInputBuffer({});
}
}
@@ -280,8 +281,9 @@
EXPECT_EQ(1u, context.global_palette_exp_);
EXPECT_EQ(1, context.global_sort_flag_);
EXPECT_EQ(2, context.global_color_resolution_);
- EXPECT_EQ(0, memcmp(data.palette, context.global_palette_.data(),
- sizeof(data.palette)));
+ EXPECT_EQ(0,
+ UNSAFE_TODO(memcmp(data.palette, context.global_palette_.data(),
+ sizeof(data.palette))));
context.SetTestInputBuffer({});
}
}
diff --git a/core/fxcodec/gif/lzw_decompressor_unittest.cpp b/core/fxcodec/gif/lzw_decompressor_unittest.cpp
index d11e1be..edb7ff5 100644
--- a/core/fxcodec/gif/lzw_decompressor_unittest.cpp
+++ b/core/fxcodec/gif/lzw_decompressor_unittest.cpp
@@ -127,7 +127,8 @@
UNSAFE_TODO(decompressor->Decode(output_data, &output_size)));
EXPECT_EQ(std::size(output_data), output_size);
- EXPECT_TRUE(0 == memcmp(expected_data, output_data, sizeof(expected_data)));
+ EXPECT_TRUE(0 == UNSAFE_TODO(memcmp(expected_data, output_data,
+ sizeof(expected_data))));
}
TEST(LZWDecompressor, Decode10x10SingleColour) {
@@ -156,7 +157,8 @@
UNSAFE_TODO(decompressor->Decode(output_data, &output_size)));
EXPECT_EQ(std::size(output_data), output_size);
- EXPECT_TRUE(0 == memcmp(kExpectedData, output_data, sizeof(kExpectedData)));
+ EXPECT_TRUE(0 == UNSAFE_TODO(memcmp(kExpectedData, output_data,
+ sizeof(kExpectedData))));
}
TEST(LZWDecompressor, Decode10x10MultipleColour) {
@@ -186,7 +188,8 @@
UNSAFE_TODO(decompressor->Decode(output_data, &output_size)));
EXPECT_EQ(std::size(output_data), output_size);
- EXPECT_TRUE(0 == memcmp(kExpectedData, output_data, sizeof(kExpectedData)));
+ EXPECT_TRUE(0 == UNSAFE_TODO(memcmp(kExpectedData, output_data,
+ sizeof(kExpectedData))));
}
TEST(LZWDecompressor, MultipleDecodes) {
diff --git a/core/fxcodec/jpx/cjpx_decoder.cpp b/core/fxcodec/jpx/cjpx_decoder.cpp
index 90f729b..4d2e269 100644
--- a/core/fxcodec/jpx/cjpx_decoder.cpp
+++ b/core/fxcodec/jpx/cjpx_decoder.cpp
@@ -454,7 +454,8 @@
m_Parameters.decod_format = 0;
m_Parameters.cod_format = 3;
m_Parameters.cp_reduce = resolution_levels_to_skip;
- if (memcmp(m_SrcData.data(), kJP2Header, sizeof(kJP2Header)) == 0) {
+ if (UNSAFE_TODO(memcmp(m_SrcData.data(), kJP2Header, sizeof(kJP2Header))) ==
+ 0) {
m_Codec.reset(opj_create_decompress(OPJ_CODEC_JP2));
m_Parameters.decod_format = 1;
} else {
diff --git a/core/fxcodec/png/png_decoder.cpp b/core/fxcodec/png/png_decoder.cpp
index 34d5a26..0e42317 100644
--- a/core/fxcodec/png/png_decoder.cpp
+++ b/core/fxcodec/png/png_decoder.cpp
@@ -12,6 +12,7 @@
#include "core/fxcodec/cfx_codec_memory.h"
#include "core/fxcodec/fx_codec.h"
#include "core/fxcodec/fx_codec_def.h"
+#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/unowned_ptr.h"
#ifdef USE_SYSTEM_LIBPNG
@@ -37,8 +38,8 @@
void _png_error_data(png_structp png_ptr, png_const_charp error_msg) {
if (png_get_error_ptr(png_ptr)) {
- strncpy(static_cast<char*>(png_get_error_ptr(png_ptr)), error_msg,
- PNG_ERROR_SIZE - 1);
+ UNSAFE_TODO(strncpy(static_cast<char*>(png_get_error_ptr(png_ptr)),
+ error_msg, PNG_ERROR_SIZE - 1));
}
longjmp(png_jmpbuf(png_ptr), 1);
@@ -228,8 +229,8 @@
pdfium::span<uint8_t> src_buf = codec_memory->GetUnconsumedSpan();
if (!_png_continue_decode(ctx->m_pPng, ctx->m_pInfo, src_buf.data(),
src_buf.size())) {
- if (pAttribute &&
- strcmp(ctx->m_szLastError, "Read Header Callback Error") == 0) {
+ if (pAttribute && UNSAFE_TODO(strcmp(ctx->m_szLastError,
+ "Read Header Callback Error")) == 0) {
_png_load_bmp_attribute(ctx->m_pPng, ctx->m_pInfo, pAttribute);
}
return false;
diff --git a/core/fxcrt/bytestring.cpp b/core/fxcrt/bytestring.cpp
index 7db94bc..8b358f0 100644
--- a/core/fxcrt/bytestring.cpp
+++ b/core/fxcrt/bytestring.cpp
@@ -16,6 +16,7 @@
#include "core/fxcrt/check.h"
#include "core/fxcrt/check_op.h"
+#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/fx_codepage.h"
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_memcpy_wrappers.h"
@@ -49,10 +50,13 @@
}
// static
+// TODO(tsepez): Should be UNSAFE_BUFFER_USAGE.
ByteString ByteString::FormatV(const char* pFormat, va_list argList) {
va_list argListCopy;
va_copy(argListCopy, argList);
- int nMaxLen = vsnprintf(nullptr, 0, pFormat, argListCopy);
+
+ // SAFETY: required from caller.
+ int nMaxLen = UNSAFE_BUFFERS(vsnprintf(nullptr, 0, pFormat, argListCopy));
va_end(argListCopy);
if (nMaxLen <= 0)
@@ -68,7 +72,7 @@
// included in the span.
UNSAFE_BUFFERS(FXSYS_memset(buf.data(), 0, nMaxLen + 1));
va_copy(argListCopy, argList);
- vsnprintf(buf.data(), nMaxLen + 1, pFormat, argListCopy);
+ UNSAFE_TODO(vsnprintf(buf.data(), nMaxLen + 1, pFormat, argListCopy));
va_end(argListCopy);
}
ret.ReleaseBuffer(ret.GetStringLength());
@@ -149,12 +153,14 @@
}
}
+// TODO(tsepez): Should be UNSAFE_BUFFER_USAGE.
ByteString& ByteString::operator=(const char* str) {
- if (!str || !str[0])
+ if (!str || !str[0]) {
clear();
- else
- AssignCopy(str, strlen(str));
-
+ } else {
+ // SAFETY: required from caller.
+ AssignCopy(str, UNSAFE_BUFFERS(strlen(str)));
+ }
return *this;
}
@@ -181,10 +187,12 @@
return *this;
}
+// TODO(tsepez): Should be UNSAFE_BUFFER_USAGE
ByteString& ByteString::operator+=(const char* str) {
- if (str)
- Concat(str, strlen(str));
-
+ if (str) {
+ // SAFETY: required from caller.
+ Concat(str, UNSAFE_BUFFERS(strlen(str)));
+ }
return *this;
}
@@ -207,6 +215,7 @@
return *this;
}
+// TODO(tsepez): Should be UNSAFE_BUFFER_USAGE
bool ByteString::operator==(const char* ptr) const {
if (!m_pData)
return !ptr || !ptr[0];
@@ -215,8 +224,9 @@
return m_pData->m_nDataLength == 0;
// SAFETY: `m_nDataLength` is within `m_String`, and the strlen() call
- // ensures there are `m_nDataLength` bytes at `ptr` before the terminator.
- return strlen(ptr) == m_pData->m_nDataLength &&
+ // (whose own safety is required from the caller) ensures there are
+ // `m_nDataLength` bytes at `ptr` before the terminator.
+ return UNSAFE_BUFFERS(strlen(ptr)) == m_pData->m_nDataLength &&
UNSAFE_BUFFERS(
FXSYS_memcmp(ptr, m_pData->m_String, m_pData->m_nDataLength)) == 0;
}
@@ -234,28 +244,34 @@
}
bool ByteString::operator==(const ByteString& other) const {
- if (m_pData == other.m_pData)
+ if (m_pData == other.m_pData) {
return true;
-
- if (IsEmpty())
+ }
+ if (IsEmpty()) {
return other.IsEmpty();
-
- if (other.IsEmpty())
+ }
+ if (other.IsEmpty()) {
return false;
+ }
+ // SAFETY: m_nDataLength describes the length of m_String.
return other.m_pData->m_nDataLength == m_pData->m_nDataLength &&
- memcmp(other.m_pData->m_String, m_pData->m_String,
- m_pData->m_nDataLength) == 0;
+ UNSAFE_BUFFERS(memcmp(other.m_pData->m_String, m_pData->m_String,
+ m_pData->m_nDataLength)) == 0;
}
+// TODO(tsepez): Should be UNSAFE_BUFFER_USAGE.
bool ByteString::operator<(const char* ptr) const {
- if (!m_pData && !ptr)
+ if (!m_pData && !ptr) {
return false;
- if (c_str() == ptr)
+ }
+ if (c_str() == ptr) {
return false;
+ }
+ // SAFETY: required from caller.
+ size_t other_len = ptr ? UNSAFE_BUFFERS(strlen(ptr)) : 0;
size_t len = GetLength();
- size_t other_len = ptr ? strlen(ptr) : 0;
// SAFETY: Comparison limited to minimum valid length of either argument.
int result =
diff --git a/core/fxcrt/bytestring_unittest.cpp b/core/fxcrt/bytestring_unittest.cpp
index 398749c..793ab36 100644
--- a/core/fxcrt/bytestring_unittest.cpp
+++ b/core/fxcrt/bytestring_unittest.cpp
@@ -39,21 +39,22 @@
pdfium::span<const char> abc_span = abc.span();
EXPECT_EQ(3u, abc_span.size());
- EXPECT_EQ(0, memcmp(abc_span.data(), "abc", 3));
+ EXPECT_EQ(0, UNSAFE_TODO(memcmp(abc_span.data(), "abc", 3)));
pdfium::span<const char> abc_span_with_terminator =
abc.span_with_terminator();
EXPECT_EQ(4u, abc_span_with_terminator.size());
- EXPECT_EQ(0, memcmp(abc_span_with_terminator.data(), "abc", 4));
+ EXPECT_EQ(0, UNSAFE_TODO(memcmp(abc_span_with_terminator.data(), "abc", 4)));
pdfium::span<const uint8_t> abc_raw_span = abc.unsigned_span();
EXPECT_EQ(3u, abc_raw_span.size());
- EXPECT_EQ(0, memcmp(abc_raw_span.data(), "abc", 3));
+ EXPECT_EQ(0, UNSAFE_TODO(memcmp(abc_raw_span.data(), "abc", 3)));
pdfium::span<const uint8_t> abc_raw_span_with_terminator =
abc.unsigned_span_with_terminator();
EXPECT_EQ(4u, abc_raw_span_with_terminator.size());
- EXPECT_EQ(0, memcmp(abc_raw_span_with_terminator.data(), "abc", 4));
+ EXPECT_EQ(0,
+ UNSAFE_TODO(memcmp(abc_raw_span_with_terminator.data(), "abc", 4)));
ByteString mutable_abc = abc;
EXPECT_EQ(abc.c_str(), mutable_abc.c_str());
@@ -1027,8 +1028,9 @@
ByteString str1;
{
pdfium::span<char> buffer = str1.GetBuffer(12);
+ // SAFETY: required for test.
// NOLINTNEXTLINE(runtime/printf)
- strcpy(buffer.data(), "clams");
+ UNSAFE_BUFFERS(strcpy(buffer.data(), "clams"));
}
str1.ReleaseBuffer(str1.GetStringLength());
EXPECT_EQ("clams", str1);
@@ -1036,8 +1038,9 @@
ByteString str2("cl");
{
pdfium::span<char> buffer = str2.GetBuffer(12);
+ // SAFETY: required for test.
// NOLINTNEXTLINE(runtime/printf)
- strcpy(&buffer[2], "ams");
+ UNSAFE_BUFFERS(strcpy(&buffer[2], "ams"));
}
str2.ReleaseBuffer(str2.GetStringLength());
EXPECT_EQ("clams", str2);
@@ -1756,7 +1759,7 @@
const char* cstr = empty_str.c_str();
EXPECT_TRUE(cstr);
- EXPECT_EQ(0u, strlen(cstr));
+ EXPECT_EQ(0u, UNSAFE_TODO(strlen(cstr)));
const uint8_t* rstr = empty_str.unsigned_str();
EXPECT_FALSE(rstr);
diff --git a/core/fxcrt/fx_extension.cpp b/core/fxcrt/fx_extension.cpp
index 45393e6..0db87cd 100644
--- a/core/fxcrt/fx_extension.cpp
+++ b/core/fxcrt/fx_extension.cpp
@@ -36,7 +36,8 @@
// Force NUL-termination via copied buffer.
auto copied = WideString(pwsStr);
wchar_t* endptr = nullptr;
- float result = wcstof(copied.c_str(), &endptr);
+ // SAFETY: WideStrings are NUL-terminated.
+ float result = UNSAFE_BUFFERS(wcstof(copied.c_str(), &endptr));
if (result != result) {
result = 0.0f; // Convert NAN to 0.0f;
}
diff --git a/core/fxcrt/fx_stream.cpp b/core/fxcrt/fx_stream.cpp
index 3a5a307..9a0a00a 100644
--- a/core/fxcrt/fx_stream.cpp
+++ b/core/fxcrt/fx_stream.cpp
@@ -55,13 +55,16 @@
char buf[20] = {};
FXSYS_itoa(i, buf, 10);
auto buf_span = pdfium::as_byte_span(buf);
- return WriteBlock(buf_span.first(strlen(buf)));
+ // SAFETY: itoa() terminates buf.
+ return WriteBlock(buf_span.first(UNSAFE_BUFFERS(strlen(buf))));
}
bool IFX_WriteStream::WriteFilesize(FX_FILESIZE size) {
char buf[20] = {};
FXSYS_i64toa(size, buf, 10);
- return WriteBlock(pdfium::as_writable_byte_span(buf).first(strlen(buf)));
+ auto buf_span = pdfium::as_byte_span(buf);
+ // SAFETY: itoa() terminates buf.
+ return WriteBlock(buf_span.first(UNSAFE_BUFFERS(strlen(buf))));
}
// static
diff --git a/core/fxcrt/widestring.cpp b/core/fxcrt/widestring.cpp
index 0909cc6..f026326 100644
--- a/core/fxcrt/widestring.cpp
+++ b/core/fxcrt/widestring.cpp
@@ -15,6 +15,7 @@
#include "core/fxcrt/check.h"
#include "core/fxcrt/check_op.h"
+#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/fx_codepage.h"
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_memcpy_wrappers.h"
@@ -149,7 +150,7 @@
case 's': {
const wchar_t* pstrNextArg = va_arg(argList, const wchar_t*);
if (pstrNextArg) {
- nItemLen = wcslen(pstrNextArg);
+ nItemLen = UNSAFE_TODO(wcslen(pstrNextArg));
if (nItemLen < 1) {
nItemLen = 1;
}
@@ -160,7 +161,7 @@
case 'S': {
const char* pstrNextArg = va_arg(argList, const char*);
if (pstrNextArg) {
- nItemLen = strlen(pstrNextArg);
+ nItemLen = UNSAFE_TODO(strlen(pstrNextArg));
if (nItemLen < 1) {
nItemLen = 1;
}
@@ -172,7 +173,7 @@
case 'S' | FORCE_ANSI: {
const char* pstrNextArg = va_arg(argList, const char*);
if (pstrNextArg) {
- nItemLen = strlen(pstrNextArg);
+ nItemLen = UNSAFE_TODO(strlen(pstrNextArg));
if (nItemLen < 1) {
nItemLen = 1;
}
@@ -184,7 +185,7 @@
case 'S' | FORCE_UNICODE: {
const wchar_t* pstrNextArg = va_arg(argList, wchar_t*);
if (pstrNextArg) {
- nItemLen = wcslen(pstrNextArg);
+ nItemLen = UNSAFE_TODO(wcslen(pstrNextArg));
if (nItemLen < 1) {
nItemLen = 1;
}
@@ -239,7 +240,7 @@
f = va_arg(argList, double);
FXSYS_snprintf(pszTemp, sizeof(pszTemp), "%*.*f", nWidth,
nPrecision + 6, f);
- nItemLen = strlen(pszTemp);
+ nItemLen = UNSAFE_TODO(strlen(pszTemp));
}
break;
case 'p':
@@ -280,7 +281,7 @@
// See https://crbug.com/705912.
UNSAFE_BUFFERS(
FXSYS_memset(buffer.data(), 0, (size + 1) * sizeof(wchar_t)));
- int ret = vswprintf(buffer.data(), size + 1, pFormat, argList);
+ int ret = UNSAFE_TODO(vswprintf(buffer.data(), size + 1, pFormat, argList));
bool bSufficientBuffer = ret >= 0 || buffer[size - 1] == 0;
if (!bSufficientBuffer)
return std::nullopt;
@@ -359,7 +360,8 @@
// static
WideString WideString::FormatInteger(int i) {
wchar_t wbuf[32];
- swprintf(wbuf, std::size(wbuf), L"%d", i);
+ // SAFTEY: 32 bytes accommodates biggest int representation plus NUL.
+ UNSAFE_BUFFERS(swprintf(wbuf, std::size(wbuf), L"%d", i));
return WideString(wbuf);
}
@@ -450,12 +452,14 @@
}
}
+// Should be UNSAFE_BUFFER_USAGE.
WideString& WideString::operator=(const wchar_t* str) {
- if (!str || !str[0])
+ if (!str || !str[0]) {
clear();
- else
- AssignCopy(str, wcslen(str));
-
+ } else {
+ // SAFETY: required from caller.
+ AssignCopy(str, UNSAFE_BUFFERS(wcslen(str)));
+ }
return *this;
}
@@ -482,10 +486,12 @@
return *this;
}
+// Should be UNSAFE_BUFFER_USAGE.
WideString& WideString::operator+=(const wchar_t* str) {
- if (str)
- Concat(str, wcslen(str));
-
+ if (str) {
+ // SAFETY: required from caller.
+ Concat(str, UNSAFE_BUFFERS(wcslen(str)));
+ }
return *this;
}
@@ -508,16 +514,19 @@
return *this;
}
+// Should be UNSAFE_BUFFER_USAGE.
bool WideString::operator==(const wchar_t* ptr) const {
- if (!m_pData)
+ if (!m_pData) {
return !ptr || !ptr[0];
-
- if (!ptr)
+ }
+ if (!ptr) {
return m_pData->m_nDataLength == 0;
+ }
- // SAFTEY: `wsclen()` comparison ensures there are `m_nDataLength` wchars at
- // `ptr` before the terminator, and `m_nDataLength` is within `m_String`.
- return wcslen(ptr) == m_pData->m_nDataLength &&
+ // SAFTEY: `wsclen()` comparison (whose own safety depends upoon the caller)
+ // ensures there are `m_nDataLength` wchars at `ptr` before the terminator,
+ // and `m_nDataLength` is within `m_String`.
+ return UNSAFE_BUFFERS(wcslen(ptr)) == m_pData->m_nDataLength &&
UNSAFE_BUFFERS(FXSYS_wmemcmp(ptr, m_pData->m_String,
m_pData->m_nDataLength)) == 0;
}
@@ -544,9 +553,11 @@
if (other.IsEmpty())
return false;
+ // SAFETY: m_nDataLength bytes available at m_String.
return other.m_pData->m_nDataLength == m_pData->m_nDataLength &&
- wmemcmp(other.m_pData->m_String, m_pData->m_String,
- m_pData->m_nDataLength) == 0;
+ UNSAFE_BUFFERS(FXSYS_wmemcmp(other.m_pData->m_String,
+ m_pData->m_String,
+ m_pData->m_nDataLength)) == 0;
}
bool WideString::operator<(const wchar_t* ptr) const {
@@ -790,9 +801,12 @@
return result;
}
+// Should be UNSAFE_BUFFER_USAGE/
int WideString::Compare(const wchar_t* str) const {
- if (m_pData)
- return str ? wcscmp(m_pData->m_String, str) : 1;
+ if (m_pData) {
+ // SAFETY: required from caller.
+ return str ? UNSAFE_BUFFERS(wcscmp(m_pData->m_String, str)) : 1;
+ }
return (!str || str[0] == 0) ? 0 : -1;
}
diff --git a/core/fxcrt/widestring_unittest.cpp b/core/fxcrt/widestring_unittest.cpp
index 885b4cf..1ac37f9 100644
--- a/core/fxcrt/widestring_unittest.cpp
+++ b/core/fxcrt/widestring_unittest.cpp
@@ -39,12 +39,13 @@
pdfium::span<const wchar_t> abc_span = abc.span();
EXPECT_EQ(3u, abc_span.size());
- EXPECT_EQ(0, wmemcmp(abc_span.data(), L"abc", 3));
+ EXPECT_EQ(0, UNSAFE_TODO(wmemcmp(abc_span.data(), L"abc", 3)));
pdfium::span<const wchar_t> abc_span_with_terminator =
abc.span_with_terminator();
EXPECT_EQ(4u, abc_span_with_terminator.size());
- EXPECT_EQ(0, wmemcmp(abc_span_with_terminator.data(), L"abc", 4));
+ EXPECT_EQ(0,
+ UNSAFE_TODO(wmemcmp(abc_span_with_terminator.data(), L"abc", 4)));
WideString mutable_abc = abc;
EXPECT_EQ(abc.c_str(), mutable_abc.c_str());
@@ -1015,7 +1016,8 @@
WideString str1;
{
pdfium::span<wchar_t> buffer = str1.GetBuffer(12);
- wcscpy(buffer.data(), L"clams");
+ // SAFETY: required for test.
+ UNSAFE_BUFFERS(wcscpy(buffer.data(), L"clams"));
}
str1.ReleaseBuffer(str1.GetStringLength());
EXPECT_EQ(L"clams", str1);
@@ -1885,7 +1887,7 @@
const wchar_t* cstr = empty_str.c_str();
EXPECT_TRUE(cstr);
- EXPECT_EQ(0u, wcslen(cstr));
+ EXPECT_EQ(0u, UNSAFE_TODO(wcslen(cstr)));
pdfium::span<const wchar_t> cspan = empty_str.span();
EXPECT_TRUE(cspan.empty());
diff --git a/core/fxge/cfx_folderfontinfo.cpp b/core/fxge/cfx_folderfontinfo.cpp
index cda0141..af936b9 100644
--- a/core/fxge/cfx_folderfontinfo.cpp
+++ b/core/fxge/cfx_folderfontinfo.cpp
@@ -80,8 +80,11 @@
{
// Span's lifetime must end before ReleaseBuffer() below.
pdfium::span<char> buffer = result.GetBuffer(size);
- if (!fread(buffer.data(), size, 1, pFile))
+
+ // SAFETY: GetBuffer(size) ensures size bytes available.
+ if (!UNSAFE_BUFFERS(fread(buffer.data(), size, 1, pFile))) {
return ByteString();
+ }
}
result.ReleaseBuffer(size);
return result;
@@ -189,7 +192,9 @@
uint8_t buffer[16];
fseek(pFile.get(), 0, SEEK_SET);
- size_t items_read = fread(buffer, /*size=*/12, /*nmemb=*/1, pFile.get());
+ // SAFETY: 12 byte read fits into 16 byte buffer,
+ size_t items_read =
+ UNSAFE_BUFFERS(fread(buffer, /*size=*/12, /*nmemb=*/1, pFile.get()));
if (items_read != 1) {
return;
}
@@ -210,8 +215,8 @@
auto offsets =
FixedSizeDataVector<uint8_t>::Uninit(safe_face_bytes.ValueOrDie());
pdfium::span<uint8_t> offsets_span = offsets.span();
- items_read = fread(offsets_span.data(), /*size=*/1,
- /*nmemb=*/offsets_span.size(), pFile.get());
+ items_read = UNSAFE_TODO(fread(offsets_span.data(), /*size=*/1,
+ /*nmemb=*/offsets_span.size(), pFile.get()));
if (items_read != offsets_span.size()) {
return;
}
@@ -227,8 +232,13 @@
FX_FILESIZE filesize,
uint32_t offset) {
char buffer[16];
- if (fseek(pFile, offset, SEEK_SET) < 0 || !fread(buffer, 12, 1, pFile))
+ if (fseek(pFile, offset, SEEK_SET) < 0) {
return;
+ }
+ // SAFTEY: 12 byt read fits in 16 byte buffer.
+ if (UNSAFE_BUFFERS(!fread(buffer, 12, 1, pFile))) {
+ return;
+ }
uint32_t nTables =
fxcrt::GetUInt16MSBFirst(pdfium::as_byte_span(buffer).subspan<4, 2>());
@@ -417,8 +427,10 @@
if (!pFile)
return 0;
- if (fseek(pFile.get(), offset, SEEK_SET) < 0 ||
- fread(buffer.data(), datasize, 1, pFile.get()) != 1) {
+ if (fseek(pFile.get(), offset, SEEK_SET) < 0) {
+ return 0;
+ }
+ if (UNSAFE_TODO(fread(buffer.data(), datasize, 1, pFile.get())) != 1) {
return 0;
}
return datasize;
diff --git a/fpdfsdk/cpdfsdk_helpers.cpp b/fpdfsdk/cpdfsdk_helpers.cpp
index c1cf7d4..eb74519 100644
--- a/fpdfsdk/cpdfsdk_helpers.cpp
+++ b/fpdfsdk/cpdfsdk_helpers.cpp
@@ -520,16 +520,21 @@
for (const auto& entry : fxcrt::Split(bsStrippedPageRange, ',')) {
std::vector<ByteString> args = fxcrt::Split(entry, '-');
if (args.size() == 1) {
- uint32_t page_num = pdfium::checked_cast<uint32_t>(atoi(args[0].c_str()));
+ // SAFETY: ByteStrings are always NUL-terminated.
+ uint32_t page_num =
+ pdfium::checked_cast<uint32_t>(UNSAFE_BUFFERS(atoi(args[0].c_str())));
if (page_num == 0 || page_num > nCount)
return std::vector<uint32_t>();
results.push_back(page_num - 1);
} else if (args.size() == 2) {
+ // SAFETY: ByteStrings are always NUL-terminated.
uint32_t first_num =
- pdfium::checked_cast<uint32_t>(atoi(args[0].c_str()));
+ pdfium::checked_cast<uint32_t>(UNSAFE_BUFFERS(atoi(args[0].c_str())));
if (first_num == 0)
return std::vector<uint32_t>();
- uint32_t last_num = pdfium::checked_cast<uint32_t>(atoi(args[1].c_str()));
+ // SAFETY: ByteStrings are always NUL-terminated.
+ uint32_t last_num =
+ pdfium::checked_cast<uint32_t>(UNSAFE_BUFFERS(atoi(args[1].c_str())));
if (last_num == 0 || first_num > last_num || last_num > nCount)
return std::vector<uint32_t>();
for (uint32_t i = first_num; i <= last_num; ++i)
diff --git a/fpdfsdk/fpdf_attachment_embeddertest.cpp b/fpdfsdk/fpdf_attachment_embeddertest.cpp
index 66799ef..5f969a3 100644
--- a/fpdfsdk/fpdf_attachment_embeddertest.cpp
+++ b/fpdfsdk/fpdf_attachment_embeddertest.cpp
@@ -150,7 +150,7 @@
// Set the new attachment's file.
static constexpr char kContents1[] = "Hello!";
EXPECT_TRUE(FPDFAttachment_SetFile(attachment, document(), kContents1,
- strlen(kContents1)));
+ UNSAFE_TODO(strlen(kContents1))));
EXPECT_EQ(3, FPDFDoc_GetAttachmentCount(document()));
// Verify the name of the new attachment (i.e. the first attachment).
@@ -177,7 +177,7 @@
ASSERT_TRUE(attachment);
static constexpr char kContents2[] = "World!";
EXPECT_TRUE(FPDFAttachment_SetFile(attachment, document(), kContents2,
- strlen(kContents2)));
+ UNSAFE_TODO(strlen(kContents2))));
EXPECT_EQ(4, FPDFDoc_GetAttachmentCount(document()));
// Verify the name of the new attachment (i.e. the fourth attachment).
@@ -211,7 +211,7 @@
ASSERT_TRUE(attachment);
static constexpr char kContents[] = "Hello World!";
EXPECT_TRUE(FPDFAttachment_SetFile(attachment, document(), kContents,
- strlen(kContents)));
+ UNSAFE_TODO(strlen(kContents))));
// Set the date to be an arbitrary value.
static constexpr wchar_t kDateW[] = L"D:20170720161527-04'00'";
@@ -290,7 +290,7 @@
// Set the new attachment's file.
static constexpr char kContents1[] = "Hello!";
EXPECT_TRUE(FPDFAttachment_SetFile(attachment, document(), kContents1,
- strlen(kContents1)));
+ UNSAFE_TODO(strlen(kContents1))));
EXPECT_EQ(1, FPDFDoc_GetAttachmentCount(document()));
// Verify the name of the new attachment (i.e. the first attachment).
@@ -317,7 +317,7 @@
ASSERT_TRUE(attachment);
static constexpr char kContents2[] = "World!";
EXPECT_TRUE(FPDFAttachment_SetFile(attachment, document(), kContents2,
- strlen(kContents2)));
+ UNSAFE_TODO(strlen(kContents2))));
EXPECT_EQ(2, FPDFDoc_GetAttachmentCount(document()));
// Verify the name of the new attachment (i.e. the second attachment).
diff --git a/fpdfsdk/fpdf_edittext.cpp b/fpdfsdk/fpdf_edittext.cpp
index 23c8c3d..63ed5c2 100644
--- a/fpdfsdk/fpdf_edittext.cpp
+++ b/fpdfsdk/fpdf_edittext.cpp
@@ -703,8 +703,11 @@
uint32_t cid_to_gid_map_data_size) {
CPDF_Document* doc = CPDFDocumentFromFPDFDocument(document);
if (!doc || !font_data || font_data_size == 0 || !to_unicode_cmap ||
- strlen(to_unicode_cmap) == 0 || !cid_to_gid_map_data ||
- cid_to_gid_map_data_size == 0) {
+ !cid_to_gid_map_data || cid_to_gid_map_data_size == 0) {
+ return nullptr;
+ }
+ // SAFETY: required from caller.
+ if (UNSAFE_BUFFERS(strlen(to_unicode_cmap)) == 0) {
return nullptr;
}
// SAFETY: required from caller.
diff --git a/fpdfsdk/fpdf_javascript_embeddertest.cpp b/fpdfsdk/fpdf_javascript_embeddertest.cpp
index a366bf2..1b94a40 100644
--- a/fpdfsdk/fpdf_javascript_embeddertest.cpp
+++ b/fpdfsdk/fpdf_javascript_embeddertest.cpp
@@ -85,7 +85,7 @@
UNSAFE_TODO(FXSYS_memcpy(buf.data(), "abcdefgh", 8));
EXPECT_EQ(kExpectedLength, FPDFJavaScriptAction_GetName(js.get(), buf.data(),
kExpectedLength - 1));
- EXPECT_EQ(0, memcmp(buf.data(), "abcdefgh", 8));
+ EXPECT_EQ(0, UNSAFE_TODO(memcmp(buf.data(), "abcdefgh", 8)));
EXPECT_EQ(kExpectedLength, FPDFJavaScriptAction_GetName(js.get(), buf.data(),
kExpectedLength));
@@ -115,7 +115,7 @@
UNSAFE_TODO(FXSYS_memcpy(buf.data(), "abcdefgh", 8));
EXPECT_EQ(kExpectedLength, FPDFJavaScriptAction_GetScript(
js.get(), buf.data(), kExpectedLength - 1));
- EXPECT_EQ(0, memcmp(buf.data(), "abcdefgh", 8));
+ EXPECT_EQ(0, UNSAFE_TODO(memcmp(buf.data(), "abcdefgh", 8)));
static const wchar_t kExpectedScript[] =
L"function ping() {\n app.alert(\"ping\");\n}\n"
diff --git a/fpdfsdk/fpdf_signature_embeddertest.cpp b/fpdfsdk/fpdf_signature_embeddertest.cpp
index 1d36fa5..70f275e 100644
--- a/fpdfsdk/fpdf_signature_embeddertest.cpp
+++ b/fpdfsdk/fpdf_signature_embeddertest.cpp
@@ -54,7 +54,7 @@
std::vector<char> contents(size);
ASSERT_EQ(size,
FPDFSignatureObj_GetContents(signature, contents.data(), size));
- ASSERT_EQ(0, memcmp(kExpectedContents, contents.data(), size));
+ ASSERT_EQ(0, UNSAFE_TODO(memcmp(kExpectedContents, contents.data(), size)));
// FPDFSignatureObj_GetContents() negative testing.
ASSERT_EQ(0U, FPDFSignatureObj_GetContents(nullptr, nullptr, 0));
@@ -108,7 +108,8 @@
std::vector<char> sub_filter(size);
ASSERT_EQ(size,
FPDFSignatureObj_GetSubFilter(signature, sub_filter.data(), size));
- ASSERT_EQ(0, memcmp(kExpectedSubFilter, sub_filter.data(), size));
+ ASSERT_EQ(0,
+ UNSAFE_TODO(memcmp(kExpectedSubFilter, sub_filter.data(), size)));
// FPDFSignatureObj_GetSubFilter() negative testing.
ASSERT_EQ(0U, FPDFSignatureObj_GetSubFilter(nullptr, nullptr, 0));
@@ -174,7 +175,7 @@
std::vector<char> time_buffer(size);
ASSERT_EQ(size,
FPDFSignatureObj_GetTime(signature, time_buffer.data(), size));
- ASSERT_EQ(0, memcmp(kExpectedTime, time_buffer.data(), size));
+ ASSERT_EQ(0, UNSAFE_TODO(memcmp(kExpectedTime, time_buffer.data(), size)));
// FPDFSignatureObj_GetTime() negative testing.
ASSERT_EQ(0U, FPDFSignatureObj_GetTime(nullptr, nullptr, 0));
diff --git a/fpdfsdk/fpdf_sysfontinfo.cpp b/fpdfsdk/fpdf_sysfontinfo.cpp
index 6aca358..1cafcf9 100644
--- a/fpdfsdk/fpdf_sysfontinfo.cpp
+++ b/fpdfsdk/fpdf_sysfontinfo.cpp
@@ -240,9 +240,10 @@
const unsigned long copy_length =
pdfium::checked_cast<unsigned long>(name.GetLength() + 1);
- if (copy_length <= buf_size)
- strncpy(buffer, name.c_str(), copy_length * sizeof(ByteString::CharType));
-
+ if (copy_length <= buf_size) {
+ UNSAFE_TODO(strncpy(buffer, name.c_str(),
+ copy_length * sizeof(ByteString::CharType)));
+ }
return copy_length;
}
diff --git a/fpdfsdk/fpdf_text_embeddertest.cpp b/fpdfsdk/fpdf_text_embeddertest.cpp
index 1d626f4..815dd91 100644
--- a/fpdfsdk/fpdf_text_embeddertest.cpp
+++ b/fpdfsdk/fpdf_text_embeddertest.cpp
@@ -1313,7 +1313,7 @@
}
// Now test larger start values.
- const int kExpectedLength = strlen(kHelloGoodbyeText);
+ const int kExpectedLength = UNSAFE_TODO(strlen(kHelloGoodbyeText));
for (int start = kGoodbyeWorldStart + 1; start < kExpectedLength; ++start) {
EXPECT_EQ(1, FPDFText_CountRects(textpage.get(), start, -1));
EXPECT_EQ(0, FPDFText_CountRects(textpage.get(), start, 0));
diff --git a/fpdfsdk/fpdf_view.cpp b/fpdfsdk/fpdf_view.cpp
index 4128b6c..ac960e8 100644
--- a/fpdfsdk/fpdf_view.cpp
+++ b/fpdfsdk/fpdf_view.cpp
@@ -1236,12 +1236,13 @@
FPDF_EXPORT FPDF_RESULT FPDF_CALLCONV FPDF_BStr_Set(FPDF_BSTR* bstr,
const char* cstr,
int length) {
- if (!bstr || !cstr)
+ if (!bstr || !cstr) {
return -1;
-
- if (length == -1)
- length = pdfium::checked_cast<int>(strlen(cstr));
-
+ }
+ if (length == -1) {
+ // SAFETY: required from caller.
+ length = pdfium::checked_cast<int>(UNSAFE_BUFFERS(strlen(cstr)));
+ }
if (length == 0) {
FPDF_BStr_Clear(bstr);
return 0;
diff --git a/fpdfsdk/fpdf_view_embeddertest.cpp b/fpdfsdk/fpdf_view_embeddertest.cpp
index bd67326..8c42582 100644
--- a/fpdfsdk/fpdf_view_embeddertest.cpp
+++ b/fpdfsdk/fpdf_view_embeddertest.cpp
@@ -684,7 +684,7 @@
// Make sure |buf| does not get written into when it appears to be too small.
// NOLINTNEXTLINE(runtime/printf)
- strcpy(buf, "ABCD");
+ UNSAFE_TODO(strcpy(buf, "ABCD"));
EXPECT_EQ(4U, FPDF_VIEWERREF_GetName(document(), "Foo", buf, 1));
EXPECT_STREQ("ABCD", buf);
@@ -1288,9 +1288,9 @@
for (const auto& testcase : kTestCases) {
char name_buffer[20] = {};
- ASSERT_EQ(strlen(testcase.name) + 1,
+ ASSERT_EQ(UNSAFE_TODO(strlen(testcase.name)) + 1,
FPDF_GetXFAPacketName(document(), testcase.index, nullptr, 0));
- EXPECT_EQ(strlen(testcase.name) + 1,
+ EXPECT_EQ(UNSAFE_TODO(strlen(testcase.name)) + 1,
FPDF_GetXFAPacketName(document(), testcase.index, name_buffer,
sizeof(name_buffer)));
EXPECT_STREQ(testcase.name, name_buffer);
diff --git a/fxbarcode/oned/BC_OnedCodaBarWriter_unittest.cpp b/fxbarcode/oned/BC_OnedCodaBarWriter_unittest.cpp
index 57d4830..e767935 100644
--- a/fxbarcode/oned/BC_OnedCodaBarWriter_unittest.cpp
+++ b/fxbarcode/oned/BC_OnedCodaBarWriter_unittest.cpp
@@ -19,8 +19,8 @@
"# ## # # " // A Start
"# # # ##"; // B End
DataVector<uint8_t> encoded = writer.Encode("");
- ASSERT_EQ(strlen(kExpected1), encoded.size());
- for (size_t i = 0; i < strlen(kExpected1); i++) {
+ ASSERT_EQ(UNSAFE_TODO(strlen(kExpected1)), encoded.size());
+ for (size_t i = 0; i < UNSAFE_TODO(strlen(kExpected1)); i++) {
UNSAFE_TODO(EXPECT_EQ(kExpected1[i] != ' ', !!encoded[i])) << i;
}
static const char kExpected2[] =
@@ -30,8 +30,8 @@
"## # # # " // 3
"# # # ##"; // B End
encoded = writer.Encode("123");
- ASSERT_EQ(strlen(kExpected2), encoded.size());
- for (size_t i = 0; i < strlen(kExpected2); i++) {
+ ASSERT_EQ(UNSAFE_TODO(strlen(kExpected2)), encoded.size());
+ for (size_t i = 0; i < UNSAFE_TODO(strlen(kExpected2)); i++) {
UNSAFE_TODO(EXPECT_EQ(kExpected2[i] != ' ', !!encoded[i])) << i;
}
static const char kExpected3[] =
@@ -44,8 +44,8 @@
"# ## ## ## " // +
"# # # ##"; // B End
encoded = writer.Encode("-$./:+");
- ASSERT_EQ(strlen(kExpected3), encoded.size());
- for (size_t i = 0; i < strlen(kExpected3); i++) {
+ ASSERT_EQ(UNSAFE_TODO(strlen(kExpected3)), encoded.size());
+ for (size_t i = 0; i < UNSAFE_TODO(strlen(kExpected3)); i++) {
UNSAFE_TODO(EXPECT_EQ(kExpected3[i] != ' ', !!encoded[i])) << i;
}
static const char kExpected4[] =
@@ -69,8 +69,8 @@
"# # ## # " // 1
"# # # ##"; // B End
encoded = writer.Encode("456.987987987/001");
- ASSERT_EQ(strlen(kExpected4), encoded.size());
- for (size_t i = 0; i < strlen(kExpected4); i++) {
+ ASSERT_EQ(UNSAFE_TODO(strlen(kExpected4)), encoded.size());
+ for (size_t i = 0; i < UNSAFE_TODO(strlen(kExpected4)); i++) {
UNSAFE_TODO(EXPECT_EQ(kExpected4[i] != ' ', !!encoded[i])) << i;
}
}
@@ -114,8 +114,8 @@
"# # ## # " // 7
"# # # ##"; // * (same as C) End
DataVector<uint8_t> encoded = writer.Encode("987");
- ASSERT_EQ(strlen(kExpected), encoded.size());
- for (size_t i = 0; i < strlen(kExpected); i++) {
+ ASSERT_EQ(UNSAFE_TODO(strlen(kExpected)), encoded.size());
+ for (size_t i = 0; i < UNSAFE_TODO(strlen(kExpected)); i++) {
UNSAFE_TODO(EXPECT_EQ(kExpected[i] != ' ', !!encoded[i])) << i;
}
}
diff --git a/fxbarcode/oned/BC_OnedCode39Writer_unittest.cpp b/fxbarcode/oned/BC_OnedCode39Writer_unittest.cpp
index 3c0aa80..65acb76 100644
--- a/fxbarcode/oned/BC_OnedCode39Writer_unittest.cpp
+++ b/fxbarcode/oned/BC_OnedCode39Writer_unittest.cpp
@@ -38,8 +38,8 @@
"### ### # # # " // M
"# # ### ### #"; // * End
DataVector<uint8_t> encoded = writer.Encode("PDFIUM");
- ASSERT_EQ(strlen(kExpected1), encoded.size());
- for (size_t i = 0; i < strlen(kExpected1); i++) {
+ ASSERT_EQ(UNSAFE_TODO(strlen(kExpected1)), encoded.size());
+ for (size_t i = 0; i < UNSAFE_TODO(strlen(kExpected1)); i++) {
UNSAFE_TODO(EXPECT_EQ(kExpected1[i] != ' ', !!encoded[i])) << i;
}
writer.SetWideNarrowRatio(2);
@@ -54,8 +54,8 @@
"## ## # # # " // M
"# # ## ## #"; // * End
encoded = writer.Encode("PDFIUM");
- ASSERT_EQ(strlen(kExpected2), encoded.size());
- for (size_t i = 0; i < strlen(kExpected2); i++) {
+ ASSERT_EQ(UNSAFE_TODO(strlen(kExpected2)), encoded.size());
+ for (size_t i = 0; i < UNSAFE_TODO(strlen(kExpected2)); i++) {
UNSAFE_TODO(EXPECT_EQ(kExpected2[i] != ' ', !!encoded[i])) << i;
}
}
@@ -67,8 +67,8 @@
"# # ### ### # " // * Start
"# # ### ### #"; // * End
DataVector<uint8_t> encoded = writer.Encode("");
- ASSERT_EQ(strlen(kExpected1), encoded.size());
- for (size_t i = 0; i < strlen(kExpected1); i++) {
+ ASSERT_EQ(UNSAFE_TODO(strlen(kExpected1)), encoded.size());
+ for (size_t i = 0; i < UNSAFE_TODO(strlen(kExpected1)); i++) {
UNSAFE_TODO(EXPECT_EQ(kExpected1[i] != ' ', !!encoded[i])) << i;
}
@@ -79,8 +79,8 @@
"### ### # # # " // 3
"# # ### ### #"; // * End
encoded = writer.Encode("123");
- ASSERT_EQ(strlen(kExpected2), encoded.size());
- for (size_t i = 0; i < strlen(kExpected2); i++) {
+ ASSERT_EQ(UNSAFE_TODO(strlen(kExpected2)), encoded.size());
+ for (size_t i = 0; i < UNSAFE_TODO(strlen(kExpected2)); i++) {
UNSAFE_TODO(EXPECT_EQ(kExpected2[i] != ' ', !!encoded[i])) << i;
}
@@ -94,8 +94,8 @@
"### ### # # # " // M
"# # ### ### #"; // * End
encoded = writer.Encode("PDFIUM");
- ASSERT_EQ(strlen(kExpected3), encoded.size());
- for (size_t i = 0; i < strlen(kExpected3); i++) {
+ ASSERT_EQ(UNSAFE_TODO(strlen(kExpected3)), encoded.size());
+ for (size_t i = 0; i < UNSAFE_TODO(strlen(kExpected3)); i++) {
UNSAFE_TODO(EXPECT_EQ(kExpected3[i] != ' ', !!encoded[i])) << i;
}
@@ -112,8 +112,8 @@
"# ### ### # # " // Z
"# # ### ### #"; // * End
encoded = writer.Encode("A -$%./+Z");
- ASSERT_EQ(strlen(kExpected4), encoded.size());
- for (size_t i = 0; i < strlen(kExpected4); i++) {
+ ASSERT_EQ(UNSAFE_TODO(strlen(kExpected4)), encoded.size());
+ for (size_t i = 0; i < UNSAFE_TODO(strlen(kExpected4)); i++) {
UNSAFE_TODO(EXPECT_EQ(kExpected4[i] != ' ', !!encoded[i])) << i;
}
}
@@ -130,9 +130,10 @@
"# ### ### # # " // 6 (6 = (1 + 2 + 3) % 43)
"# # ### ### #"; // * End
DataVector<uint8_t> encoded = writer.Encode("123");
- ASSERT_EQ(strlen(kExpected1), encoded.size());
- for (size_t i = 0; i < strlen(kExpected1); i++)
+ ASSERT_EQ(UNSAFE_TODO(strlen(kExpected1)), encoded.size());
+ for (size_t i = 0; i < UNSAFE_TODO(strlen(kExpected1)); i++) {
UNSAFE_TODO(EXPECT_EQ(kExpected1[i] != ' ', !!encoded[i])) << i;
+ }
static const char kExpected2[] =
"# # ### ### # " // * Start
@@ -145,8 +146,8 @@
"### # # ### # " // . (37 = (25 + 13 + 15 + 18 + 30 + 22) % 43)
"# # ### ### #"; // * End
encoded = writer.Encode("PDFIUM");
- ASSERT_EQ(strlen(kExpected2), encoded.size());
- for (size_t i = 0; i < strlen(kExpected2); i++) {
+ ASSERT_EQ(UNSAFE_TODO(strlen(kExpected2)), encoded.size());
+ for (size_t i = 0; i < UNSAFE_TODO(strlen(kExpected2)); i++) {
UNSAFE_TODO(EXPECT_EQ(kExpected2[i] != ' ', !!encoded[i])) << i;
}
}
diff --git a/fxbarcode/oned/BC_OnedEAN13Writer_unittest.cpp b/fxbarcode/oned/BC_OnedEAN13Writer_unittest.cpp
index 6671fe2..9636b07 100644
--- a/fxbarcode/oned/BC_OnedEAN13Writer_unittest.cpp
+++ b/fxbarcode/oned/BC_OnedEAN13Writer_unittest.cpp
@@ -41,7 +41,7 @@
"# # " // 8 R
"# #"; // End
DataVector<uint8_t> encoded = writer.Encode("1234567890128");
- for (size_t i = 0; i < strlen(kExpected1); i++) {
+ for (size_t i = 0; i < UNSAFE_TODO(strlen(kExpected1)); i++) {
UNSAFE_TODO(EXPECT_EQ(kExpected1[i] != ' ', !!encoded[i])) << i;
}
static const char kExpected2[] =
@@ -62,8 +62,8 @@
"### # " // 0 R
"# #"; // End
encoded = writer.Encode("7776665554440");
- ASSERT_EQ(strlen(kExpected2), encoded.size());
- for (size_t i = 0; i < strlen(kExpected2); i++) {
+ ASSERT_EQ(UNSAFE_TODO(strlen(kExpected2)), encoded.size());
+ for (size_t i = 0; i < UNSAFE_TODO(strlen(kExpected2)); i++) {
UNSAFE_TODO(EXPECT_EQ(kExpected2[i] != ' ', !!encoded[i])) << i;
}
}
diff --git a/fxbarcode/oned/BC_OnedEAN8Writer_unittest.cpp b/fxbarcode/oned/BC_OnedEAN8Writer_unittest.cpp
index 12fa994..612779f 100644
--- a/fxbarcode/oned/BC_OnedEAN8Writer_unittest.cpp
+++ b/fxbarcode/oned/BC_OnedEAN8Writer_unittest.cpp
@@ -36,8 +36,8 @@
"### # " // 0 R
"# #"; // End
DataVector<uint8_t> encoded = writer.Encode("12345670");
- ASSERT_EQ(strlen(kExpected1), encoded.size());
- for (size_t i = 0; i < strlen(kExpected1); i++) {
+ ASSERT_EQ(UNSAFE_TODO(strlen(kExpected1)), encoded.size());
+ for (size_t i = 0; i < UNSAFE_TODO(strlen(kExpected1)); i++) {
UNSAFE_TODO(EXPECT_EQ(kExpected1[i] != ' ', !!encoded[i])) << i;
}
static const char kExpected2[] =
@@ -53,9 +53,10 @@
"# ### " // 4 R
"# #"; // End
encoded = writer.Encode("99441104");
- ASSERT_EQ(strlen(kExpected2), encoded.size());
- for (size_t i = 0; i < strlen(kExpected2); i++)
+ ASSERT_EQ(UNSAFE_TODO(strlen(kExpected2)), encoded.size());
+ for (size_t i = 0; i < UNSAFE_TODO(strlen(kExpected2)); i++) {
UNSAFE_TODO(EXPECT_EQ(kExpected2[i] != ' ', !!encoded[i])) << i;
+ }
}
TEST(OnedEAN8WriterTest, Checksum) {
diff --git a/fxbarcode/oned/BC_OnedUPCAWriter_unittest.cpp b/fxbarcode/oned/BC_OnedUPCAWriter_unittest.cpp
index e818d7c..cb56389 100644
--- a/fxbarcode/oned/BC_OnedUPCAWriter_unittest.cpp
+++ b/fxbarcode/oned/BC_OnedUPCAWriter_unittest.cpp
@@ -40,8 +40,8 @@
"## ## " // 2 R
"# #"; // End
DataVector<uint8_t> encoded = writer.Encode("123456789012");
- ASSERT_EQ(strlen(kExpected1), encoded.size());
- for (size_t i = 0; i < strlen(kExpected1); i++) {
+ ASSERT_EQ(UNSAFE_TODO(strlen(kExpected1)), encoded.size());
+ for (size_t i = 0; i < UNSAFE_TODO(strlen(kExpected1)); i++) {
UNSAFE_TODO(EXPECT_EQ(kExpected1[i] != ' ', !!encoded[i])) << i;
}
@@ -62,8 +62,8 @@
"# ### " // 4 R
"### # " // 0 R
"# #"; // End
- ASSERT_EQ(strlen(kExpected2), encoded.size());
- for (size_t i = 0; i < strlen(kExpected2); i++) {
+ ASSERT_EQ(UNSAFE_TODO(strlen(kExpected2)), encoded.size());
+ for (size_t i = 0; i < UNSAFE_TODO(strlen(kExpected2)); i++) {
UNSAFE_TODO(EXPECT_EQ(kExpected2[i] != ' ', !!encoded[i])) << i;
}
}
diff --git a/fxjs/cjs_publicmethods.cpp b/fxjs/cjs_publicmethods.cpp
index f935264..7bb7a86 100644
--- a/fxjs/cjs_publicmethods.cpp
+++ b/fxjs/cjs_publicmethods.cpp
@@ -616,7 +616,9 @@
// Processing decimal places
NormalizeDecimalMark(&strValue);
- double dValue = atof(strValue.c_str());
+
+ // SAFETY: ByteStrings are always NUL-terminated.
+ double dValue = UNSAFE_BUFFERS(atof(strValue.c_str()));
if (iDec > 0)
dValue += kDoubleCorrect;
@@ -822,7 +824,8 @@
strValue = "0";
// for processing decimal places
- double dValue = atof(strValue.c_str());
+ // SAFETY: ByteStrings are always NUL-terminated.
+ double dValue = UNSAFE_BUFFERS(atof(strValue.c_str()));
dValue *= 100;
size_t szNewSize;
@@ -842,8 +845,8 @@
// Write into |strValue|.
pdfium::span<char> span = strValue.GetBuffer(szBufferSize);
- FXSYS_snprintf(span.data(), szBufferSize, format, dValue);
- szNewSize = strlen(span.data());
+ UNSAFE_TODO(FXSYS_snprintf(span.data(), szBufferSize, format, dValue));
+ szNewSize = UNSAFE_TODO(strlen(span.data()));
}
strValue.ReleaseBuffer(szNewSize);
@@ -1392,7 +1395,8 @@
if (pEvent->Value().IsEmpty())
return CJS_Result::Success();
- double dEventValue = atof(pEvent->Value().ToUTF8().c_str());
+ // SAFETY: ByteStrings are always NUL-terminated.
+ double dEventValue = UNSAFE_BUFFERS(atof(pEvent->Value().ToUTF8().c_str()));
bool bGreaterThan = pRuntime->ToBoolean(params[0]);
double dGreaterThan = pRuntime->ToDouble(params[1]);
bool bLessThan = pRuntime->ToBoolean(params[2]);
diff --git a/fxjs/cjs_util.cpp b/fxjs/cjs_util.cpp
index e3c22c2..ce580b5 100644
--- a/fxjs/cjs_util.cpp
+++ b/fxjs/cjs_util.cpp
@@ -225,7 +225,7 @@
if (nFound == std::wstring::npos) {
break;
}
- cFormat.replace(nFound, wcslen(conversion.lpszJSMark),
+ cFormat.replace(nFound, UNSAFE_TODO(wcslen(conversion.lpszJSMark)),
conversion.lpszCppMark);
}
}
diff --git a/fxjs/js_define.h b/fxjs/js_define.h
index 58163ff..1175dcc 100644
--- a/fxjs/js_define.h
+++ b/fxjs/js_define.h
@@ -131,7 +131,8 @@
for (unsigned int i = 0; i < (unsigned int)info.Length(); i++)
parameters.push_back(info[i]);
- CJS_Result result = (pObj.get()->*M)(pRuntime, parameters);
+ // TODO(tsepez): why does the compiler think this is sometimes unsafe?
+ CJS_Result result = UNSAFE_TODO((pObj.get()->*M)(pRuntime, parameters));
if (result.HasError()) {
pRuntime->Error(JSFormatErrorString(class_name_string, method_name_string,
result.Error()));
diff --git a/fxjs/xfa/cfxjse_formcalc_context.cpp b/fxjs/xfa/cfxjse_formcalc_context.cpp
index 27db406..796768b 100644
--- a/fxjs/xfa/cfxjse_formcalc_context.cpp
+++ b/fxjs/xfa/cfxjse_formcalc_context.cpp
@@ -549,7 +549,8 @@
bool HTMLSTR2Code(const WideString& pData, uint32_t* iCode) {
auto cmpFunc = [](const XFA_FMHtmlReserveCode& iter, ByteStringView val) {
- return strcmp(val.unterminated_c_str(), iter.m_htmlReserve) > 0;
+ return UNSAFE_TODO(strcmp(val.unterminated_c_str(), iter.m_htmlReserve)) >
+ 0;
};
if (!pData.IsASCII())
return false;
@@ -558,7 +559,7 @@
std::begin(kReservesForDecode), std::end(kReservesForDecode),
temp.AsStringView(), cmpFunc);
if (result != std::end(kReservesForDecode) &&
- !strcmp(temp.c_str(), result->m_htmlReserve)) {
+ !UNSAFE_TODO(strcmp(temp.c_str(), result->m_htmlReserve))) {
*iCode = result->m_uCode;
return true;
}
@@ -1098,7 +1099,8 @@
if (fxv8::IsString(extracted)) {
ByteString bsValue = fxv8::ReentrantToByteStringHelper(pIsolate, extracted);
- return strtof(bsValue.c_str(), nullptr);
+ // SAFETY: ByteStrings are always NUL-terminated.
+ return UNSAFE_BUFFERS(strtof(bsValue.c_str(), nullptr));
}
return fxv8::ReentrantToFloatHelper(pIsolate, extracted);
@@ -1117,7 +1119,8 @@
if (fxv8::IsString(extracted)) {
ByteString bsValue = fxv8::ReentrantToByteStringHelper(pIsolate, extracted);
- return strtod(bsValue.c_str(), nullptr);
+ // SAFETY: ByteStrings are always NUL_terminated.
+ return UNSAFE_BUFFERS(strtod(bsValue.c_str(), nullptr));
}
return fxv8::ReentrantToDoubleHelper(pIsolate, extracted);
diff --git a/xfa/fgas/crt/cfgas_stringformatter.cpp b/xfa/fgas/crt/cfgas_stringformatter.cpp
index 38eae09..fd58d99 100644
--- a/xfa/fgas/crt/cfgas_stringformatter.cpp
+++ b/xfa/fgas/crt/cfgas_stringformatter.cpp
@@ -217,7 +217,8 @@
continue;
}
if (ccf + spDotSymbol.size() <= spNum.size() &&
- wcsncmp(&spNum[ccf], spDotSymbol.data(), spDotSymbol.size()) == 0) {
+ UNSAFE_TODO(wcsncmp(&spNum[ccf], spDotSymbol.data(),
+ spDotSymbol.size())) == 0) {
*iDotIndex = ccf;
return true;
}
diff --git a/xfa/fxfa/parser/cxfa_localevalue.cpp b/xfa/fxfa/parser/cxfa_localevalue.cpp
index c938f7a..92cff00 100644
--- a/xfa/fxfa/parser/cxfa_localevalue.cpp
+++ b/xfa/fxfa/parser/cxfa_localevalue.cpp
@@ -224,7 +224,8 @@
return 0;
}
- return wcstod(m_wsValue.c_str(), nullptr);
+ // SAFETY: WideStrings are always terminated.
+ return UNSAFE_BUFFERS(wcstod(m_wsValue.c_str(), nullptr));
}
CFX_DateTime CXFA_LocaleValue::GetDate() const {