summaryrefslogtreecommitdiff
path: root/core/fxcodec/codec/fx_codec_flate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/fxcodec/codec/fx_codec_flate.cpp')
-rw-r--r--core/fxcodec/codec/fx_codec_flate.cpp167
1 files changed, 85 insertions, 82 deletions
diff --git a/core/fxcodec/codec/fx_codec_flate.cpp b/core/fxcodec/codec/fx_codec_flate.cpp
index b17e202ea7..2ba505d059 100644
--- a/core/fxcodec/codec/fx_codec_flate.cpp
+++ b/core/fxcodec/codec/fx_codec_flate.cpp
@@ -13,84 +13,87 @@
#include "core/fxcodec/fx_codec.h"
#include "core/fxcrt/fx_ext.h"
+#include "third_party/base/numerics/safe_conversions.h"
#include "third_party/base/ptr_util.h"
#include "third_party/zlib_v128/zlib.h"
extern "C" {
+
static void* my_alloc_func(void* opaque,
unsigned int items,
unsigned int size) {
return FX_Alloc2D(uint8_t, items, size);
}
+
static void my_free_func(void* opaque, void* address) {
FX_Free(address);
}
-static int FPDFAPI_FlateGetTotalOut(void* context) {
- return ((z_stream*)context)->total_out;
+
+} // extern "C"
+
+namespace {
+
+uint32_t FlateGetPossiblyTruncatedTotalOut(void* context) {
+ return pdfium::base::saturated_cast<uint32_t>(
+ static_cast<z_stream*>(context)->total_out);
}
-static int FPDFAPI_FlateGetTotalIn(void* context) {
- return ((z_stream*)context)->total_in;
+
+uint32_t FlateGetPossiblyTruncatedTotalIn(void* context) {
+ return pdfium::base::saturated_cast<uint32_t>(
+ static_cast<z_stream*>(context)->total_in);
}
-static bool FPDFAPI_FlateCompress(unsigned char* dest_buf,
- unsigned long* dest_size,
- const unsigned char* src_buf,
- unsigned long src_size) {
+bool FlateCompress(unsigned char* dest_buf,
+ unsigned long* dest_size,
+ const unsigned char* src_buf,
+ uint32_t src_size) {
return compress(dest_buf, dest_size, src_buf, src_size) == Z_OK;
}
-void* FPDFAPI_FlateInit(void* (*alloc_func)(void*, unsigned int, unsigned int),
- void (*free_func)(void*, void*)) {
- z_stream* p = (z_stream*)alloc_func(0, 1, sizeof(z_stream));
- if (!p)
- return nullptr;
-
+void* FlateInit() {
+ z_stream* p = FX_Alloc(z_stream, 1);
FXSYS_memset(p, 0, sizeof(z_stream));
- p->zalloc = alloc_func;
- p->zfree = free_func;
+ p->zalloc = my_alloc_func;
+ p->zfree = my_free_func;
inflateInit(p);
return p;
}
-void FPDFAPI_FlateInput(void* context,
- const unsigned char* src_buf,
- unsigned int src_size) {
- ((z_stream*)context)->next_in = (unsigned char*)src_buf;
- ((z_stream*)context)->avail_in = src_size;
+void FlateInput(void* context,
+ const unsigned char* src_buf,
+ uint32_t src_size) {
+ static_cast<z_stream*>(context)->next_in =
+ const_cast<unsigned char*>(src_buf);
+ static_cast<z_stream*>(context)->avail_in = src_size;
}
-int FPDFAPI_FlateOutput(void* context,
- unsigned char* dest_buf,
- unsigned int dest_size) {
- ((z_stream*)context)->next_out = dest_buf;
- ((z_stream*)context)->avail_out = dest_size;
- unsigned int pre_pos = (unsigned int)FPDFAPI_FlateGetTotalOut(context);
- int ret = inflate((z_stream*)context, Z_SYNC_FLUSH);
- unsigned int post_pos = (unsigned int)FPDFAPI_FlateGetTotalOut(context);
- unsigned int written = post_pos - pre_pos;
- if (written < dest_size) {
+uint32_t FlateOutput(void* context,
+ unsigned char* dest_buf,
+ uint32_t dest_size) {
+ static_cast<z_stream*>(context)->next_out = dest_buf;
+ static_cast<z_stream*>(context)->avail_out = dest_size;
+ uint32_t pre_pos = FlateGetPossiblyTruncatedTotalOut(context);
+ int ret = inflate(static_cast<z_stream*>(context), Z_SYNC_FLUSH);
+
+ uint32_t post_pos = FlateGetPossiblyTruncatedTotalOut(context);
+ ASSERT(post_pos >= pre_pos);
+
+ uint32_t written = post_pos - pre_pos;
+ if (written < dest_size)
FXSYS_memset(dest_buf + written, '\0', dest_size - written);
- }
- return ret;
-}
-int FPDFAPI_FlateGetAvailIn(void* context) {
- return ((z_stream*)context)->avail_in;
+ return ret;
}
-int FPDFAPI_FlateGetAvailOut(void* context) {
- return ((z_stream*)context)->avail_out;
+uint32_t FlateGetAvailOut(void* context) {
+ return static_cast<z_stream*>(context)->avail_out;
}
-void FPDFAPI_FlateEnd(void* context) {
- inflateEnd((z_stream*)context);
- ((z_stream*)context)->zfree(0, context);
+void FlateEnd(void* context) {
+ inflateEnd(static_cast<z_stream*>(context));
+ static_cast<z_stream*>(context)->zfree(0, context);
}
-} // extern "C"
-
-namespace {
-
class CLZWDecoder {
public:
int Decode(uint8_t* output,
@@ -518,7 +521,7 @@ void FlateUncompress(const uint8_t* src_buf,
dest_buf = nullptr;
dest_size = 0;
- void* context = FPDFAPI_FlateInit(my_alloc_func, my_free_func);
+ void* context = FlateInit();
if (!context)
return;
@@ -526,23 +529,23 @@ void FlateUncompress(const uint8_t* src_buf,
FX_Alloc(uint8_t, guess_size + 1));
guess_buf.get()[guess_size] = '\0';
- FPDFAPI_FlateInput(context, src_buf, src_size);
+ FlateInput(context, src_buf, src_size);
if (src_size < kStepSize) {
// This is the old implementation.
uint8_t* cur_buf = guess_buf.get();
while (1) {
- int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size);
+ uint32_t ret = FlateOutput(context, cur_buf, buf_size);
if (ret != Z_OK)
break;
- int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context);
+ uint32_t avail_buf_size = FlateGetAvailOut(context);
if (avail_buf_size != 0)
break;
uint32_t old_size = guess_size;
guess_size += alloc_step;
if (guess_size < old_size || guess_size + 1 < guess_size) {
- FPDFAPI_FlateEnd(context);
+ FlateEnd(context);
return;
}
@@ -555,8 +558,8 @@ void FlateUncompress(const uint8_t* src_buf,
cur_buf = guess_buf.get() + old_size;
buf_size = guess_size - old_size;
}
- dest_size = FPDFAPI_FlateGetTotalOut(context);
- offset = FPDFAPI_FlateGetTotalIn(context);
+ dest_size = FlateGetPossiblyTruncatedTotalOut(context);
+ offset = FlateGetPossiblyTruncatedTotalIn(context);
if (guess_size / 2 > dest_size) {
{
uint8_t* new_buf =
@@ -571,14 +574,9 @@ void FlateUncompress(const uint8_t* src_buf,
std::vector<uint8_t*> result_tmp_bufs;
uint8_t* cur_buf = guess_buf.release();
while (1) {
- int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size);
- int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context);
- if (ret != Z_OK) {
- last_buf_size = buf_size - avail_buf_size;
- result_tmp_bufs.push_back(cur_buf);
- break;
- }
- if (avail_buf_size != 0) {
+ uint32_t ret = FlateOutput(context, cur_buf, buf_size);
+ uint32_t avail_buf_size = FlateGetAvailOut(context);
+ if (ret != Z_OK || avail_buf_size != 0) {
last_buf_size = buf_size - avail_buf_size;
result_tmp_bufs.push_back(cur_buf);
break;
@@ -591,8 +589,8 @@ void FlateUncompress(const uint8_t* src_buf,
// The TotalOut size returned from the library may not be big enough to
// handle the content the library returns. We can only handle items
// up to 4GB in size.
- dest_size = FPDFAPI_FlateGetTotalOut(context);
- offset = FPDFAPI_FlateGetTotalIn(context);
+ dest_size = FlateGetPossiblyTruncatedTotalOut(context);
+ offset = FlateGetPossiblyTruncatedTotalIn(context);
if (result_tmp_bufs.size() == 1) {
dest_buf = result_tmp_bufs[0];
} else {
@@ -602,19 +600,20 @@ void FlateUncompress(const uint8_t* src_buf,
for (size_t i = 0; i < result_tmp_bufs.size(); i++) {
uint8_t* tmp_buf = result_tmp_bufs[i];
uint32_t tmp_buf_size = buf_size;
- if (i == result_tmp_bufs.size() - 1) {
+ if (i == result_tmp_bufs.size() - 1)
tmp_buf_size = last_buf_size;
- }
+
uint32_t cp_size = std::min(tmp_buf_size, remaining);
FXSYS_memcpy(result_buf + result_pos, tmp_buf, cp_size);
result_pos += cp_size;
remaining -= cp_size;
+
FX_Free(result_tmp_bufs[i]);
}
dest_buf = result_buf;
}
}
- FPDFAPI_FlateEnd(context);
+ FlateEnd(context);
}
} // namespace
@@ -663,15 +662,16 @@ CCodec_FlateScanlineDecoder::CCodec_FlateScanlineDecoder() {
m_pPredictRaw = nullptr;
m_LeftOver = 0;
}
+
CCodec_FlateScanlineDecoder::~CCodec_FlateScanlineDecoder() {
FX_Free(m_pScanline);
FX_Free(m_pLastLine);
FX_Free(m_pPredictBuffer);
FX_Free(m_pPredictRaw);
- if (m_pFlate) {
- FPDFAPI_FlateEnd(m_pFlate);
- }
+ if (m_pFlate)
+ FlateEnd(m_pFlate);
}
+
void CCodec_FlateScanlineDecoder::Create(const uint8_t* src_buf,
uint32_t src_size,
int width,
@@ -716,28 +716,30 @@ void CCodec_FlateScanlineDecoder::Create(const uint8_t* src_buf,
}
}
}
+
bool CCodec_FlateScanlineDecoder::v_Rewind() {
- if (m_pFlate) {
- FPDFAPI_FlateEnd(m_pFlate);
- }
- m_pFlate = FPDFAPI_FlateInit(my_alloc_func, my_free_func);
- if (!m_pFlate) {
+ if (m_pFlate)
+ FlateEnd(m_pFlate);
+
+ m_pFlate = FlateInit();
+ if (!m_pFlate)
return false;
- }
- FPDFAPI_FlateInput(m_pFlate, m_SrcBuf, m_SrcSize);
+
+ FlateInput(m_pFlate, m_SrcBuf, m_SrcSize);
m_LeftOver = 0;
return true;
}
+
uint8_t* CCodec_FlateScanlineDecoder::v_GetNextLine() {
if (m_Predictor) {
if (m_Pitch == m_PredictPitch) {
if (m_Predictor == 2) {
- FPDFAPI_FlateOutput(m_pFlate, m_pPredictRaw, m_PredictPitch + 1);
+ FlateOutput(m_pFlate, m_pPredictRaw, m_PredictPitch + 1);
PNG_PredictLine(m_pScanline, m_pPredictRaw, m_pLastLine,
m_BitsPerComponent, m_Colors, m_Columns);
FXSYS_memcpy(m_pLastLine, m_pScanline, m_PredictPitch);
} else {
- FPDFAPI_FlateOutput(m_pFlate, m_pScanline, m_Pitch);
+ FlateOutput(m_pFlate, m_pScanline, m_Pitch);
TIFF_PredictLine(m_pScanline, m_PredictPitch, m_bpc, m_nComps,
m_OutputWidth);
}
@@ -754,12 +756,12 @@ uint8_t* CCodec_FlateScanlineDecoder::v_GetNextLine() {
}
while (bytes_to_go) {
if (m_Predictor == 2) {
- FPDFAPI_FlateOutput(m_pFlate, m_pPredictRaw, m_PredictPitch + 1);
+ FlateOutput(m_pFlate, m_pPredictRaw, m_PredictPitch + 1);
PNG_PredictLine(m_pPredictBuffer, m_pPredictRaw, m_pLastLine,
m_BitsPerComponent, m_Colors, m_Columns);
FXSYS_memcpy(m_pLastLine, m_pPredictBuffer, m_PredictPitch);
} else {
- FPDFAPI_FlateOutput(m_pFlate, m_pPredictBuffer, m_PredictPitch);
+ FlateOutput(m_pFlate, m_pPredictBuffer, m_PredictPitch);
TIFF_PredictLine(m_pPredictBuffer, m_PredictPitch, m_BitsPerComponent,
m_Colors, m_Columns);
}
@@ -772,12 +774,13 @@ uint8_t* CCodec_FlateScanlineDecoder::v_GetNextLine() {
}
}
} else {
- FPDFAPI_FlateOutput(m_pFlate, m_pScanline, m_Pitch);
+ FlateOutput(m_pFlate, m_pScanline, m_Pitch);
}
return m_pScanline;
}
+
uint32_t CCodec_FlateScanlineDecoder::GetSrcOffset() {
- return FPDFAPI_FlateGetTotalIn(m_pFlate);
+ return FlateGetPossiblyTruncatedTotalIn(m_pFlate);
}
std::unique_ptr<CCodec_ScanlineDecoder> CCodec_FlateModule::CreateDecoder(
@@ -859,7 +862,7 @@ bool CCodec_FlateModule::Encode(const uint8_t* src_buf,
*dest_size = src_size + src_size / 1000 + 12;
*dest_buf = FX_Alloc(uint8_t, *dest_size);
unsigned long temp_size = *dest_size;
- if (!FPDFAPI_FlateCompress(*dest_buf, &temp_size, src_buf, src_size))
+ if (!FlateCompress(*dest_buf, &temp_size, src_buf, src_size))
return false;
*dest_size = (uint32_t)temp_size;