Remove out-parameters from more codec decoding functions
Convert to using DataAndBytesConsumed.
Change-Id: Ic93ccdf9fcad7016449a0d5d1fbd4f5f1ecd8f55
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/119172
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Thomas Sepez <tsepez@google.com>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/page/cpdf_streamparser.cpp b/core/fpdfapi/page/cpdf_streamparser.cpp
index 1086371..d0bc3a9 100644
--- a/core/fpdfapi/page/cpdf_streamparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamparser.cpp
@@ -103,8 +103,6 @@
/*estimated_size=*/0)
.bytes_consumed;
}
- std::unique_ptr<uint8_t, FxFreeDeleter> ignored_result;
- uint32_t ignored_size;
if (decoder == "DCTDecode") {
std::unique_ptr<ScanlineDecoder> pDecoder = JpegModule::CreateDecoder(
src_span, width, height, 0,
@@ -117,12 +115,15 @@
return DecodeAllScanlines(std::move(pDecoder));
}
- if (decoder == "ASCII85Decode")
- return A85Decode(src_span, &ignored_result, &ignored_size);
- if (decoder == "ASCIIHexDecode")
- return HexDecode(src_span, &ignored_result, &ignored_size);
- if (decoder == "RunLengthDecode")
- return RunLengthDecode(src_span, &ignored_result, &ignored_size);
+ if (decoder == "ASCII85Decode") {
+ return A85Decode(src_span).bytes_consumed;
+ }
+ if (decoder == "ASCIIHexDecode") {
+ return HexDecode(src_span).bytes_consumed;
+ }
+ if (decoder == "RunLengthDecode") {
+ return RunLengthDecode(src_span).bytes_consumed;
+ }
return FX_INVALID_OFFSET;
}
diff --git a/core/fpdfapi/parser/BUILD.gn b/core/fpdfapi/parser/BUILD.gn
index e3152d8..e331793 100644
--- a/core/fpdfapi/parser/BUILD.gn
+++ b/core/fpdfapi/parser/BUILD.gn
@@ -137,6 +137,7 @@
":parser",
":unit_test_support",
"../../../constants",
+ "../../fxcodec",
"../page",
"../page:unit_test_support",
"../render",
diff --git a/core/fpdfapi/parser/fpdf_parser_decode.cpp b/core/fpdfapi/parser/fpdf_parser_decode.cpp
index c6dc9b2..e9c1f8d 100644
--- a/core/fpdfapi/parser/fpdf_parser_decode.cpp
+++ b/core/fpdfapi/parser/fpdf_parser_decode.cpp
@@ -29,6 +29,7 @@
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_memcpy_wrappers.h"
#include "core/fxcrt/fx_safe_types.h"
+#include "core/fxcrt/numerics/safe_conversions.h"
#include "core/fxcrt/span.h"
#include "core/fxcrt/span_util.h"
#include "core/fxcrt/utf16.h"
@@ -113,13 +114,9 @@
return true;
}
-uint32_t A85Decode(pdfium::span<const uint8_t> src_span,
- std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
- uint32_t* dest_size) {
- *dest_size = 0;
+DataAndBytesConsumed A85Decode(pdfium::span<const uint8_t> src_span) {
if (src_span.empty()) {
- dest_buf->reset();
- return 0;
+ return {nullptr, 0u, 0u};
}
// Count legal characters and zeros.
@@ -136,8 +133,9 @@
pos++;
}
// No content to decode.
- if (pos == 0)
- return 0;
+ if (pos == 0) {
+ return {nullptr, 0u, 0u};
+ }
// Count the space needed to contain non-zero characters. The encoding ratio
// of Ascii85 is 4:5.
@@ -145,30 +143,35 @@
FX_SAFE_UINT32 size = zcount;
size *= 4;
size += space_for_non_zeroes;
- if (!size.IsValid())
- return FX_INVALID_OFFSET;
+ if (!size.IsValid()) {
+ return {nullptr, 0u, FX_INVALID_OFFSET};
+ }
- dest_buf->reset(FX_Alloc(uint8_t, size.ValueOrDie()));
- uint8_t* dest_buf_ptr = dest_buf->get();
+ std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf(
+ FX_Alloc(uint8_t, size.ValueOrDie()));
+ uint8_t* dest_buf_ptr = dest_buf.get();
+ uint32_t dest_size = 0;
size_t state = 0;
uint32_t res = 0;
pos = 0;
while (pos < src_span.size()) {
uint8_t ch = src_span[pos++];
- if (PDFCharIsLineEnding(ch) || ch == ' ' || ch == '\t')
+ if (PDFCharIsLineEnding(ch) || ch == ' ' || ch == '\t') {
continue;
+ }
if (ch == 'z') {
- UNSAFE_TODO(FXSYS_memset(dest_buf_ptr + *dest_size, 0, 4));
+ UNSAFE_TODO(FXSYS_memset(dest_buf_ptr + dest_size, 0, 4));
state = 0;
res = 0;
- *dest_size += 4;
+ dest_size += 4;
continue;
}
// Check for the end or illegal character.
- if (ch < '!' || ch > 'u')
+ if (ch < '!' || ch > 'u') {
break;
+ }
res = res * 85 + ch - 33;
if (state < 4) {
@@ -177,95 +180,100 @@
}
for (size_t i = 0; i < 4; ++i) {
- UNSAFE_TODO(dest_buf_ptr[(*dest_size)++] = GetA85Result(res, i));
+ UNSAFE_TODO(dest_buf_ptr[dest_size++] = GetA85Result(res, i));
}
state = 0;
res = 0;
}
// Handle partial group.
if (state) {
- for (size_t i = state; i < 5; ++i)
+ for (size_t i = state; i < 5; ++i) {
res = res * 85 + 84;
+ }
for (size_t i = 0; i < state - 1; ++i) {
- UNSAFE_TODO(dest_buf_ptr[(*dest_size)++] = GetA85Result(res, i));
+ UNSAFE_TODO(dest_buf_ptr[dest_size++] = GetA85Result(res, i));
}
}
- if (pos < src_span.size() && src_span[pos] == '>')
+ if (pos < src_span.size() && src_span[pos] == '>') {
++pos;
- return pos;
+ }
+ return {std::move(dest_buf), dest_size, pos};
}
-uint32_t HexDecode(pdfium::span<const uint8_t> src_span,
- std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
- uint32_t* dest_size) {
- *dest_size = 0;
+DataAndBytesConsumed HexDecode(pdfium::span<const uint8_t> src_span) {
if (src_span.empty()) {
- dest_buf->reset();
- return 0;
+ return {nullptr, 0u, 0u};
}
uint32_t i = 0;
// Find the end of data.
- while (i < src_span.size() && src_span[i] != '>')
+ while (i < src_span.size() && src_span[i] != '>') {
++i;
+ }
- dest_buf->reset(FX_Alloc(uint8_t, i / 2 + 1));
- uint8_t* dest_buf_ptr = dest_buf->get();
+ std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf(
+ FX_Alloc(uint8_t, i / 2 + 1));
+ uint8_t* dest_buf_ptr = dest_buf.get();
+ uint32_t dest_size = 0;
bool bFirst = true;
for (i = 0; i < src_span.size(); ++i) {
uint8_t ch = src_span[i];
- if (PDFCharIsLineEnding(ch) || ch == ' ' || ch == '\t')
+ if (PDFCharIsLineEnding(ch) || ch == ' ' || ch == '\t') {
continue;
+ }
if (ch == '>') {
++i;
break;
}
- if (!isxdigit(ch))
+ if (!isxdigit(ch)) {
continue;
+ }
int digit = FXSYS_HexCharToInt(ch);
if (bFirst) {
- UNSAFE_TODO(dest_buf_ptr[*dest_size] = digit * 16);
+ UNSAFE_TODO(dest_buf_ptr[dest_size] = digit * 16);
} else {
- UNSAFE_TODO(dest_buf_ptr[(*dest_size)++] += digit);
+ UNSAFE_TODO(dest_buf_ptr[dest_size++] += digit);
}
bFirst = !bFirst;
}
- if (!bFirst)
- ++(*dest_size);
- return i;
+ if (!bFirst) {
+ ++dest_size;
+ }
+ return {std::move(dest_buf), dest_size, i};
}
-uint32_t RunLengthDecode(pdfium::span<const uint8_t> src_span,
- std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
- uint32_t* dest_size) {
+DataAndBytesConsumed RunLengthDecode(pdfium::span<const uint8_t> src_span) {
+ uint32_t dest_size = 0;
size_t i = 0;
- *dest_size = 0;
while (i < src_span.size()) {
if (src_span[i] == 128)
break;
- uint32_t old = *dest_size;
+ uint32_t old = dest_size;
if (src_span[i] < 128) {
- *dest_size += src_span[i] + 1;
- if (*dest_size < old)
- return FX_INVALID_OFFSET;
+ dest_size += src_span[i] + 1;
+ if (dest_size < old) {
+ return {nullptr, 0, FX_INVALID_OFFSET};
+ }
i += src_span[i] + 2;
} else {
- *dest_size += 257 - src_span[i];
- if (*dest_size < old)
- return FX_INVALID_OFFSET;
+ dest_size += 257 - src_span[i];
+ if (dest_size < old) {
+ return {nullptr, 0, FX_INVALID_OFFSET};
+ }
i += 2;
}
}
- if (*dest_size >= kMaxStreamSize)
- return FX_INVALID_OFFSET;
+ if (dest_size >= kMaxStreamSize) {
+ return {nullptr, 0, FX_INVALID_OFFSET};
+ }
- dest_buf->reset(FX_Alloc(uint8_t, *dest_size));
+ std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf(
+ FX_Alloc(uint8_t, dest_size));
// SAFETY: allocation of `*dest_size` above.
- auto dest_span =
- UNSAFE_BUFFERS(pdfium::make_span(dest_buf->get(), *dest_size));
+ auto dest_span = UNSAFE_BUFFERS(pdfium::make_span(dest_buf.get(), dest_size));
i = 0;
int dest_count = 0;
while (i < src_span.size()) {
@@ -292,7 +300,8 @@
i += 2;
}
}
- return std::min(i + 1, src_span.size());
+ return {std::move(dest_buf), dest_size,
+ pdfium::checked_cast<uint32_t>(std::min(i + 1, src_span.size()))};
}
std::unique_ptr<ScanlineDecoder> CreateFaxDecoder(
@@ -442,9 +451,15 @@
new_size = decode_result.size;
bytes_consumed = decode_result.bytes_consumed;
} else if (decoder == "ASCII85Decode" || decoder == "A85") {
- bytes_consumed = A85Decode(last_span, &new_buf, &new_size);
+ DataAndBytesConsumed decode_result = A85Decode(last_span);
+ new_buf = std::move(decode_result.data);
+ new_size = decode_result.size;
+ bytes_consumed = decode_result.bytes_consumed;
} else if (decoder == "ASCIIHexDecode" || decoder == "AHx") {
- bytes_consumed = HexDecode(last_span, &new_buf, &new_size);
+ DataAndBytesConsumed decode_result = HexDecode(last_span);
+ new_buf = std::move(decode_result.data);
+ new_size = decode_result.size;
+ bytes_consumed = decode_result.bytes_consumed;
} else if (decoder == "RunLengthDecode" || decoder == "RL") {
if (bImageAcc && i == nSize - 1) {
*ImageEncoding = "RunLengthDecode";
@@ -453,7 +468,10 @@
*pImageParams = std::move(pParam);
return true;
}
- bytes_consumed = RunLengthDecode(last_span, &new_buf, &new_size);
+ DataAndBytesConsumed decode_result = RunLengthDecode(last_span);
+ new_buf = std::move(decode_result.data);
+ new_size = decode_result.size;
+ bytes_consumed = decode_result.bytes_consumed;
} else {
// If we get here, assume it's an image decoder.
if (decoder == "DCT")
diff --git a/core/fpdfapi/parser/fpdf_parser_decode.h b/core/fpdfapi/parser/fpdf_parser_decode.h
index d53d0b2..2fd7cb0 100644
--- a/core/fpdfapi/parser/fpdf_parser_decode.h
+++ b/core/fpdfapi/parser/fpdf_parser_decode.h
@@ -54,17 +54,12 @@
int bpc,
const CPDF_Dictionary* pParams);
-uint32_t RunLengthDecode(pdfium::span<const uint8_t> src_span,
- std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
- uint32_t* dest_size);
+fxcodec::DataAndBytesConsumed RunLengthDecode(
+ pdfium::span<const uint8_t> src_span);
-uint32_t A85Decode(pdfium::span<const uint8_t> src_span,
- std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
- uint32_t* dest_size);
+fxcodec::DataAndBytesConsumed A85Decode(pdfium::span<const uint8_t> src_span);
-uint32_t HexDecode(pdfium::span<const uint8_t> src_span,
- std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
- uint32_t* dest_size);
+fxcodec::DataAndBytesConsumed HexDecode(pdfium::span<const uint8_t> src_span);
fxcodec::DataAndBytesConsumed FlateOrLZWDecode(
bool use_lzw,
diff --git a/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp b/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp
index 61d74b4..806f279 100644
--- a/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp
+++ b/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp
@@ -20,6 +20,7 @@
#include "core/fpdfapi/parser/cpdf_name.h"
#include "core/fpdfapi/parser/cpdf_reference.h"
#include "core/fpdfapi/parser/cpdf_string.h"
+#include "core/fxcodec/data_and_bytes_consumed.h"
#include "core/fxcrt/bytestring.h"
#include "core/fxcrt/fx_memory_wrappers.h"
#include "core/fxcrt/span.h"
@@ -287,16 +288,13 @@
STR_IN_OUT_CASE("FCfN8FCfN8vw", "testtest", 11),
};
for (const auto& test_case : kTestData) {
- std::unique_ptr<uint8_t, FxFreeDeleter> result;
- uint32_t result_size = 0;
- EXPECT_EQ(test_case.processed_size,
- A85Decode(UNSAFE_TODO(pdfium::make_span(test_case.input,
- test_case.input_size)),
- &result, &result_size))
+ DataAndBytesConsumed result = A85Decode(
+ UNSAFE_TODO(pdfium::make_span(test_case.input, test_case.input_size)));
+ EXPECT_EQ(test_case.processed_size, result.bytes_consumed)
<< "for case " << test_case.input;
- ASSERT_EQ(test_case.expected_size, result_size);
- const uint8_t* result_ptr = result.get();
- for (size_t j = 0; j < result_size; ++j) {
+ ASSERT_EQ(test_case.expected_size, result.size);
+ const uint8_t* result_ptr = result.data.get();
+ for (size_t j = 0; j < result.size; ++j) {
EXPECT_EQ(test_case.expected[j], result_ptr[j])
<< "for case " << test_case.input << " char " << j;
}
@@ -323,16 +321,13 @@
STR_IN_OUT_CASE("12AcED3c3456", "\x12\xac\xed\x3c\x34\x56", 12),
};
for (const auto& test_case : kTestData) {
- std::unique_ptr<uint8_t, FxFreeDeleter> result;
- uint32_t result_size = 0;
- EXPECT_EQ(test_case.processed_size,
- HexDecode(UNSAFE_TODO(pdfium::make_span(test_case.input,
- test_case.input_size)),
- &result, &result_size))
+ DataAndBytesConsumed result = HexDecode(
+ UNSAFE_TODO(pdfium::make_span(test_case.input, test_case.input_size)));
+ EXPECT_EQ(test_case.processed_size, result.bytes_consumed)
<< "for case " << test_case.input;
- ASSERT_EQ(test_case.expected_size, result_size);
- const uint8_t* result_ptr = result.get();
- for (size_t j = 0; j < result_size; ++j) {
+ ASSERT_EQ(test_case.expected_size, result.size);
+ const uint8_t* result_ptr = result.data.get();
+ for (size_t j = 0; j < result.size; ++j) {
EXPECT_EQ(test_case.expected[j], result_ptr[j])
<< "for case " << test_case.input << " char " << j;
}
diff --git a/core/fxcodec/basic/rle_unittest.cpp b/core/fxcodec/basic/rle_unittest.cpp
index 87a5213..4f150b0 100644
--- a/core/fxcodec/basic/rle_unittest.cpp
+++ b/core/fxcodec/basic/rle_unittest.cpp
@@ -14,6 +14,7 @@
#include "core/fpdfapi/parser/fpdf_parser_decode.h"
#include "core/fxcodec/basic/basicmodule.h"
+#include "core/fxcodec/data_and_bytes_consumed.h"
#include "core/fxcrt/data_vector.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -34,62 +35,56 @@
// Check a few basic cases (2 matching runs in a row, matching run followed
// by a non-matching run, and non-matching run followed by a matching run).
TEST(fxcodec, RLENormalInputs) {
- std::unique_ptr<uint8_t, FxFreeDeleter> decoded_buf;
- uint32_t decoded_size = 0;
-
{
// Case 1: Match, match
const uint8_t src_buf_1[] = {2, 2, 2, 2, 4, 4, 4, 4, 4, 4};
DataVector<uint8_t> dest_buf = BasicModule::RunLengthEncode(src_buf_1);
- RunLengthDecode(dest_buf, &decoded_buf, &decoded_size);
- ASSERT_EQ(sizeof(src_buf_1), decoded_size);
- auto decoded_buf_span = pdfium::make_span(decoded_buf.get(), decoded_size);
- for (uint32_t i = 0; i < decoded_size; i++)
+ DataAndBytesConsumed result = RunLengthDecode(dest_buf);
+ ASSERT_EQ(sizeof(src_buf_1), result.size);
+ auto decoded_buf_span = pdfium::make_span(result.data.get(), result.size);
+ for (uint32_t i = 0; i < result.size; i++) {
EXPECT_EQ(src_buf_1[i], decoded_buf_span[i]) << " at " << i;
+ }
}
{
// Case 2: Match, non-match
const uint8_t src_buf_2[] = {2, 2, 2, 2, 1, 2, 3, 4, 5, 6};
DataVector<uint8_t> dest_buf = BasicModule::RunLengthEncode(src_buf_2);
- decoded_buf.reset();
- decoded_size = 0;
- RunLengthDecode(dest_buf, &decoded_buf, &decoded_size);
- ASSERT_EQ(sizeof(src_buf_2), decoded_size);
- auto decoded_buf_span = pdfium::make_span(decoded_buf.get(), decoded_size);
- for (uint32_t i = 0; i < decoded_size; i++)
+ DataAndBytesConsumed result = RunLengthDecode(dest_buf);
+ ASSERT_EQ(sizeof(src_buf_2), result.size);
+ auto decoded_buf_span = pdfium::make_span(result.data.get(), result.size);
+ for (uint32_t i = 0; i < result.size; i++) {
EXPECT_EQ(src_buf_2[i], decoded_buf_span[i]) << " at " << i;
+ }
}
{
// Case 3: Non-match, match
const uint8_t src_buf_3[] = {1, 2, 3, 4, 5, 3, 3, 3, 3, 3};
DataVector<uint8_t> dest_buf = BasicModule::RunLengthEncode(src_buf_3);
- decoded_buf.reset();
- decoded_size = 0;
- RunLengthDecode(dest_buf, &decoded_buf, &decoded_size);
- ASSERT_EQ(sizeof(src_buf_3), decoded_size);
- auto decoded_buf_span = pdfium::make_span(decoded_buf.get(), decoded_size);
- for (uint32_t i = 0; i < decoded_size; i++)
+ DataAndBytesConsumed result = RunLengthDecode(dest_buf);
+ ASSERT_EQ(sizeof(src_buf_3), result.size);
+ auto decoded_buf_span = pdfium::make_span(result.data.get(), result.size);
+ for (uint32_t i = 0; i < result.size; i++) {
EXPECT_EQ(src_buf_3[i], decoded_buf_span[i]) << " at " << i;
+ }
}
}
// Check that runs longer than 128 are broken up properly, both matched and
// non-matched.
TEST(fxcodec, RLEFullLengthInputs) {
- std::unique_ptr<uint8_t, FxFreeDeleter> decoded_buf;
- uint32_t decoded_size = 0;
-
{
// Case 1: Match, match
const uint8_t src_buf_1[260] = {1};
DataVector<uint8_t> dest_buf = BasicModule::RunLengthEncode(src_buf_1);
- RunLengthDecode(dest_buf, &decoded_buf, &decoded_size);
- ASSERT_EQ(sizeof(src_buf_1), decoded_size);
- auto decoded_buf_span = pdfium::make_span(decoded_buf.get(), decoded_size);
- for (uint32_t i = 0; i < decoded_size; i++)
+ DataAndBytesConsumed result = RunLengthDecode(dest_buf);
+ ASSERT_EQ(sizeof(src_buf_1), result.size);
+ auto decoded_buf_span = pdfium::make_span(result.data.get(), result.size);
+ for (uint32_t i = 0; i < result.size; i++) {
EXPECT_EQ(src_buf_1[i], decoded_buf_span[i]) << " at " << i;
+ }
}
{
@@ -98,13 +93,12 @@
for (uint16_t i = 128; i < 260; i++)
src_buf_2[i] = static_cast<uint8_t>(i - 125);
DataVector<uint8_t> dest_buf = BasicModule::RunLengthEncode(src_buf_2);
- decoded_buf.reset();
- decoded_size = 0;
- RunLengthDecode(dest_buf, &decoded_buf, &decoded_size);
- ASSERT_EQ(sizeof(src_buf_2), decoded_size);
- auto decoded_buf_span = pdfium::make_span(decoded_buf.get(), decoded_size);
- for (uint32_t i = 0; i < decoded_size; i++)
+ DataAndBytesConsumed result = RunLengthDecode(dest_buf);
+ ASSERT_EQ(sizeof(src_buf_2), result.size);
+ auto decoded_buf_span = pdfium::make_span(result.data.get(), result.size);
+ for (uint32_t i = 0; i < result.size; i++) {
EXPECT_EQ(src_buf_2[i], decoded_buf_span[i]) << " at " << i;
+ }
}
{
@@ -113,13 +107,12 @@
for (uint8_t i = 0; i < 128; i++)
src_buf_3[i] = i;
DataVector<uint8_t> dest_buf = BasicModule::RunLengthEncode(src_buf_3);
- decoded_buf.reset();
- decoded_size = 0;
- RunLengthDecode(dest_buf, &decoded_buf, &decoded_size);
- ASSERT_EQ(sizeof(src_buf_3), decoded_size);
- auto decoded_buf_span = pdfium::make_span(decoded_buf.get(), decoded_size);
- for (uint32_t i = 0; i < decoded_size; i++)
+ DataAndBytesConsumed result = RunLengthDecode(dest_buf);
+ ASSERT_EQ(sizeof(src_buf_3), result.size);
+ auto decoded_buf_span = pdfium::make_span(result.data.get(), result.size);
+ for (uint32_t i = 0; i < result.size; i++) {
EXPECT_EQ(src_buf_3[i], decoded_buf_span[i]) << " at " << i;
+ }
}
{
@@ -128,12 +121,11 @@
for (uint16_t i = 0; i < 260; i++)
src_buf_4[i] = static_cast<uint8_t>(i);
DataVector<uint8_t> dest_buf = BasicModule::RunLengthEncode(src_buf_4);
- decoded_buf.reset();
- decoded_size = 0;
- RunLengthDecode(dest_buf, &decoded_buf, &decoded_size);
- ASSERT_EQ(sizeof(src_buf_4), decoded_size);
- auto decoded_buf_span = pdfium::make_span(decoded_buf.get(), decoded_size);
- for (uint32_t i = 0; i < decoded_size; i++)
+ DataAndBytesConsumed result = RunLengthDecode(dest_buf);
+ ASSERT_EQ(sizeof(src_buf_4), result.size);
+ auto decoded_buf_span = pdfium::make_span(result.data.get(), result.size);
+ for (uint32_t i = 0; i < result.size; i++) {
EXPECT_EQ(src_buf_4[i], decoded_buf_span[i]) << " at " << i;
+ }
}
}
diff --git a/fpdfsdk/BUILD.gn b/fpdfsdk/BUILD.gn
index c8aa54f..b18ca03 100644
--- a/fpdfsdk/BUILD.gn
+++ b/fpdfsdk/BUILD.gn
@@ -76,6 +76,7 @@
"../core/fpdfapi/render",
"../core/fpdfdoc",
"../core/fpdftext",
+ "../core/fxcodec",
"../core/fxcrt",
"../core/fxge",
"../fxjs",
diff --git a/fpdfsdk/fpdf_attachment.cpp b/fpdfsdk/fpdf_attachment.cpp
index 85ba9fb..4136ad5 100644
--- a/fpdfsdk/fpdf_attachment.cpp
+++ b/fpdfsdk/fpdf_attachment.cpp
@@ -22,6 +22,7 @@
#include "core/fpdfapi/parser/fpdf_parser_decode.h"
#include "core/fpdfdoc/cpdf_filespec.h"
#include "core/fpdfdoc/cpdf_nametree.h"
+#include "core/fxcodec/data_and_bytes_consumed.h"
#include "core/fxcrt/cfx_datetime.h"
#include "core/fxcrt/data_vector.h"
#include "core/fxcrt/fx_extension.h"
@@ -34,10 +35,8 @@
constexpr char kChecksumKey[] = "CheckSum";
ByteString CFXByteStringHexDecode(const ByteString& bsHex) {
- std::unique_ptr<uint8_t, FxFreeDeleter> result;
- uint32_t size = 0;
- HexDecode(bsHex.unsigned_span(), &result, &size);
- return ByteString(result.get(), size);
+ DataAndBytesConsumed result = HexDecode(bsHex.unsigned_span());
+ return ByteString(result.data.get(), result.size);
}
// TODO(tsepez): should be UNSAFE_BUFFER_USAGE.