Index: core/src/fxcodec/codec/fx_codec_flate.cpp |
diff --git a/core/src/fxcodec/codec/fx_codec_flate.cpp b/core/src/fxcodec/codec/fx_codec_flate.cpp |
index 76514bae2b961374acba387fc8df137a5a19545e..bbee167f3dafbadfa941c368b89f7cd79d79ac2d 100644 |
--- a/core/src/fxcodec/codec/fx_codec_flate.cpp |
+++ b/core/src/fxcodec/codec/fx_codec_flate.cpp |
@@ -742,6 +742,7 @@ FX_DWORD CCodec_FlateScanlineDecoder::GetSrcOffset() |
static void FlateUncompress(FX_LPCBYTE src_buf, FX_DWORD src_size, FX_DWORD orig_size, |
FX_LPBYTE& dest_buf, FX_DWORD& dest_size, FX_DWORD& offset) |
{ |
+ const FX_BOOL useOldImpl = src_size < 10240; |
FX_DWORD guess_size = orig_size ? orig_size : src_size * 2; |
FX_DWORD alloc_step = orig_size ? 10240 : (src_size < 10240 ? 10240 : src_size); |
static const FX_DWORD kMaxInitialAllocSize = 10000000; |
@@ -749,87 +750,88 @@ static void FlateUncompress(FX_LPCBYTE src_buf, FX_DWORD src_size, FX_DWORD orig |
guess_size = kMaxInitialAllocSize; |
alloc_step = kMaxInitialAllocSize; |
} |
+ FX_DWORD buf_size = guess_size; |
+ FX_DWORD last_buf_size = buf_size; |
+ void* context = nullptr; |
+ |
FX_LPBYTE guess_buf = FX_Alloc(FX_BYTE, guess_size + 1); |
- if (!guess_buf) { |
- dest_buf = NULL; |
- dest_size = 0; |
- return; |
- } |
+ FX_LPBYTE cur_buf = guess_buf; |
+ if (!guess_buf) |
+ goto fail; |
guess_buf[guess_size] = '\0'; |
- FX_BOOL useOldImpl = src_size < 10240; |
- void* context = FPDFAPI_FlateInit(my_alloc_func, my_free_func); |
- if (context == NULL) { |
- dest_buf = NULL; |
- dest_size = 0; |
- return ; |
- } |
+ context = FPDFAPI_FlateInit(my_alloc_func, my_free_func); |
+ if (!context) |
+ goto fail; |
FPDFAPI_FlateInput(context, src_buf, src_size); |
- CFX_ArrayTemplate<FX_LPBYTE> result_tmp_bufs; |
- FX_LPBYTE buf = guess_buf; |
- FX_DWORD buf_size = guess_size; |
- FX_DWORD last_buf_size = buf_size; |
- while (1) { |
- FX_INT32 ret = FPDFAPI_FlateOutput(context, buf, buf_size); |
- FX_INT32 avail_buf_size = FPDFAPI_FlateGetAvailOut(context); |
- if (!useOldImpl) { |
+ if (useOldImpl) { |
+ while (1) { |
+ FX_INT32 ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size); |
+ if (ret != Z_OK) |
+ break; |
+ FX_INT32 avail_buf_size = FPDFAPI_FlateGetAvailOut(context); |
+ if (avail_buf_size != 0) |
+ break; |
+ |
+ // |avail_buf_size| == 0 case. |
+ FX_DWORD old_size = guess_size; |
+ guess_size += alloc_step; |
+ if (guess_size < old_size || guess_size + 1 < guess_size) |
+ goto fail; |
+ guess_buf = FX_Realloc(FX_BYTE, guess_buf, guess_size + 1); |
+ if (!guess_buf) |
+ goto fail; |
+ guess_buf[guess_size] = '\0'; |
+ cur_buf = guess_buf + old_size; |
+ buf_size = guess_size - old_size; |
+ } |
+ dest_size = FPDFAPI_FlateGetTotalOut(context); |
+ offset = FPDFAPI_FlateGetTotalIn(context); |
+ if (guess_size / 2 > dest_size) { |
+ guess_buf = FX_Realloc(FX_BYTE, guess_buf, dest_size + 1); |
+ if (!guess_buf) |
+ goto fail; |
+ guess_size = dest_size; |
+ guess_buf[guess_size] = '\0'; |
+ } |
+ dest_buf = guess_buf; |
+ } else { |
+ CFX_ArrayTemplate<FX_LPBYTE> result_tmp_bufs; |
+ while (1) { |
+ FX_INT32 ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size); |
+ FX_INT32 avail_buf_size = FPDFAPI_FlateGetAvailOut(context); |
if (ret != Z_OK) { |
last_buf_size = buf_size - avail_buf_size; |
- result_tmp_bufs.Add(buf); |
+ result_tmp_bufs.Add(cur_buf); |
break; |
} |
- if (avail_buf_size == 0) { |
- result_tmp_bufs.Add(buf); |
- buf = NULL; |
- buf = FX_Alloc(FX_BYTE, buf_size + 1); |
- if (!buf) { |
- dest_buf = NULL; |
- dest_size = 0; |
- return; |
- } |
- buf[buf_size] = '\0'; |
- } else { |
+ if (avail_buf_size != 0) { |
last_buf_size = buf_size - avail_buf_size; |
- result_tmp_bufs.Add(buf); |
- buf = NULL; |
- break; |
- } |
- } else { |
- if (ret != Z_OK) { |
+ result_tmp_bufs.Add(cur_buf); |
break; |
} |
- if (avail_buf_size == 0) { |
- FX_DWORD old_size = guess_size; |
- guess_size += alloc_step; |
- if (guess_size < old_size || guess_size + 1 < guess_size) { |
- dest_buf = NULL; |
- dest_size = 0; |
- return; |
- } |
- guess_buf = FX_Realloc(FX_BYTE, guess_buf, guess_size + 1); |
- if (!guess_buf) { |
- dest_buf = NULL; |
- dest_size = 0; |
- return; |
+ |
+ // |avail_buf_size| == 0 case. |
+ result_tmp_bufs.Add(cur_buf); |
+ cur_buf = FX_Alloc(FX_BYTE, buf_size + 1); |
+ if (!cur_buf) { |
+ for (FX_INT32 i = 0; i < result_tmp_bufs.GetSize(); i++) { |
+ FX_Free(result_tmp_bufs[i]); |
} |
- guess_buf[guess_size] = '\0'; |
- buf = guess_buf + old_size; |
- buf_size = guess_size - old_size; |
- } else { |
- break; |
+ goto fail; |
} |
+ cur_buf[buf_size] = '\0'; |
} |
- } |
- dest_size = FPDFAPI_FlateGetTotalOut(context); |
- offset = FPDFAPI_FlateGetTotalIn(context); |
- if (!useOldImpl) { |
+ dest_size = FPDFAPI_FlateGetTotalOut(context); |
+ offset = FPDFAPI_FlateGetTotalIn(context); |
if (result_tmp_bufs.GetSize() == 1) { |
dest_buf = result_tmp_bufs[0]; |
} else { |
FX_LPBYTE result_buf = FX_Alloc(FX_BYTE, dest_size); |
if (!result_buf) { |
- dest_buf = NULL; |
- dest_size = 0; |
- return; |
+ for (FX_INT32 i = 0; i < result_tmp_bufs.GetSize(); i++) { |
+ FX_Free(result_tmp_bufs[i]); |
+ } |
+ goto fail; |
} |
FX_DWORD result_pos = 0; |
for (FX_INT32 i = 0; i < result_tmp_bufs.GetSize(); i++) { |
@@ -840,27 +842,19 @@ static void FlateUncompress(FX_LPCBYTE src_buf, FX_DWORD src_size, FX_DWORD orig |
} |
FXSYS_memcpy32(result_buf + result_pos, tmp_buf, tmp_buf_size); |
result_pos += tmp_buf_size; |
- FX_Free(tmp_buf); |
- tmp_buf = NULL; |
- result_tmp_bufs[i] = NULL; |
+ FX_Free(result_tmp_bufs[i]); |
} |
dest_buf = result_buf; |
} |
- } else { |
- if (guess_size / 2 > dest_size) { |
- guess_buf = FX_Realloc(FX_BYTE, guess_buf, dest_size + 1); |
- if (!guess_buf) { |
- dest_buf = NULL; |
- dest_size = 0; |
- return; |
- } |
- guess_size = dest_size; |
- guess_buf[guess_size] = '\0'; |
- } |
- dest_buf = guess_buf; |
} |
FPDFAPI_FlateEnd(context); |
- context = NULL; |
+ return; |
+ |
+fail: |
+ FX_Free(guess_buf); |
+ dest_buf = nullptr; |
+ dest_size = 0; |
+ return; |
} |
ICodec_ScanlineDecoder* CCodec_FlateModule::CreateDecoder(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height, |
int nComps, int bpc, int predictor, int Colors, int BitsPerComponent, int Columns) |