Mark two-arg ByteString() constructor as UNSAFE_BUFFER_USAGE.
Follow-on from
https://pdfium-review.googlesource.com/c/pdfium/+/119677
but uses the same technique on ByteString.
Change-Id: If0d1f56c99a2ff5dd6be5dc0f1c25ffc887546fd
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/119692
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Reviewed-by: Thomas Sepez <tsepez@google.com>
diff --git a/core/fpdfapi/font/cpdf_font.cpp b/core/fpdfapi/font/cpdf_font.cpp
index a714894..bba8ff4 100644
--- a/core/fpdfapi/font/cpdf_font.cpp
+++ b/core/fpdfapi/font/cpdf_font.cpp
@@ -305,8 +305,8 @@
if (type == "TrueType") {
ByteString tag = pFontDict->GetByteStringFor("BaseFont").First(4);
for (size_t i = 0; i < std::size(kChineseFontNames); ++i) {
- if (tag ==
- UNSAFE_TODO(ByteString(kChineseFontNames[i], kChineseFontNameSize))) {
+ if (tag == UNSAFE_TODO(ByteString::Create(kChineseFontNames[i],
+ kChineseFontNameSize))) {
RetainPtr<const CPDF_Dictionary> pFontDesc =
pFontDict->GetDictFor("FontDescriptor");
if (!pFontDesc || !pFontDesc->KeyExist("FontFile2"))
diff --git a/core/fpdfapi/parser/cpdf_security_handler.cpp b/core/fpdfapi/parser/cpdf_security_handler.cpp
index 53dd844..c956be0 100644
--- a/core/fpdfapi/parser/cpdf_security_handler.cpp
+++ b/core/fpdfapi/parser/cpdf_security_handler.cpp
@@ -21,6 +21,7 @@
#include "core/fxcrt/byteorder.h"
#include "core/fxcrt/check.h"
#include "core/fxcrt/check_op.h"
+#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/data_vector.h"
#include "core/fxcrt/fx_memcpy_wrappers.h"
#include "core/fxcrt/fx_random.h"
@@ -525,7 +526,7 @@
len--;
}
});
- return ByteString(okeybuf, len);
+ return UNSAFE_TODO(ByteString::Create(okeybuf, len));
}
bool CPDF_SecurityHandler::CheckOwnerPassword(const ByteString& password) {
@@ -589,7 +590,8 @@
FXSYS_memcpy(tempbuf, kDefaultPasscode, sizeof(kDefaultPasscode)));
CRYPT_ArcFourCryptBlock(tempbuf,
pdfium::make_span(m_EncryptKey).first(key_len));
- pEncryptDict->SetNewFor<CPDF_String>("U", ByteString(tempbuf, 32));
+ pEncryptDict->SetNewFor<CPDF_String>(
+ "U", UNSAFE_TODO(ByteString::Create(tempbuf, 32)));
} else {
CRYPT_md5_context md5 = CRYPT_MD5Start();
CRYPT_MD5Update(&md5, kDefaultPasscode);
@@ -611,7 +613,8 @@
}
CRYPT_MD5Generate(pdfium::make_span(digest).first(16u),
pdfium::make_span(digest).subspan(16u).data());
- pEncryptDict->SetNewFor<CPDF_String>("U", ByteString(digest, 32));
+ pEncryptDict->SetNewFor<CPDF_String>(
+ "U", UNSAFE_TODO(ByteString::Create(digest, 32)));
}
InitCryptoHandler();
@@ -638,7 +641,8 @@
CRYPT_SHA256Finish(&sha2, digest1);
}
UNSAFE_TODO(FXSYS_memcpy(digest1 + 32, digest, 16));
- pEncryptDict->SetNewFor<CPDF_String>("U", ByteString(digest1, 48));
+ pEncryptDict->SetNewFor<CPDF_String>(
+ "U", UNSAFE_TODO(ByteString::Create(digest1, 48)));
if (m_Revision >= 6) {
Revision6_Hash(password, UNSAFE_TODO(digest + 8), nullptr, digest1);
} else {
@@ -652,7 +656,8 @@
uint8_t iv[16] = {};
CRYPT_AESSetIV(&aes, iv);
CRYPT_AESEncrypt(&aes, digest1, m_EncryptKey.data(), m_EncryptKey.size());
- pEncryptDict->SetNewFor<CPDF_String>("UE", ByteString(digest1, 32));
+ pEncryptDict->SetNewFor<CPDF_String>(
+ "UE", UNSAFE_TODO(ByteString::Create(digest1, 32)));
}
void CPDF_SecurityHandler::AES256_SetPerms(CPDF_Dictionary* pEncryptDict) {
@@ -683,7 +688,8 @@
uint8_t buf1[16];
CRYPT_AESEncrypt(&aes, buf1, buf, 16);
- pEncryptDict->SetNewFor<CPDF_String>("Perms", ByteString(buf1, 16));
+ pEncryptDict->SetNewFor<CPDF_String>(
+ "Perms", UNSAFE_TODO(ByteString::Create(buf1, 16)));
}
void CPDF_SecurityHandler::InitCryptoHandler() {
diff --git a/core/fpdfapi/parser/cpdf_stream_acc.cpp b/core/fpdfapi/parser/cpdf_stream_acc.cpp
index 896f36e..1658a01 100644
--- a/core/fpdfapi/parser/cpdf_stream_acc.cpp
+++ b/core/fpdfapi/parser/cpdf_stream_acc.cpp
@@ -88,7 +88,7 @@
uint8_t digest[20];
pdfium::span<const uint8_t> span = GetSpan();
CRYPT_SHA1Generate(span.data(), span.size(), digest);
- return ByteString(digest, 20);
+ return UNSAFE_TODO(ByteString::Create(digest, 20));
}
DataVector<uint8_t> CPDF_StreamAcc::DetachData() {
diff --git a/core/fpdfapi/parser/cpdf_syntax_parser.cpp b/core/fpdfapi/parser/cpdf_syntax_parser.cpp
index 4cdd669..8e0c452 100644
--- a/core/fpdfapi/parser/cpdf_syntax_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_syntax_parser.cpp
@@ -471,7 +471,7 @@
WordType word_type = GetNextWordInternal();
ByteString word;
if (!GetValidator()->has_read_problems())
- word = ByteString(m_WordBuffer.data(), m_WordSize);
+ word = UNSAFE_TODO(ByteString::Create(m_WordBuffer.data(), m_WordSize));
return {word, word_type == WordType::kNumber};
}
diff --git a/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp b/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp
index f416aac..92d4356 100644
--- a/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp
+++ b/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp
@@ -40,7 +40,8 @@
// Converts a string literal into a `ByteString`.
template <size_t N>
ByteString ToByteString(const char (&array)[N]) {
- return ByteString(array, N - 1);
+ // SAFETY: compiler correctly infers size.
+ return UNSAFE_BUFFERS(ByteString::Create(array, N - 1));
}
} // namespace
diff --git a/core/fpdfdoc/cpdf_annotlist_unittest.cpp b/core/fpdfdoc/cpdf_annotlist_unittest.cpp
index e15c110..469f766 100644
--- a/core/fpdfdoc/cpdf_annotlist_unittest.cpp
+++ b/core/fpdfdoc/cpdf_annotlist_unittest.cpp
@@ -19,6 +19,7 @@
#include "core/fpdfapi/parser/cpdf_test_document.h"
#include "core/fpdfdoc/cpdf_annot.h"
#include "core/fxcrt/bytestring.h"
+#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/retain_ptr.h"
#include "core/fxcrt/widestring.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -56,7 +57,8 @@
};
ByteString MakeByteString(std::initializer_list<uint8_t> bytes) {
- return ByteString(std::data(bytes), std::size(bytes));
+ // SAFETY: compiler determines size of initializer_list.
+ return UNSAFE_BUFFERS(ByteString::Create(std::data(bytes), std::size(bytes)));
}
ByteString GetRawContents(const CPDF_Annot* annotation) {
diff --git a/core/fxcrt/bytestring.h b/core/fxcrt/bytestring.h
index 498b454..54b29e8 100644
--- a/core/fxcrt/bytestring.h
+++ b/core/fxcrt/bytestring.h
@@ -14,6 +14,7 @@
#include <iosfwd>
#include <utility>
+#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/fx_string_wrappers.h"
#include "core/fxcrt/string_template.h"
@@ -28,6 +29,14 @@
[[nodiscard]] static ByteString Format(const char* pFormat, ...);
[[nodiscard]] static ByteString FormatV(const char* pFormat, va_list argList);
+ // Make public when compiler enforces UNSAFE_BUFFER_USAGE on ctors.
+ UNSAFE_BUFFER_USAGE static ByteString Create(const char* str, size_t len) {
+ return UNSAFE_BUFFERS(ByteString(str, len));
+ }
+ UNSAFE_BUFFER_USAGE static ByteString Create(const uint8_t* str, size_t len) {
+ return UNSAFE_BUFFERS(ByteString(str, len));
+ }
+
ByteString() = default;
ByteString(const ByteString& other) = default;
@@ -47,9 +56,6 @@
// NOLINTNEXTLINE(runtime/explicit)
ByteString(wchar_t) = delete;
- ByteString(const char* pStr, size_t len);
- ByteString(const uint8_t* pStr, size_t len);
-
explicit ByteString(ByteStringView bstrc);
ByteString(ByteStringView str1, ByteStringView str2);
ByteString(const std::initializer_list<ByteStringView>& list);
@@ -98,6 +104,10 @@
uint32_t GetID() const { return AsStringView().GetID(); }
protected:
+ // Make public when compiler enforces UNSAFE_BUFFER_USAGE on ctors.
+ UNSAFE_BUFFER_USAGE ByteString(const char* pStr, size_t len);
+ UNSAFE_BUFFER_USAGE ByteString(const uint8_t* pStr, size_t len);
+
intptr_t ReferenceCountForTesting() const;
friend class ByteString_Assign_Test;
diff --git a/core/fxcrt/bytestring_unittest.cpp b/core/fxcrt/bytestring_unittest.cpp
index c2b84e6..4265bd5 100644
--- a/core/fxcrt/bytestring_unittest.cpp
+++ b/core/fxcrt/bytestring_unittest.cpp
@@ -12,6 +12,7 @@
#include <set>
#include <vector>
+#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/containers/contains.h"
#include "core/fxcrt/fx_string.h"
#include "core/fxcrt/span.h"
@@ -1886,7 +1887,7 @@
stream << "abc" << str << "ghi";
EXPECT_EQ("abc123ghi", stream.str());
- char stringWithNulls[]{'x', 'y', '\0', 'z'};
+ char stringWithNulls[] = {'x', 'y', '\0', 'z'};
// Writing a ByteString with nulls and no specified length treats it as
// a C-style null-terminated string.
@@ -1898,7 +1899,7 @@
// Writing a ByteString with nulls but specifying its length treats it as
// a C++-style string.
- str = ByteString(stringWithNulls, 4);
+ str = UNSAFE_TODO(ByteString::Create(stringWithNulls, 4));
EXPECT_EQ(4u, str.GetLength());
stream.str("");
stream << str;
diff --git a/core/fxcrt/fx_string_unittest.cpp b/core/fxcrt/fx_string_unittest.cpp
index d2cf265..18a6e12 100644
--- a/core/fxcrt/fx_string_unittest.cpp
+++ b/core/fxcrt/fx_string_unittest.cpp
@@ -430,7 +430,7 @@
TEST(fxstring, ByteStringSplitEfficiency) {
std::vector<char> commas(50000, ',');
- ByteString input(commas.data(), commas.size());
+ auto input = ByteString(ByteStringView(commas));
std::vector<ByteString> result;
result = fxcrt::Split(input, ',');
ASSERT_EQ(commas.size() + 1, result.size());
diff --git a/core/fxcrt/widestring_unittest.cpp b/core/fxcrt/widestring_unittest.cpp
index 727ffc4..bd696dc 100644
--- a/core/fxcrt/widestring_unittest.cpp
+++ b/core/fxcrt/widestring_unittest.cpp
@@ -1250,10 +1250,11 @@
WideString out;
} const utf16be_decode_cases[] = {
{"", L""},
- {ByteString("\0a\0b\0c", 6), L"abc"},
- {ByteString("\0a\0b\0c\0\0\0d\0e\0f", 14), WideString(L"abc\0def", 7)},
- {ByteString(" &", 2), L"…"},
- {ByteString("\xD8\x3C\xDF\xA8", 4), L"🎨"},
+ {UNSAFE_BUFFERS(ByteString::Create("\0a\0b\0c", 6)), L"abc"},
+ {UNSAFE_BUFFERS(ByteString::Create("\0a\0b\0c\0\0\0d\0e\0f", 14)),
+ WideString(L"abc\0def", 7)},
+ {UNSAFE_BUFFERS(ByteString::Create(" &", 2)), L"…"},
+ {UNSAFE_BUFFERS(ByteString::Create("\xD8\x3C\xDF\xA8", 4)), L"🎨"},
};
UNSAFE_TODO({
for (size_t i = 0; i < std::size(utf16be_decode_cases); ++i) {
@@ -1270,11 +1271,13 @@
ByteString in;
WideString out;
} const utf16le_decode_cases[] = {
+ // SAFETY: not required, control sizes for test.
{"", L""},
- {ByteString("a\0b\0c\0", 6), L"abc"},
- {ByteString("a\0b\0c\0\0\0d\0e\0f\0", 14), WideString(L"abc\0def", 7)},
- {ByteString("& ", 2), L"…"},
- {ByteString("\x3C\xD8\xA8\xDF", 4), L"🎨"},
+ {UNSAFE_BUFFERS(ByteString::Create("a\0b\0c\0", 6)), L"abc"},
+ {UNSAFE_BUFFERS(ByteString::Create("a\0b\0c\0\0\0d\0e\0f\0", 14)),
+ WideString(L"abc\0def", 7)},
+ {UNSAFE_BUFFERS(ByteString::Create("& ", 2)), L"…"},
+ {UNSAFE_BUFFERS(ByteString::Create("\x3C\xD8\xA8\xDF", 4)), L"🎨"},
};
UNSAFE_TODO({
for (size_t i = 0; i < std::size(utf16le_decode_cases); ++i) {
@@ -1291,13 +1294,16 @@
WideString ws;
ByteString bs;
} const utf16le_encode_cases[] = {
- {L"", ByteString("\0\0", 2)},
- {L"abc", ByteString("a\0b\0c\0\0\0", 8)},
- {L"abcdef", ByteString("a\0b\0c\0d\0e\0f\0\0\0", 14)},
- {L"abc\0def", ByteString("a\0b\0c\0\0\0", 8)},
- {L"\xaabb\xccdd", ByteString("\xbb\xaa\xdd\xcc\0\0", 6)},
- {L"\x3132\x6162", ByteString("\x32\x31\x62\x61\0\0", 6)},
- {L"🎨", ByteString("\x3C\xD8\xA8\xDF\0\0", 6)},
+ {L"", UNSAFE_TODO(ByteString::Create("\0\0", 2))},
+ {L"abc", UNSAFE_TODO(ByteString::Create("a\0b\0c\0\0\0", 8))},
+ {L"abcdef",
+ UNSAFE_TODO(ByteString::Create("a\0b\0c\0d\0e\0f\0\0\0", 14))},
+ {L"abc\0def", UNSAFE_TODO(ByteString::Create("a\0b\0c\0\0\0", 8))},
+ {L"\xaabb\xccdd",
+ UNSAFE_TODO(ByteString::Create("\xbb\xaa\xdd\xcc\0\0", 6))},
+ {L"\x3132\x6162",
+ UNSAFE_TODO(ByteString::Create("\x32\x31\x62\x61\0\0", 6))},
+ {L"🎨", UNSAFE_TODO(ByteString::Create("\x3C\xD8\xA8\xDF\0\0", 6))},
};
UNSAFE_TODO({
for (size_t i = 0; i < std::size(utf16le_encode_cases); ++i) {
@@ -1313,14 +1319,17 @@
WideString ws;
ByteString bs;
} const ucs2le_encode_cases[] = {
- {L"", ByteString("\0\0", 2)},
- {L"abc", ByteString("a\0b\0c\0\0\0", 8)},
- {L"abcdef", ByteString("a\0b\0c\0d\0e\0f\0\0\0", 14)},
- {L"abc\0def", ByteString("a\0b\0c\0\0\0", 8)},
- {L"\xaabb\xccdd", ByteString("\xbb\xaa\xdd\xcc\0\0", 6)},
- {L"\x3132\x6162", ByteString("\x32\x31\x62\x61\0\0", 6)},
+ {L"", UNSAFE_TODO(ByteString::Create("\0\0", 2))},
+ {L"abc", UNSAFE_TODO(ByteString::Create("a\0b\0c\0\0\0", 8))},
+ {L"abcdef",
+ UNSAFE_TODO(ByteString::Create("a\0b\0c\0d\0e\0f\0\0\0", 14))},
+ {L"abc\0def", UNSAFE_TODO(ByteString::Create("a\0b\0c\0\0\0", 8))},
+ {L"\xaabb\xccdd",
+ UNSAFE_TODO(ByteString::Create("\xbb\xaa\xdd\xcc\0\0", 6))},
+ {L"\x3132\x6162",
+ UNSAFE_TODO(ByteString::Create("\x32\x31\x62\x61\0\0", 6))},
#if defined(WCHAR_T_IS_32_BIT)
- {L"🎨", ByteString("\0\0", 2)},
+ {L"🎨", UNSAFE_TODO(ByteString::Create("\0\0", 2))},
#endif
};
UNSAFE_TODO({
diff --git a/core/fxge/cfx_glyphcache.cpp b/core/fxge/cfx_glyphcache.cpp
index 5ce2be9..d5c92b8 100644
--- a/core/fxge/cfx_glyphcache.cpp
+++ b/core/fxge/cfx_glyphcache.cpp
@@ -161,7 +161,8 @@
const bool bNative = false;
#endif
GenKey(&keygen, pFont, matrix, dest_width, anti_alias, bNative);
- ByteString FaceGlyphsKey(keygen.key_, keygen.key_len_);
+ auto FaceGlyphsKey =
+ UNSAFE_TODO(ByteString::Create(keygen.key_, keygen.key_len_));
#if BUILDFLAG(IS_APPLE)
const bool bDoLookUp =
@@ -206,7 +207,8 @@
}
}
GenKey(&keygen, pFont, matrix, dest_width, anti_alias, /*bNative=*/false);
- ByteString FaceGlyphsKey2(keygen.key_, keygen.key_len_);
+ auto FaceGlyphsKey2 =
+ UNSAFE_TODO(ByteString::Create(keygen.key_, keygen.key_len_));
text_options->native_text = false;
return LookUpGlyphBitmap(pFont, matrix, FaceGlyphsKey2, glyph_index,
bFontStyle, dest_width, anti_alias);
diff --git a/core/fxge/fx_font.cpp b/core/fxge/fx_font.cpp
index 5c9d1b4..36ed33c 100644
--- a/core/fxge/fx_font.cpp
+++ b/core/fxge/fx_font.cpp
@@ -29,8 +29,7 @@
if (string_span.size() < static_cast<uint32_t>(offset + length))
return ByteString();
- string_span = string_span.subspan(offset, length);
- return ByteString(string_span.data(), string_span.size());
+ return ByteString(ByteStringView(string_span.subspan(offset, length)));
}
} // namespace
diff --git a/fpdfsdk/fpdf_sysfontinfo.cpp b/fpdfsdk/fpdf_sysfontinfo.cpp
index 453d4be..265a70b 100644
--- a/fpdfsdk/fpdf_sysfontinfo.cpp
+++ b/fpdfsdk/fpdf_sysfontinfo.cpp
@@ -126,7 +126,7 @@
return false;
char* buffer = FX_Alloc(char, size);
size = m_pInfo->GetFaceName(m_pInfo, hFont, buffer, size);
- *name = ByteString(buffer, size);
+ *name = UNSAFE_TODO(ByteString::Create(buffer, size));
FX_Free(buffer);
return true;
}
diff --git a/fxjs/cfx_globaldata.cpp b/fxjs/cfx_globaldata.cpp
index 735eee4..27fcb4b 100644
--- a/fxjs/cfx_globaldata.cpp
+++ b/fxjs/cfx_globaldata.cpp
@@ -308,7 +308,7 @@
break;
}
- ByteString sEntry = ByteString(p, dwNameLen);
+ ByteString sEntry = ByteString::Create(p, dwNameLen);
p += sizeof(char) * dwNameLen;
uint16_t wDataType = 0;
@@ -351,8 +351,7 @@
if (p + dwLength > buffer.end()) {
break;
}
-
- SetGlobalVariableString(sEntry, ByteString(p, dwLength));
+ SetGlobalVariableString(sEntry, ByteString::Create(p, dwLength));
SetGlobalVariablePersistent(sEntry, true);
p += sizeof(char) * dwLength;
} break;
diff --git a/fxjs/cjs_publicmethods.cpp b/fxjs/cjs_publicmethods.cpp
index c09930c..162abe5 100644
--- a/fxjs/cjs_publicmethods.cpp
+++ b/fxjs/cjs_publicmethods.cpp
@@ -343,7 +343,7 @@
pRuntime->PutArrayElement(
StrArray, nIndex,
pRuntime->NewString(
- StrTrim(ByteString(p, pTemp - p)).AsStringView()));
+ StrTrim(ByteString::Create(p, pTemp - p)).AsStringView()));
nIndex++;
p = ++pTemp;
diff --git a/fxjs/fxv8.cpp b/fxjs/fxv8.cpp
index 95b0dfe..7993b5c 100644
--- a/fxjs/fxv8.cpp
+++ b/fxjs/fxv8.cpp
@@ -128,7 +128,8 @@
ByteString ToByteString(v8::Isolate* pIsolate, v8::Local<v8::String> pValue) {
v8::String::Utf8Value s(pIsolate, pValue);
- return ByteString(*s, s.length());
+ // SAFETY: required from V8.
+ return UNSAFE_BUFFERS(ByteString::Create(*s, s.length()));
}
int ReentrantToInt32Helper(v8::Isolate* pIsolate, v8::Local<v8::Value> pValue) {
diff --git a/fxjs/xfa/cfxjse_formcalc_context_embeddertest.cpp b/fxjs/xfa/cfxjse_formcalc_context_embeddertest.cpp
index 4f5f174..47939fb 100644
--- a/fxjs/xfa/cfxjse_formcalc_context_embeddertest.cpp
+++ b/fxjs/xfa/cfxjse_formcalc_context_embeddertest.cpp
@@ -6,6 +6,7 @@
#include <algorithm>
+#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/fx_extension.h"
#include "fxjs/fxv8.h"
#include "fxjs/xfa/cfxjse_engine.h"
@@ -761,7 +762,8 @@
const uint8_t test_string[] = {
0x4c, 0x6f, 0x77, 0x65, 0x72, 0x28, 0x22, 0xc3,
0x85, 0xc3, 0x85, 0xc3, 0x85, 0x22, 0x29}; // Lower("ÅÅÅ")
- Execute(ByteString(test_string, sizeof(test_string)).AsStringView());
+ Execute(UNSAFE_TODO(ByteString::Create(test_string, sizeof(test_string)))
+ .AsStringView());
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Ltrim) {