Replace 3-parameter CPDF_String ctor
Replace the 3-parameter CPDF_String ctor with a different 3-parameter
ctor that takes a span<const uint8_t> and a placeholder. Update callers
to use some kind of a uint8_t data container instead of stuffing the
data into a ByteString.
Change-Id: I168d1e4b42bbf804758f65ecfead23097a8526c5
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/119372
Reviewed-by: Thomas Sepez <tsepez@google.com>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/edit/cpdf_creator.cpp b/core/fpdfapi/edit/cpdf_creator.cpp
index 000df08..dfcfa7e 100644
--- a/core/fpdfapi/edit/cpdf_creator.cpp
+++ b/core/fpdfapi/edit/cpdf_creator.cpp
@@ -9,6 +9,7 @@
#include <stdint.h>
#include <algorithm>
+#include <array>
#include <set>
#include <utility>
@@ -95,17 +96,15 @@
return true;
}
-ByteString GenerateFileID(uint32_t dwSeed1, uint32_t dwSeed2) {
- uint32_t buffer[4];
+std::array<uint32_t, 4> GenerateFileID(uint32_t dwSeed1, uint32_t dwSeed2) {
void* pContext1 = FX_Random_MT_Start(dwSeed1);
void* pContext2 = FX_Random_MT_Start(dwSeed2);
- buffer[0] = FX_Random_MT_Generate(pContext1);
- buffer[1] = FX_Random_MT_Generate(pContext1);
- buffer[2] = FX_Random_MT_Generate(pContext2);
- buffer[3] = FX_Random_MT_Generate(pContext2);
+ std::array<uint32_t, 4> buffer = {
+ FX_Random_MT_Generate(pContext1), FX_Random_MT_Generate(pContext1),
+ FX_Random_MT_Generate(pContext2), FX_Random_MT_Generate(pContext2)};
FX_Random_MT_Close(pContext1);
FX_Random_MT_Close(pContext2);
- return ByteString(ByteStringView(pdfium::as_byte_span(buffer)));
+ return buffer;
}
bool OutputIndex(IFX_ArchiveStream* archive, FX_FILESIZE offset) {
@@ -570,9 +569,11 @@
if (pID1) {
m_pIDArray->Append(pID1->Clone());
} else {
- ByteString bsBuffer =
+ std::array<uint32_t, 4> file_id =
GenerateFileID((uint32_t)(uintptr_t)this, m_dwLastObjNum);
- m_pIDArray->AppendNew<CPDF_String>(bsBuffer, true);
+ m_pIDArray->AppendNew<CPDF_String>(
+ pdfium::as_bytes(pdfium::make_span(file_id)),
+ CPDF_String::DataType::kIsHex);
}
if (pOldIDArray) {
@@ -581,9 +582,11 @@
m_pIDArray->Append(pID2->Clone());
return;
}
- ByteString bsBuffer =
+ std::array<uint32_t, 4> file_id =
GenerateFileID((uint32_t)(uintptr_t)this, m_dwLastObjNum);
- m_pIDArray->AppendNew<CPDF_String>(bsBuffer, true);
+ m_pIDArray->AppendNew<CPDF_String>(
+ pdfium::as_bytes(pdfium::make_span(file_id)),
+ CPDF_String::DataType::kIsHex);
return;
}
diff --git a/core/fpdfapi/page/cpdf_image.cpp b/core/fpdfapi/page/cpdf_image.cpp
index a5e5552..35361a6 100644
--- a/core/fpdfapi/page/cpdf_image.cpp
+++ b/core/fpdfapi/page/cpdf_image.cpp
@@ -4,16 +4,12 @@
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-#if defined(UNSAFE_BUFFERS_BUILD)
-// TODO(crbug.com/pdfium/2154): resolve buffer safety issues.
-#pragma allow_unsafe_buffers
-#endif
-
#include "core/fpdfapi/page/cpdf_image.h"
#include <stdint.h>
#include <algorithm>
+#include <array>
#include <memory>
#include <utility>
@@ -224,19 +220,11 @@
pCS->AppendNew<CPDF_Name>("Indexed");
pCS->AppendNew<CPDF_Name>("DeviceRGB");
pCS->AppendNew<CPDF_Number>(1);
- ByteString ct;
- {
- // Span's lifetime must end before ReleaseBuffer() below.
- pdfium::span<char> pBuf = ct.GetBuffer(6);
- pBuf[0] = static_cast<char>(reset_r);
- pBuf[1] = static_cast<char>(reset_g);
- pBuf[2] = static_cast<char>(reset_b);
- pBuf[3] = static_cast<char>(set_r);
- pBuf[4] = static_cast<char>(set_g);
- pBuf[5] = static_cast<char>(set_b);
- }
- ct.ReleaseBuffer(6);
- pCS->AppendNew<CPDF_String>(ct, true);
+ uint8_t ct[6] = {
+ static_cast<uint8_t>(reset_r), static_cast<uint8_t>(reset_g),
+ static_cast<uint8_t>(reset_b), static_cast<uint8_t>(set_r),
+ static_cast<uint8_t>(set_g), static_cast<uint8_t>(set_b)};
+ pCS->AppendNew<CPDF_String>(ct, CPDF_String::DataType::kIsHex);
}
pDict->SetNewFor<CPDF_Number>("BitsPerComponent", 1);
dest_pitch = (BitmapWidth + 7) / 8;
@@ -317,11 +305,13 @@
uint8_t* dest_ptr = dest_span.data();
const uint8_t* src_ptr = src_span.data();
for (int32_t column = 0; column < BitmapWidth; column++) {
- dest_ptr[0] = src_ptr[2];
- dest_ptr[1] = src_ptr[1];
- dest_ptr[2] = src_ptr[0];
- dest_ptr += 3;
- src_ptr += src_step;
+ UNSAFE_TODO({
+ dest_ptr[0] = src_ptr[2];
+ dest_ptr[1] = src_ptr[1];
+ dest_ptr[2] = src_ptr[0];
+ dest_ptr += 3;
+ src_ptr += src_step;
+ })
}
dest_span = dest_span.subspan(dest_pitch);
src_span = src_span.subspan(src_pitch);
diff --git a/core/fpdfapi/page/cpdf_streamparser.cpp b/core/fpdfapi/page/cpdf_streamparser.cpp
index ec003a5..442ec80 100644
--- a/core/fpdfapi/page/cpdf_streamparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamparser.cpp
@@ -327,13 +327,13 @@
}
if (first_char == '(') {
- ByteString str = ReadString();
- return pdfium::MakeRetain<CPDF_String>(m_pPool, str);
+ return pdfium::MakeRetain<CPDF_String>(m_pPool, ReadString());
}
if (first_char == '<') {
if (m_WordSize == 1) {
- return pdfium::MakeRetain<CPDF_String>(m_pPool, ReadHexString(), true);
+ return pdfium::MakeRetain<CPDF_String>(m_pPool, ReadHexString(),
+ CPDF_String::DataType::kIsHex);
}
auto pDict = pdfium::MakeRetain<CPDF_Dictionary>(m_pPool);
@@ -552,13 +552,15 @@
}
}
-ByteString CPDF_StreamParser::ReadHexString() {
- if (!PositionIsInBounds())
- return ByteString();
+DataVector<uint8_t> CPDF_StreamParser::ReadHexString() {
+ if (!PositionIsInBounds()) {
+ return DataVector<uint8_t>();
+ }
- ByteString buf;
+ // TODO(thestig): Deduplicate CPDF_SyntaxParser::ReadHexString()?
+ DataVector<uint8_t> buf;
bool bFirst = true;
- int code = 0;
+ uint8_t code = 0;
while (PositionIsInBounds()) {
uint8_t ch = m_pBuf[m_Pos++];
if (ch == '>')
@@ -572,14 +574,18 @@
code = val * 16;
} else {
code += val;
- buf += static_cast<uint8_t>(code);
+ buf.push_back(code);
}
bFirst = !bFirst;
}
- if (!bFirst)
- buf += static_cast<char>(code);
+ if (!bFirst) {
+ buf.push_back(code);
+ }
- return buf.First(std::min<size_t>(buf.GetLength(), kMaxStringLength));
+ if (buf.size() > kMaxStringLength) {
+ buf.resize(kMaxStringLength);
+ }
+ return buf;
}
bool CPDF_StreamParser::PositionIsInBounds() const {
diff --git a/core/fpdfapi/page/cpdf_streamparser.h b/core/fpdfapi/page/cpdf_streamparser.h
index 50f7d65..b6ad7d7 100644
--- a/core/fpdfapi/page/cpdf_streamparser.h
+++ b/core/fpdfapi/page/cpdf_streamparser.h
@@ -7,6 +7,9 @@
#ifndef CORE_FPDFAPI_PAGE_CPDF_STREAMPARSER_H_
#define CORE_FPDFAPI_PAGE_CPDF_STREAMPARSER_H_
+#include <stdint.h>
+
+#include "core/fxcrt/data_vector.h"
#include "core/fxcrt/raw_span.h"
#include "core/fxcrt/retain_ptr.h"
#include "core/fxcrt/span.h"
@@ -47,7 +50,7 @@
void GetNextWord(bool& bIsNumber);
ByteString ReadString();
- ByteString ReadHexString();
+ DataVector<uint8_t> ReadHexString();
bool PositionIsInBounds() const;
uint32_t m_Pos = 0; // Current byte position within |m_pBuf|.
diff --git a/core/fpdfapi/page/cpdf_streamparser_unittest.cpp b/core/fpdfapi/page/cpdf_streamparser_unittest.cpp
index c9af44b..f38cd47 100644
--- a/core/fpdfapi/page/cpdf_streamparser_unittest.cpp
+++ b/core/fpdfapi/page/cpdf_streamparser_unittest.cpp
@@ -3,22 +3,26 @@
// found in the LICENSE file.
#include "core/fpdfapi/page/cpdf_streamparser.h"
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+using testing::ElementsAre;
+using testing::IsEmpty;
+
TEST(cpdf_streamparser, ReadHexString) {
{
// Position out of bounds.
uint8_t data[] = "12ab>";
CPDF_StreamParser parser(data);
parser.SetPos(6);
- EXPECT_EQ("", parser.ReadHexString());
+ EXPECT_THAT(parser.ReadHexString(), IsEmpty());
}
{
// Regular conversion.
uint8_t data[] = "1A2b>abcd";
CPDF_StreamParser parser(data);
- EXPECT_EQ("\x1a\x2b", parser.ReadHexString());
+ EXPECT_THAT(parser.ReadHexString(), ElementsAre(0x1a, 0x2b));
EXPECT_EQ(5u, parser.GetPos());
}
@@ -26,7 +30,7 @@
// Missing ending >
uint8_t data[] = "1A2b";
CPDF_StreamParser parser(data);
- EXPECT_EQ("\x1a\x2b", parser.ReadHexString());
+ EXPECT_THAT(parser.ReadHexString(), ElementsAre(0x1a, 0x2b));
EXPECT_EQ(5u, parser.GetPos());
}
@@ -34,14 +38,14 @@
// Uneven number of bytes.
uint8_t data[] = "1A2>asdf";
CPDF_StreamParser parser(data);
- EXPECT_EQ("\x1a\x20", parser.ReadHexString());
+ EXPECT_THAT(parser.ReadHexString(), ElementsAre(0x1a, 0x20));
EXPECT_EQ(4u, parser.GetPos());
}
{
uint8_t data[] = ">";
CPDF_StreamParser parser(data);
- EXPECT_EQ("", parser.ReadHexString());
+ EXPECT_THAT(parser.ReadHexString(), IsEmpty());
EXPECT_EQ(1u, parser.GetPos());
}
}
diff --git a/core/fpdfapi/parser/cpdf_string.cpp b/core/fpdfapi/parser/cpdf_string.cpp
index ca0dd53..ab56541 100644
--- a/core/fpdfapi/parser/cpdf_string.cpp
+++ b/core/fpdfapi/parser/cpdf_string.cpp
@@ -17,21 +17,25 @@
CPDF_String::CPDF_String() = default;
-CPDF_String::CPDF_String(WeakPtr<ByteStringPool> pPool, const ByteString& str)
- : CPDF_String(pPool, str, false) {}
-
CPDF_String::CPDF_String(WeakPtr<ByteStringPool> pPool,
- const ByteString& str,
- bool bHex)
- : m_String(str), m_bHex(bHex) {
- if (pPool)
+ pdfium::span<const uint8_t> data,
+ DataType is_hex)
+ : m_String(ByteStringView(data)), m_bHex(true) {
+ if (pPool) {
m_String = pPool->Intern(m_String);
+ }
+}
+
+CPDF_String::CPDF_String(WeakPtr<ByteStringPool> pPool, const ByteString& str)
+ : m_String(str) {
+ if (pPool) {
+ m_String = pPool->Intern(m_String);
+ }
}
CPDF_String::CPDF_String(WeakPtr<ByteStringPool> pPool, WideStringView str)
- : m_String(PDF_EncodeText(str)) {
- if (pPool)
- m_String = pPool->Intern(m_String);
+ : CPDF_String(pPool, PDF_EncodeText(str)) {
+ // Delegates to ctor above.
}
CPDF_String::~CPDF_String() = default;
diff --git a/core/fpdfapi/parser/cpdf_string.h b/core/fpdfapi/parser/cpdf_string.h
index 3b70d37..aa6af77 100644
--- a/core/fpdfapi/parser/cpdf_string.h
+++ b/core/fpdfapi/parser/cpdf_string.h
@@ -10,6 +10,7 @@
#include "core/fpdfapi/parser/cpdf_object.h"
#include "core/fxcrt/fx_string.h"
#include "core/fxcrt/retain_ptr.h"
+#include "core/fxcrt/span.h"
#include "core/fxcrt/string_pool_template.h"
#include "core/fxcrt/weak_ptr.h"
@@ -17,6 +18,9 @@
public:
CONSTRUCT_VIA_MAKE_RETAIN;
+ // Used as a placeholder to differentiate constructors.
+ enum class DataType { kIsHex };
+
// CPDF_Object:
Type GetType() const override;
RetainPtr<CPDF_Object> Clone() const override;
@@ -32,9 +36,10 @@
private:
CPDF_String();
- // Same as the 3-param ctor, with `bHex` set to false.
+ CPDF_String(WeakPtr<ByteStringPool> pPool,
+ pdfium::span<const uint8_t> data,
+ DataType is_hex);
CPDF_String(WeakPtr<ByteStringPool> pPool, const ByteString& str);
- CPDF_String(WeakPtr<ByteStringPool> pPool, const ByteString& str, bool bHex);
CPDF_String(WeakPtr<ByteStringPool> pPool, WideStringView str);
~CPDF_String() override;
diff --git a/core/fpdfapi/parser/cpdf_syntax_parser.cpp b/core/fpdfapi/parser/cpdf_syntax_parser.cpp
index bfddc14..4cdd669 100644
--- a/core/fpdfapi/parser/cpdf_syntax_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_syntax_parser.cpp
@@ -28,6 +28,7 @@
#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/fixed_size_data_vector.h"
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_memcpy_wrappers.h"
@@ -321,12 +322,13 @@
return buf;
}
-ByteString CPDF_SyntaxParser::ReadHexString() {
+DataVector<uint8_t> CPDF_SyntaxParser::ReadHexString() {
uint8_t ch;
- if (!GetNextChar(ch))
- return ByteString();
+ if (!GetNextChar(ch)) {
+ return DataVector<uint8_t>();
+ }
- ByteString buf;
+ DataVector<uint8_t> buf;
bool bFirst = true;
uint8_t code = 0;
while (true) {
@@ -339,16 +341,18 @@
code = val * 16;
} else {
code += val;
- buf += static_cast<char>(code);
+ buf.push_back(code);
}
bFirst = !bFirst;
}
- if (!GetNextChar(ch))
+ if (!GetNextChar(ch)) {
break;
+ }
}
- if (!bFirst)
- buf += static_cast<char>(code);
+ if (!bFirst) {
+ buf.push_back(code);
+ }
return buf;
}
@@ -532,12 +536,11 @@
return pdfium::MakeRetain<CPDF_Null>();
if (word == "(") {
- ByteString str = ReadString();
- return pdfium::MakeRetain<CPDF_String>(m_pPool, str);
+ return pdfium::MakeRetain<CPDF_String>(m_pPool, ReadString());
}
if (word == "<") {
- ByteString str = ReadHexString();
- return pdfium::MakeRetain<CPDF_String>(m_pPool, str, true);
+ return pdfium::MakeRetain<CPDF_String>(m_pPool, ReadHexString(),
+ CPDF_String::DataType::kIsHex);
}
if (word == "[") {
auto pArray = pdfium::MakeRetain<CPDF_Array>();
diff --git a/core/fpdfapi/parser/cpdf_syntax_parser.h b/core/fpdfapi/parser/cpdf_syntax_parser.h
index a7fc3f2..42fbb14 100644
--- a/core/fpdfapi/parser/cpdf_syntax_parser.h
+++ b/core/fpdfapi/parser/cpdf_syntax_parser.h
@@ -82,7 +82,7 @@
FX_FILESIZE GetDocumentSize() const;
ByteString ReadString();
- ByteString ReadHexString();
+ DataVector<uint8_t> ReadHexString();
void SetTrailerEnds(std::vector<unsigned int>* trailer_ends) {
m_TrailerEnds = trailer_ends;
diff --git a/core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp b/core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp
index 94e573c..beb3fb7 100644
--- a/core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp
@@ -14,16 +14,20 @@
#include "core/fpdfapi/parser/cpdf_syntax_parser.h"
#include "core/fxcrt/cfx_read_only_span_stream.h"
#include "core/fxcrt/fx_extension.h"
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/utils/path_service.h"
+using testing::ElementsAre;
+using testing::IsEmpty;
+
TEST(SyntaxParserTest, ReadHexString) {
{
// Empty string.
static const uint8_t data[] = "";
CPDF_SyntaxParser parser(pdfium::MakeRetain<CFX_ReadOnlySpanStream>(
pdfium::make_span(data, 0u)));
- EXPECT_EQ("", parser.ReadHexString());
+ EXPECT_THAT(parser.ReadHexString(), IsEmpty());
EXPECT_EQ(0, parser.GetPos());
}
@@ -32,7 +36,7 @@
static const uint8_t data[] = " ";
CPDF_SyntaxParser parser(pdfium::MakeRetain<CFX_ReadOnlySpanStream>(
pdfium::make_span(data, 2u)));
- EXPECT_EQ("", parser.ReadHexString());
+ EXPECT_THAT(parser.ReadHexString(), IsEmpty());
EXPECT_EQ(2, parser.GetPos());
}
@@ -41,7 +45,7 @@
static const uint8_t data[] = "z12b";
CPDF_SyntaxParser parser(pdfium::MakeRetain<CFX_ReadOnlySpanStream>(
pdfium::make_span(data, 4u)));
- EXPECT_EQ("\x12\xb0", parser.ReadHexString());
+ EXPECT_THAT(parser.ReadHexString(), ElementsAre(0x12, 0xb0));
EXPECT_EQ(4, parser.GetPos());
}
@@ -50,7 +54,7 @@
static const uint8_t data[] = "*<&*#$^&@1";
CPDF_SyntaxParser parser(pdfium::MakeRetain<CFX_ReadOnlySpanStream>(
pdfium::make_span(data, 10u)));
- EXPECT_EQ("\x10", parser.ReadHexString());
+ EXPECT_THAT(parser.ReadHexString(), ElementsAre(0x10));
EXPECT_EQ(10, parser.GetPos());
}
@@ -59,7 +63,7 @@
static const uint8_t data[] = "\x80zab";
CPDF_SyntaxParser parser(pdfium::MakeRetain<CFX_ReadOnlySpanStream>(
pdfium::make_span(data, 4u)));
- EXPECT_EQ("\xab", parser.ReadHexString());
+ EXPECT_THAT(parser.ReadHexString(), ElementsAre(0xab));
EXPECT_EQ(4, parser.GetPos());
}
@@ -68,7 +72,7 @@
static const uint8_t data[] = "\xffzab";
CPDF_SyntaxParser parser(pdfium::MakeRetain<CFX_ReadOnlySpanStream>(
pdfium::make_span(data, 4u)));
- EXPECT_EQ("\xab", parser.ReadHexString());
+ EXPECT_THAT(parser.ReadHexString(), ElementsAre(0xab));
EXPECT_EQ(4, parser.GetPos());
}
@@ -77,7 +81,7 @@
static const uint8_t data[] = "1A2b>abcd";
CPDF_SyntaxParser parser(pdfium::MakeRetain<CFX_ReadOnlySpanStream>(
pdfium::make_span(data, 9u)));
- EXPECT_EQ("\x1a\x2b", parser.ReadHexString());
+ EXPECT_THAT(parser.ReadHexString(), ElementsAre(0x1a, 0x2b));
EXPECT_EQ(5, parser.GetPos());
}
@@ -87,17 +91,17 @@
CPDF_SyntaxParser parser(pdfium::MakeRetain<CFX_ReadOnlySpanStream>(
pdfium::make_span(data, 5u)));
parser.SetPos(5);
- EXPECT_EQ("", parser.ReadHexString());
+ EXPECT_THAT(parser.ReadHexString(), IsEmpty());
parser.SetPos(6);
- EXPECT_EQ("", parser.ReadHexString());
+ EXPECT_THAT(parser.ReadHexString(), IsEmpty());
parser.SetPos(std::numeric_limits<FX_FILESIZE>::max());
- EXPECT_EQ("", parser.ReadHexString());
+ EXPECT_THAT(parser.ReadHexString(), IsEmpty());
// Check string still parses when set to 0.
parser.SetPos(0);
- EXPECT_EQ("\x12\xab", parser.ReadHexString());
+ EXPECT_THAT(parser.ReadHexString(), ElementsAre(0x12, 0xab));
}
{
@@ -105,7 +109,7 @@
static const uint8_t data[] = "1A2b";
CPDF_SyntaxParser parser(pdfium::MakeRetain<CFX_ReadOnlySpanStream>(
pdfium::make_span(data, 4u)));
- EXPECT_EQ("\x1a\x2b", parser.ReadHexString());
+ EXPECT_THAT(parser.ReadHexString(), ElementsAre(0x1a, 0x2b));
EXPECT_EQ(4, parser.GetPos());
}
@@ -114,7 +118,7 @@
static const uint8_t data[] = "12abz";
CPDF_SyntaxParser parser(pdfium::MakeRetain<CFX_ReadOnlySpanStream>(
pdfium::make_span(data, 5u)));
- EXPECT_EQ("\x12\xab", parser.ReadHexString());
+ EXPECT_THAT(parser.ReadHexString(), ElementsAre(0x12, 0xab));
EXPECT_EQ(5, parser.GetPos());
}
@@ -123,7 +127,7 @@
static const uint8_t data[] = "1A2>asdf";
CPDF_SyntaxParser parser(pdfium::MakeRetain<CFX_ReadOnlySpanStream>(
pdfium::make_span(data, 8u)));
- EXPECT_EQ("\x1a\x20", parser.ReadHexString());
+ EXPECT_THAT(parser.ReadHexString(), ElementsAre(0x1a, 0x20));
EXPECT_EQ(4, parser.GetPos());
}
@@ -132,7 +136,7 @@
static const uint8_t data[] = "1A2zasdf";
CPDF_SyntaxParser parser(pdfium::MakeRetain<CFX_ReadOnlySpanStream>(
pdfium::make_span(data, 8u)));
- EXPECT_EQ("\x1a\x2a\xdf", parser.ReadHexString());
+ EXPECT_THAT(parser.ReadHexString(), ElementsAre(0x1a, 0x2a, 0xdf));
EXPECT_EQ(8, parser.GetPos());
}
@@ -141,7 +145,7 @@
const char gt = '>';
CPDF_SyntaxParser parser(pdfium::MakeRetain<CFX_ReadOnlySpanStream>(
pdfium::byte_span_from_ref(gt)));
- EXPECT_EQ("", parser.ReadHexString());
+ EXPECT_THAT(parser.ReadHexString(), IsEmpty());
EXPECT_EQ(1, parser.GetPos());
}
}
diff --git a/core/fpdfdoc/cpdf_nametree_unittest.cpp b/core/fpdfdoc/cpdf_nametree_unittest.cpp
index 413c914..0861f10 100644
--- a/core/fpdfdoc/cpdf_nametree_unittest.cpp
+++ b/core/fpdfdoc/cpdf_nametree_unittest.cpp
@@ -107,8 +107,8 @@
auto pNames = pRootDict->SetNewFor<CPDF_Array>("Names");
// Add the key "1" (with BOM) and value 100 into the array.
- constexpr char kData[] = "\xFE\xFF\x00\x31";
- pNames->AppendNew<CPDF_String>(ByteString(kData, sizeof(kData) - 1), true);
+ constexpr uint8_t kData[] = {0xFE, 0xFF, 0x00, 0x31};
+ pNames->AppendNew<CPDF_String>(kData, CPDF_String::DataType::kIsHex);
pNames->AppendNew<CPDF_Number>(100);
// Check that the key is as expected.
diff --git a/fpdfsdk/fpdf_attachment.cpp b/fpdfsdk/fpdf_attachment.cpp
index 89b71f9..ccc2154 100644
--- a/fpdfsdk/fpdf_attachment.cpp
+++ b/fpdfsdk/fpdf_attachment.cpp
@@ -6,6 +6,7 @@
#include <limits.h>
+#include <array>
#include <memory>
#include <utility>
@@ -33,11 +34,6 @@
constexpr char kChecksumKey[] = "CheckSum";
-ByteString CFXByteStringHexDecode(const ByteString& bsHex) {
- DataAndBytesConsumed result = HexDecode(bsHex.unsigned_span());
- return ByteString(ByteStringView(result.data));
-}
-
} // namespace
FPDF_EXPORT int FPDF_CALLCONV
@@ -162,11 +158,13 @@
// SAFETY: required from caller.
ByteString bsValue = UNSAFE_BUFFERS(ByteStringFromFPDFWideString(value));
ByteString bsKey = key;
- bool bEncodedAsHex = bsKey == kChecksumKey;
- if (bEncodedAsHex) {
- bsValue = CFXByteStringHexDecode(bsValue);
+ if (bsKey == kChecksumKey) {
+ pParamsDict->SetNewFor<CPDF_String>(bsKey,
+ HexDecode(bsValue.unsigned_span()).data,
+ CPDF_String::DataType::kIsHex);
+ } else {
+ pParamsDict->SetNewFor<CPDF_String>(bsKey, bsValue);
}
- pParamsDict->SetNewFor<CPDF_String>(bsKey, bsValue, bEncodedAsHex);
return true;
}
@@ -239,15 +237,12 @@
pdfium::span<const uint8_t> contents_span = UNSAFE_BUFFERS(
pdfium::make_span(static_cast<const uint8_t*>(contents), len));
- ByteString digest;
- {
- auto digest_span = pdfium::as_writable_bytes(digest.GetBuffer(16));
- CRYPT_MD5Generate(contents_span, digest_span.data());
- digest.ReleaseBuffer(16);
- }
+ std::array<uint8_t, 16> digest;
+ CRYPT_MD5Generate(contents_span, digest.data());
// Set the checksum of the new attachment in the dictionary.
- pParamsDict->SetNewFor<CPDF_String>(kChecksumKey, digest, /*bHex=*/true);
+ pParamsDict->SetNewFor<CPDF_String>(kChecksumKey, digest,
+ CPDF_String::DataType::kIsHex);
// Create the file stream and have the filespec dictionary link to it.
auto pFileStream = pDoc->NewIndirect<CPDF_Stream>(
diff --git a/fpdfsdk/fpdf_editpage.cpp b/fpdfsdk/fpdf_editpage.cpp
index 49e623a..9ddd89f 100644
--- a/fpdfsdk/fpdf_editpage.cpp
+++ b/fpdfsdk/fpdf_editpage.cpp
@@ -571,20 +571,27 @@
FPDF_BYTESTRING key,
void* value,
unsigned long value_len) {
- CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
- if (!pPageObj || !PageObjectContainsMark(pPageObj, mark))
+ if (!value && value_len > 0) {
return false;
+ }
+
+ CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object);
+ if (!pPageObj || !PageObjectContainsMark(pPageObj, mark)) {
+ return false;
+ }
RetainPtr<CPDF_Dictionary> pParams =
GetOrCreateMarkParamsDict(document, mark);
- if (!pParams)
+ if (!pParams) {
return false;
+ }
- if (!value && value_len > 0)
- return false;
-
+ // SAFETY: required from caller.
pParams->SetNewFor<CPDF_String>(
- key, ByteString(static_cast<const char*>(value), value_len), true);
+ key,
+ UNSAFE_BUFFERS(
+ pdfium::make_span(static_cast<const uint8_t*>(value), value_len)),
+ CPDF_String::DataType::kIsHex);
pPageObj->SetDirty(true);
return true;
}