summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/fpdfapi/page/cpdf_streamparser.cpp15
-rw-r--r--core/fpdfapi/parser/fpdf_parser_decode.cpp44
-rw-r--r--core/fpdfapi/parser/fpdf_parser_decode.h5
-rw-r--r--core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp24
4 files changed, 52 insertions, 36 deletions
diff --git a/core/fpdfapi/page/cpdf_streamparser.cpp b/core/fpdfapi/page/cpdf_streamparser.cpp
index 9533bb2a17..fe67634196 100644
--- a/core/fpdfapi/page/cpdf_streamparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamparser.cpp
@@ -68,22 +68,24 @@ uint32_t DecodeInlineStream(pdfium::span<const uint8_t> src_span,
CPDF_Dictionary* pParam,
uint8_t** dest_buf,
uint32_t* dest_size) {
+ *dest_buf = nullptr;
+ *dest_size = 0;
if (decoder == "CCITTFaxDecode" || decoder == "CCF") {
std::unique_ptr<CCodec_ScanlineDecoder> pDecoder =
CreateFaxDecoder(src_span, width, height, pParam);
return DecodeAllScanlines(std::move(pDecoder), dest_buf, dest_size);
}
+ std::unique_ptr<uint8_t, FxFreeDeleter> ignored_result;
if (decoder == "ASCII85Decode" || decoder == "A85")
- return A85Decode(src_span, dest_buf, dest_size);
+ return A85Decode(src_span, &ignored_result, dest_size);
if (decoder == "ASCIIHexDecode" || decoder == "AHx")
- return HexDecode(src_span, dest_buf, dest_size);
+ return HexDecode(src_span, &ignored_result, dest_size);
if (decoder == "FlateDecode" || decoder == "Fl") {
return FlateOrLZWDecode(false, src_span, pParam, *dest_size, dest_buf,
dest_size);
}
- if (decoder == "LZWDecode" || decoder == "LZW") {
+ if (decoder == "LZWDecode" || decoder == "LZW")
return FlateOrLZWDecode(true, src_span, pParam, 0, dest_buf, dest_size);
- }
if (decoder == "DCTDecode" || decoder == "DCT") {
std::unique_ptr<CCodec_ScanlineDecoder> pDecoder =
CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder(
@@ -93,9 +95,8 @@ uint32_t DecodeInlineStream(pdfium::span<const uint8_t> src_span,
}
if (decoder == "RunLengthDecode" || decoder == "RL")
return RunLengthDecode(src_span, dest_buf, dest_size);
- *dest_size = 0;
- *dest_buf = 0;
- return 0xFFFFFFFF;
+
+ return FX_INVALID_OFFSET;
}
} // namespace
diff --git a/core/fpdfapi/parser/fpdf_parser_decode.cpp b/core/fpdfapi/parser/fpdf_parser_decode.cpp
index 410c9a9b8d..efa60d8e3b 100644
--- a/core/fpdfapi/parser/fpdf_parser_decode.cpp
+++ b/core/fpdfapi/parser/fpdf_parser_decode.cpp
@@ -50,6 +50,10 @@ bool CheckFlateDecodeParams(int Colors, int BitsPerComponent, int Columns) {
return check.ValueOrDie() <= INT_MAX - 7;
}
+uint8_t GetA85Result(uint32_t res, size_t i) {
+ return static_cast<uint8_t>(res >> (3 - i) * 8);
+}
+
} // namespace
const uint16_t PDFDocEncoding[256] = {
@@ -84,12 +88,13 @@ const uint16_t PDFDocEncoding[256] = {
0x00fc, 0x00fd, 0x00fe, 0x00ff};
uint32_t A85Decode(pdfium::span<const uint8_t> src_span,
- uint8_t** dest_buf,
+ std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
uint32_t* dest_size) {
*dest_size = 0;
- *dest_buf = nullptr;
- if (src_span.empty())
+ if (src_span.empty()) {
+ dest_buf->reset();
return 0;
+ }
// Count legal characters and zeros.
uint32_t zcount = 0;
@@ -111,10 +116,14 @@ uint32_t A85Decode(pdfium::span<const uint8_t> src_span,
// Count the space needed to contain non-zero characters. The encoding ratio
// of Ascii85 is 4:5.
uint32_t space_for_non_zeroes = (pos - zcount) / 5 * 4 + 4;
- if (zcount > (UINT_MAX - space_for_non_zeroes) / 4)
+ FX_SAFE_UINT32 size = zcount;
+ size *= 4;
+ size += space_for_non_zeroes;
+ if (!size.IsValid())
return FX_INVALID_OFFSET;
- *dest_buf = FX_Alloc(uint8_t, zcount * 4 + space_for_non_zeroes);
+ dest_buf->reset(FX_Alloc(uint8_t, size.ValueOrDie()));
+ uint8_t* dest_buf_ptr = dest_buf->get();
size_t state = 0;
uint32_t res = 0;
pos = 0;
@@ -124,7 +133,7 @@ uint32_t A85Decode(pdfium::span<const uint8_t> src_span,
continue;
if (ch == 'z') {
- memset(*dest_buf + *dest_size, 0, 4);
+ memset(dest_buf_ptr + *dest_size, 0, 4);
state = 0;
res = 0;
*dest_size += 4;
@@ -142,7 +151,7 @@ uint32_t A85Decode(pdfium::span<const uint8_t> src_span,
}
for (size_t i = 0; i < 4; ++i) {
- (*dest_buf)[(*dest_size)++] = static_cast<uint8_t>(res >> (3 - i) * 8);
+ dest_buf_ptr[(*dest_size)++] = GetA85Result(res, i);
}
state = 0;
res = 0;
@@ -152,7 +161,7 @@ uint32_t A85Decode(pdfium::span<const uint8_t> src_span,
for (size_t i = state; i < 5; ++i)
res = res * 85 + 84;
for (size_t i = 0; i < state - 1; ++i)
- (*dest_buf)[(*dest_size)++] = static_cast<uint8_t>(res >> (3 - i) * 8);
+ dest_buf_ptr[(*dest_size)++] = GetA85Result(res, i);
}
if (pos < src_span.size() && src_span[pos] == '>')
++pos;
@@ -160,11 +169,11 @@ uint32_t A85Decode(pdfium::span<const uint8_t> src_span,
}
uint32_t HexDecode(pdfium::span<const uint8_t> src_span,
- uint8_t** dest_buf,
+ std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
uint32_t* dest_size) {
*dest_size = 0;
if (src_span.empty()) {
- *dest_buf = nullptr;
+ dest_buf->reset();
return 0;
}
@@ -173,7 +182,8 @@ uint32_t HexDecode(pdfium::span<const uint8_t> src_span,
while (i < src_span.size() && src_span[i] != '>')
++i;
- *dest_buf = FX_Alloc(uint8_t, i / 2 + 1);
+ dest_buf->reset(FX_Alloc(uint8_t, i / 2 + 1));
+ uint8_t* dest_buf_ptr = dest_buf->get();
bool bFirst = true;
for (i = 0; i < src_span.size(); ++i) {
uint8_t ch = src_span[i];
@@ -189,9 +199,9 @@ uint32_t HexDecode(pdfium::span<const uint8_t> src_span,
int digit = FXSYS_HexCharToInt(ch);
if (bFirst)
- (*dest_buf)[*dest_size] = digit * 16;
+ dest_buf_ptr[*dest_size] = digit * 16;
else
- (*dest_buf)[(*dest_size)++] += digit;
+ dest_buf_ptr[(*dest_size)++] += digit;
bFirst = !bFirst;
}
if (!bFirst)
@@ -384,9 +394,13 @@ bool PDF_DataDecode(pdfium::span<const uint8_t> src_span,
offset = FlateOrLZWDecode(true, last_span, pParam, estimated_size,
&new_buf, &new_size);
} else if (decoder == "ASCII85Decode" || decoder == "A85") {
- offset = A85Decode(last_span, &new_buf, &new_size);
+ std::unique_ptr<uint8_t, FxFreeDeleter> result;
+ offset = A85Decode(last_span, &result, &new_size);
+ new_buf = result.release();
} else if (decoder == "ASCIIHexDecode" || decoder == "AHx") {
- offset = HexDecode(last_span, &new_buf, &new_size);
+ std::unique_ptr<uint8_t, FxFreeDeleter> result;
+ offset = HexDecode(last_span, &result, &new_size);
+ new_buf = result.release();
} else if (decoder == "RunLengthDecode" || decoder == "RL") {
if (bImageAcc && i == nSize - 1) {
*ImageEncoding = "RunLengthDecode";
diff --git a/core/fpdfapi/parser/fpdf_parser_decode.h b/core/fpdfapi/parser/fpdf_parser_decode.h
index 1484dd7cf0..eb7beaccdf 100644
--- a/core/fpdfapi/parser/fpdf_parser_decode.h
+++ b/core/fpdfapi/parser/fpdf_parser_decode.h
@@ -9,6 +9,7 @@
#include <memory>
+#include "core/fxcrt/fx_memory.h"
#include "core/fxcrt/fx_string.h"
#include "core/fxcrt/unowned_ptr.h"
#include "third_party/base/span.h"
@@ -51,11 +52,11 @@ uint32_t RunLengthDecode(pdfium::span<const uint8_t> src_span,
uint32_t* dest_size);
uint32_t A85Decode(pdfium::span<const uint8_t> src_span,
- uint8_t** dest_buf,
+ std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
uint32_t* dest_size);
uint32_t HexDecode(pdfium::span<const uint8_t> src_span,
- uint8_t** dest_buf,
+ std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
uint32_t* dest_size);
uint32_t FlateOrLZWDecode(bool bLZW,
diff --git a/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp b/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp
index aa37b796e2..b6d7679ef5 100644
--- a/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp
+++ b/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp
@@ -8,7 +8,7 @@
#include "testing/test_support.h"
TEST(fpdf_parser_decode, A85Decode) {
- pdfium::DecodeTestData test_data[] = {
+ const pdfium::DecodeTestData test_data[] = {
// Empty src string.
STR_IN_OUT_CASE("", "", 0),
// Empty content in src string.
@@ -27,23 +27,23 @@ TEST(fpdf_parser_decode, A85Decode) {
STR_IN_OUT_CASE("FCfN8FCfN8vw", "testtest", 11),
};
for (size_t i = 0; i < FX_ArraySize(test_data); ++i) {
- pdfium::DecodeTestData* ptr = &test_data[i];
- uint8_t* result = nullptr;
+ const pdfium::DecodeTestData* ptr = &test_data[i];
+ std::unique_ptr<uint8_t, FxFreeDeleter> result;
uint32_t result_size = 0;
EXPECT_EQ(ptr->processed_size,
A85Decode({ptr->input, ptr->input_size}, &result, &result_size))
<< "for case " << i;
ASSERT_EQ(ptr->expected_size, result_size);
+ const uint8_t* result_ptr = result.get();
for (size_t j = 0; j < result_size; ++j) {
- EXPECT_EQ(ptr->expected[j], result[j]) << "for case " << i << " char "
- << j;
+ EXPECT_EQ(ptr->expected[j], result_ptr[j])
+ << "for case " << i << " char " << j;
}
- FX_Free(result);
}
}
TEST(fpdf_parser_decode, HexDecode) {
- pdfium::DecodeTestData test_data[] = {
+ const pdfium::DecodeTestData test_data[] = {
// Empty src string.
STR_IN_OUT_CASE("", "", 0),
// Empty content in src string.
@@ -62,18 +62,18 @@ TEST(fpdf_parser_decode, HexDecode) {
STR_IN_OUT_CASE("12AcED3c3456", "\x12\xac\xed\x3c\x34\x56", 12),
};
for (size_t i = 0; i < FX_ArraySize(test_data); ++i) {
- pdfium::DecodeTestData* ptr = &test_data[i];
- uint8_t* result = nullptr;
+ const pdfium::DecodeTestData* ptr = &test_data[i];
+ std::unique_ptr<uint8_t, FxFreeDeleter> result;
uint32_t result_size = 0;
EXPECT_EQ(ptr->processed_size,
HexDecode({ptr->input, ptr->input_size}, &result, &result_size))
<< "for case " << i;
ASSERT_EQ(ptr->expected_size, result_size);
+ const uint8_t* result_ptr = result.get();
for (size_t j = 0; j < result_size; ++j) {
- EXPECT_EQ(ptr->expected[j], result[j]) << "for case " << i << " char "
- << j;
+ EXPECT_EQ(ptr->expected[j], result_ptr[j])
+ << "for case " << i << " char " << j;
}
- FX_Free(result);
}
}