summaryrefslogtreecommitdiff
path: root/core/fpdfapi/parser/fpdf_parser_decode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/fpdfapi/parser/fpdf_parser_decode.cpp')
-rw-r--r--core/fpdfapi/parser/fpdf_parser_decode.cpp44
1 files changed, 29 insertions, 15 deletions
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";