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.cpp204
1 files changed, 100 insertions, 104 deletions
diff --git a/core/fpdfapi/parser/fpdf_parser_decode.cpp b/core/fpdfapi/parser/fpdf_parser_decode.cpp
index a2ba203488..ddd6b1462d 100644
--- a/core/fpdfapi/parser/fpdf_parser_decode.cpp
+++ b/core/fpdfapi/parser/fpdf_parser_decode.cpp
@@ -19,6 +19,7 @@
#include "core/fpdfapi/parser/fpdf_parser_utility.h"
#include "core/fxcodec/fx_codec.h"
#include "core/fxcrt/fx_extension.h"
+#include "third_party/base/numerics/safe_math.h"
#include "third_party/base/stl_util.h"
namespace {
@@ -29,15 +30,13 @@ bool CheckFlateDecodeParams(int Colors, int BitsPerComponent, int Columns) {
if (Colors < 0 || BitsPerComponent < 0 || Columns < 0)
return false;
- int check = Columns;
- if (check > 0 && Colors > INT_MAX / check)
- return false;
-
+ pdfium::base::CheckedNumeric<int> check = Columns;
check *= Colors;
- if (check > 0 && BitsPerComponent > INT_MAX / check)
+ check *= BitsPerComponent;
+ if (!check.IsValid())
return false;
- return check * BitsPerComponent <= INT_MAX - 7;
+ return check.ValueOrDie() <= INT_MAX - 7;
}
} // namespace
@@ -75,10 +74,10 @@ const uint16_t PDFDocEncoding[256] = {
uint32_t A85Decode(const uint8_t* src_buf,
uint32_t src_size,
- uint8_t*& dest_buf,
- uint32_t& dest_size) {
- dest_size = 0;
- dest_buf = nullptr;
+ uint8_t** dest_buf,
+ uint32_t* dest_size) {
+ *dest_size = 0;
+ *dest_buf = nullptr;
if (src_size == 0)
return 0;
@@ -105,26 +104,27 @@ uint32_t A85Decode(const uint8_t* src_buf,
if (zcount > (UINT_MAX - space_for_non_zeroes) / 4)
return 0xFFFFFFFF;
- dest_buf = FX_Alloc(uint8_t, zcount * 4 + space_for_non_zeroes);
+ *dest_buf = FX_Alloc(uint8_t, zcount * 4 + space_for_non_zeroes);
size_t state = 0;
uint32_t res = 0;
- pos = dest_size = 0;
+ pos = 0;
while (pos < src_size) {
uint8_t ch = src_buf[pos++];
if (PDFCharIsLineEnding(ch) || ch == ' ' || ch == '\t')
continue;
if (ch == 'z') {
- memset(dest_buf + dest_size, 0, 4);
+ memset(*dest_buf + *dest_size, 0, 4);
state = 0;
res = 0;
- dest_size += 4;
+ *dest_size += 4;
} else if (ch >= '!' && ch <= 'u') {
res = res * 85 + ch - 33;
state++;
if (state == 5) {
- for (size_t i = 0; i < 4; i++) {
- dest_buf[dest_size++] = (uint8_t)(res >> (3 - i) * 8);
+ for (size_t i = 0; i < 4; ++i) {
+ (*dest_buf)[(*dest_size)++] =
+ static_cast<uint8_t>(res >> (3 - i) * 8);
}
state = 0;
res = 0;
@@ -136,34 +136,34 @@ uint32_t A85Decode(const uint8_t* src_buf,
}
// 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++)
- dest_buf[dest_size++] = (uint8_t)(res >> (3 - i) * 8);
+ for (size_t i = 0; i < state - 1; ++i)
+ (*dest_buf)[(*dest_size)++] = static_cast<uint8_t>(res >> (3 - i) * 8);
}
if (pos < src_size && src_buf[pos] == '>')
- pos++;
+ ++pos;
return pos;
}
uint32_t HexDecode(const uint8_t* src_buf,
uint32_t src_size,
- uint8_t*& dest_buf,
- uint32_t& dest_size) {
- dest_size = 0;
+ uint8_t** dest_buf,
+ uint32_t* dest_size) {
+ *dest_size = 0;
if (src_size == 0) {
- dest_buf = nullptr;
+ *dest_buf = nullptr;
return 0;
}
uint32_t i = 0;
// Find the end of data.
while (i < src_size && src_buf[i] != '>')
- i++;
+ ++i;
- dest_buf = FX_Alloc(uint8_t, i / 2 + 1);
+ *dest_buf = FX_Alloc(uint8_t, i / 2 + 1);
bool bFirst = true;
- for (i = 0; i < src_size; i++) {
+ for (i = 0; i < src_size; ++i) {
uint8_t ch = src_buf[i];
if (PDFCharIsLineEnding(ch) || ch == ' ' || ch == '\t')
continue;
@@ -177,44 +177,43 @@ uint32_t HexDecode(const uint8_t* src_buf,
int digit = FXSYS_HexCharToInt(ch);
if (bFirst)
- dest_buf[dest_size] = digit * 16;
+ (*dest_buf)[*dest_size] = digit * 16;
else
- dest_buf[dest_size++] += digit;
-
+ (*dest_buf)[(*dest_size)++] += digit;
bFirst = !bFirst;
}
if (!bFirst)
- dest_size++;
+ ++(*dest_size);
return i;
}
uint32_t RunLengthDecode(const uint8_t* src_buf,
uint32_t src_size,
- uint8_t*& dest_buf,
- uint32_t& dest_size) {
+ uint8_t** dest_buf,
+ uint32_t* dest_size) {
uint32_t i = 0;
- dest_size = 0;
+ *dest_size = 0;
while (i < src_size) {
if (src_buf[i] == 128)
break;
- uint32_t old = dest_size;
+ uint32_t old = *dest_size;
if (src_buf[i] < 128) {
- dest_size += src_buf[i] + 1;
- if (dest_size < old)
+ *dest_size += src_buf[i] + 1;
+ if (*dest_size < old)
return FX_INVALID_OFFSET;
i += src_buf[i] + 2;
} else {
- dest_size += 257 - src_buf[i];
- if (dest_size < old)
+ *dest_size += 257 - src_buf[i];
+ if (*dest_size < old)
return FX_INVALID_OFFSET;
i += 2;
}
}
- if (dest_size >= kMaxStreamSize)
+ if (*dest_size >= kMaxStreamSize)
return FX_INVALID_OFFSET;
- dest_buf = FX_Alloc(uint8_t, dest_size);
+ *dest_buf = FX_Alloc(uint8_t, *dest_size);
i = 0;
int dest_count = 0;
while (i < src_size) {
@@ -227,22 +226,20 @@ uint32_t RunLengthDecode(const uint8_t* src_buf,
if (buf_left < copy_len) {
uint32_t delta = copy_len - buf_left;
copy_len = buf_left;
- memset(dest_buf + dest_count + copy_len, '\0', delta);
+ memset(*dest_buf + dest_count + copy_len, '\0', delta);
}
- memcpy(dest_buf + dest_count, src_buf + i + 1, copy_len);
+ memcpy(*dest_buf + dest_count, src_buf + i + 1, copy_len);
dest_count += src_buf[i] + 1;
i += src_buf[i] + 2;
} else {
int fill = 0;
- if (i < src_size - 1) {
+ if (i < src_size - 1)
fill = src_buf[i + 1];
- }
- memset(dest_buf + dest_count, fill, 257 - src_buf[i]);
+ memset(*dest_buf + dest_count, fill, 257 - src_buf[i]);
dest_count += 257 - src_buf[i];
i += 2;
}
}
-
return std::min(i + 1, src_size);
}
@@ -265,9 +262,8 @@ std::unique_ptr<CCodec_ScanlineDecoder> FPDFAPI_CreateFaxDecoder(
BlackIs1 = !!pParams->GetIntegerFor("BlackIs1");
Columns = pParams->GetIntegerFor("Columns", 1728);
Rows = pParams->GetIntegerFor("Rows");
- if (Rows > USHRT_MAX) {
+ if (Rows > USHRT_MAX)
Rows = 0;
- }
}
return CPDF_ModuleMgr::Get()->GetFaxModule()->CreateDecoder(
src_buf, src_size, width, height, K, EndOfLine, ByteAlign, BlackIs1,
@@ -283,7 +279,9 @@ std::unique_ptr<CCodec_ScanlineDecoder> FPDFAPI_CreateFlateDecoder(
int bpc,
const CPDF_Dictionary* pParams) {
int predictor = 0;
- int Colors = 0, BitsPerComponent = 0, Columns = 0;
+ int Colors = 0;
+ int BitsPerComponent = 0;
+ int Columns = 0;
if (pParams) {
predictor = pParams->GetIntegerFor("Predictor");
Colors = pParams->GetIntegerFor("Colors", 1);
@@ -302,8 +300,8 @@ uint32_t FPDFAPI_FlateOrLZWDecode(bool bLZW,
uint32_t src_size,
CPDF_Dictionary* pParams,
uint32_t estimated_size,
- uint8_t*& dest_buf,
- uint32_t& dest_size) {
+ uint8_t** dest_buf,
+ uint32_t* dest_size) {
int predictor = 0;
int Colors = 0;
int BitsPerComponent = 0;
@@ -326,12 +324,12 @@ uint32_t FPDFAPI_FlateOrLZWDecode(bool bLZW,
bool PDF_DataDecode(const uint8_t* src_buf,
uint32_t src_size,
const CPDF_Dictionary* pDict,
- uint8_t*& dest_buf,
- uint32_t& dest_size,
- CFX_ByteString* ImageEncoding,
- CPDF_Dictionary*& pImageParms,
uint32_t last_estimated_size,
- bool bImageAcc) {
+ bool bImageAcc,
+ uint8_t** dest_buf,
+ uint32_t* dest_size,
+ CFX_ByteString* ImageEncoding,
+ CPDF_Dictionary** pImageParms) {
CPDF_Object* pDecoder = pDict ? pDict->GetDirectObjectFor("Filter") : nullptr;
if (!pDecoder || (!pDecoder->IsArray() && !pDecoder->IsName()))
return false;
@@ -342,7 +340,7 @@ bool PDF_DataDecode(const uint8_t* src_buf,
std::vector<std::pair<CFX_ByteString, CPDF_Object*>> DecoderArray;
if (CPDF_Array* pDecoders = pDecoder->AsArray()) {
CPDF_Array* pParamsArray = ToArray(pParams);
- for (size_t i = 0; i < pDecoders->GetCount(); i++) {
+ for (size_t i = 0; i < pDecoders->GetCount(); ++i) {
DecoderArray.push_back(
{pDecoders->GetStringAt(i),
pParamsArray ? pParamsArray->GetDictAt(i) : nullptr});
@@ -354,7 +352,7 @@ bool PDF_DataDecode(const uint8_t* src_buf,
uint8_t* last_buf = const_cast<uint8_t*>(src_buf);
uint32_t last_size = src_size;
int nSize = pdfium::CollectionSize<int>(DecoderArray);
- for (int i = 0; i < nSize; i++) {
+ for (int i = 0; i < nSize; ++i) {
int estimated_size = i == nSize - 1 ? last_estimated_size : 0;
CFX_ByteString decoder = DecoderArray[i].first;
CPDF_Dictionary* pParam = ToDictionary(DecoderArray[i].second);
@@ -364,49 +362,47 @@ bool PDF_DataDecode(const uint8_t* src_buf,
if (decoder == "FlateDecode" || decoder == "Fl") {
if (bImageAcc && i == nSize - 1) {
*ImageEncoding = "FlateDecode";
- dest_buf = last_buf;
- dest_size = last_size;
- pImageParms = pParam;
+ *dest_buf = last_buf;
+ *dest_size = last_size;
+ *pImageParms = pParam;
return true;
}
offset = FPDFAPI_FlateOrLZWDecode(false, last_buf, last_size, pParam,
- estimated_size, new_buf, new_size);
+ estimated_size, &new_buf, &new_size);
} else if (decoder == "LZWDecode" || decoder == "LZW") {
offset = FPDFAPI_FlateOrLZWDecode(true, last_buf, last_size, pParam,
- estimated_size, new_buf, new_size);
+ estimated_size, &new_buf, &new_size);
} else if (decoder == "ASCII85Decode" || decoder == "A85") {
- offset = A85Decode(last_buf, last_size, new_buf, new_size);
+ offset = A85Decode(last_buf, last_size, &new_buf, &new_size);
} else if (decoder == "ASCIIHexDecode" || decoder == "AHx") {
- offset = HexDecode(last_buf, last_size, new_buf, new_size);
+ offset = HexDecode(last_buf, last_size, &new_buf, &new_size);
} else if (decoder == "RunLengthDecode" || decoder == "RL") {
if (bImageAcc && i == nSize - 1) {
*ImageEncoding = "RunLengthDecode";
- dest_buf = last_buf;
- dest_size = last_size;
- pImageParms = pParam;
+ *dest_buf = last_buf;
+ *dest_size = last_size;
+ *pImageParms = pParam;
return true;
}
- offset = RunLengthDecode(last_buf, last_size, new_buf, new_size);
+ offset = RunLengthDecode(last_buf, last_size, &new_buf, &new_size);
} else if (decoder == "Crypt") {
continue;
} else {
// If we get here, assume it's an image decoder.
- if (decoder == "DCT") {
+ if (decoder == "DCT")
decoder = "DCTDecode";
- } else if (decoder == "CCF") {
+ else if (decoder == "CCF")
decoder = "CCITTFaxDecode";
- }
*ImageEncoding = decoder;
- pImageParms = pParam;
- dest_buf = last_buf;
- dest_size = last_size;
+ *pImageParms = pParam;
+ *dest_buf = last_buf;
+ *dest_size = last_size;
if (CPDF_Array* pDecoders = pDecoder->AsArray())
pDecoders->Truncate(i + 1);
return true;
}
- if (last_buf != src_buf) {
+ if (last_buf != src_buf)
FX_Free(last_buf);
- }
if (offset == -1) {
FX_Free(new_buf);
return false;
@@ -415,9 +411,9 @@ bool PDF_DataDecode(const uint8_t* src_buf,
last_size = new_size;
}
*ImageEncoding = "";
- pImageParms = nullptr;
- dest_buf = last_buf;
- dest_size = last_size;
+ *pImageParms = nullptr;
+ *dest_buf = last_buf;
+ *dest_size = last_size;
return true;
}
@@ -427,12 +423,11 @@ CFX_WideString PDF_DecodeText(const uint8_t* src_data, uint32_t src_len) {
(src_data[0] == 0xff && src_data[1] == 0xfe))) {
bool bBE = src_data[0] == 0xfe;
uint32_t max_chars = (src_len - 2) / 2;
- if (!max_chars) {
+ if (!max_chars)
return result;
- }
- if (src_data[0] == 0xff) {
+
+ if (src_data[0] == 0xff)
bBE = !src_data[2];
- }
wchar_t* dest_buf = result.GetBuffer(max_chars);
const uint8_t* uni_str = src_data + 2;
int dest_pos = 0;
@@ -455,7 +450,7 @@ CFX_WideString PDF_DecodeText(const uint8_t* src_data, uint32_t src_len) {
result.ReleaseBuffer(dest_pos);
} else {
wchar_t* dest_buf = result.GetBuffer(src_len);
- for (uint32_t i = 0; i < src_len; i++)
+ for (uint32_t i = 0; i < src_len; ++i)
dest_buf[i] = PDFDocEncoding[src_data[i]];
result.ReleaseBuffer(src_len);
}
@@ -463,31 +458,32 @@ CFX_WideString PDF_DecodeText(const uint8_t* src_data, uint32_t src_len) {
}
CFX_WideString PDF_DecodeText(const CFX_ByteString& bstr) {
- return PDF_DecodeText((const uint8_t*)bstr.c_str(), bstr.GetLength());
+ return PDF_DecodeText(reinterpret_cast<const uint8_t*>(bstr.c_str()),
+ bstr.GetLength());
}
CFX_ByteString PDF_EncodeText(const wchar_t* pString, int len) {
- if (len == -1) {
+ if (len == -1)
len = FXSYS_wcslen(pString);
- }
+
CFX_ByteString result;
char* dest_buf1 = result.GetBuffer(len);
int i;
- for (i = 0; i < len; i++) {
+ for (i = 0; i < len; ++i) {
int code;
- for (code = 0; code < 256; code++)
- if (PDFDocEncoding[code] == pString[i]) {
+ for (code = 0; code < 256; ++code) {
+ if (PDFDocEncoding[code] == pString[i])
break;
- }
- if (code == 256) {
- break;
}
+
+ if (code == 256)
+ break;
+
dest_buf1[i] = code;
}
result.ReleaseBuffer(i);
- if (i == len) {
+ if (i == len)
return result;
- }
if (len > INT_MAX / 2 - 1) {
result.ReleaseBuffer(0);
@@ -496,13 +492,13 @@ CFX_ByteString PDF_EncodeText(const wchar_t* pString, int len) {
int encLen = len * 2 + 2;
- uint8_t* dest_buf2 = (uint8_t*)result.GetBuffer(encLen);
+ uint8_t* dest_buf2 = reinterpret_cast<uint8_t*>(result.GetBuffer(encLen));
dest_buf2[0] = 0xfe;
dest_buf2[1] = 0xff;
dest_buf2 += 2;
- for (int j = 0; j < len; j++) {
+ for (int j = 0; j < len; ++j) {
*dest_buf2++ = pString[j] >> 8;
- *dest_buf2++ = (uint8_t)pString[j];
+ *dest_buf2++ = static_cast<uint8_t>(pString[j]);
}
result.ReleaseBuffer(encLen);
return result;
@@ -517,7 +513,7 @@ CFX_ByteString PDF_EncodeString(const CFX_ByteString& src, bool bHex) {
int srclen = src.GetLength();
if (bHex) {
result << '<';
- for (int i = 0; i < srclen; i++) {
+ for (int i = 0; i < srclen; ++i) {
char buf[2];
FXSYS_IntToTwoHexChars(src[i], buf);
result << buf[0];
@@ -527,7 +523,7 @@ CFX_ByteString PDF_EncodeString(const CFX_ByteString& src, bool bHex) {
return CFX_ByteString(result);
}
result << '(';
- for (int i = 0; i < srclen; i++) {
+ for (int i = 0; i < srclen; ++i) {
uint8_t ch = src[i];
if (ch == 0x0a) {
result << "\\n";
@@ -565,8 +561,8 @@ bool PngEncode(const uint8_t* src_buf,
uint32_t FlateDecode(const uint8_t* src_buf,
uint32_t src_size,
- uint8_t*& dest_buf,
- uint32_t& dest_size) {
+ uint8_t** dest_buf,
+ uint32_t* dest_size) {
CCodec_ModuleMgr* pEncoders = CPDF_ModuleMgr::Get()->GetCodecModule();
return pEncoders->GetFlateModule()->FlateOrLZWDecode(
false, src_buf, src_size, false, 0, 0, 0, 0, 0, dest_buf, dest_size);