summaryrefslogtreecommitdiff
path: root/core/fxcodec/codec/fx_codec_progress.cpp
diff options
context:
space:
mode:
authorRyan Harrison <rharrison@chromium.org>2018-01-17 18:12:16 +0000
committerChromium commit bot <commit-bot@chromium.org>2018-01-17 18:12:16 +0000
commitb73a96938d0fc932a9d498359c98f4cf6ef34160 (patch)
tree9223a1b178dc7ceedff28dd96df294d3f3eaddca /core/fxcodec/codec/fx_codec_progress.cpp
parent6d6a243893532de40f636dbdc61d10c04ab019fb (diff)
downloadpdfium-b73a96938d0fc932a9d498359c98f4cf6ef34160.tar.xz
Correctly handle errors when starting jpeg codec
The current implementation treats both returning false and longjmp'ing out of jpeg_start_decompress as indicating that the decompression has paused and needs more data. This is incorrect, in reality only the false return value indicates this. The longjmp path indicates a fatal error in the processing of the jpeg. The default implementation actually calls exit() in this case, and the documentation explicitly calls out that in this case recovery isn't possible and the decode process will have to start from scratch. This resolves a situation where the progressive decoder would get a malformed jpeg and keep on grabbing blocks from it and try to start decoding it. This would eventually fail when it ran out of data to read, but would cause a large memory leak and a crash on the MSAN fuzzers. BUG=pdfium:986,chromium:798665 Change-Id: Ifd2ed7a2dc46fa20bab34e9c461a8d4c4718c4d7 Reviewed-on: https://pdfium-review.googlesource.com/23072 Reviewed-by: dsinclair <dsinclair@chromium.org> Commit-Queue: Ryan Harrison <rharrison@chromium.org>
Diffstat (limited to 'core/fxcodec/codec/fx_codec_progress.cpp')
-rw-r--r--core/fxcodec/codec/fx_codec_progress.cpp13
1 files changed, 10 insertions, 3 deletions
diff --git a/core/fxcodec/codec/fx_codec_progress.cpp b/core/fxcodec/codec/fx_codec_progress.cpp
index ea9cdd2ea9..c9436186ab 100644
--- a/core/fxcodec/codec/fx_codec_progress.cpp
+++ b/core/fxcodec/codec/fx_codec_progress.cpp
@@ -1869,10 +1869,15 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::StartDecode(
case FXCODEC_IMAGE_JPG: {
int down_scale = 1;
GetDownScale(down_scale);
+ // Setting jump marker before calling StartScanLine, since a longjmp to
+ // the marker indicates a fatal error.
+ if (setjmp(*m_pJpegContext->GetJumpMark()) == -1)
+ return FXCODEC_STATUS_ERROR;
+
CCodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule();
- bool bStart =
+ bool startStatus =
pJpegModule->StartScanline(m_pJpegContext.get(), down_scale);
- while (!bStart) {
+ while (!startStatus) {
FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR;
if (!JpegReadMoreData(pJpegModule, error_status)) {
m_pDeviceBitmap = nullptr;
@@ -1880,7 +1885,9 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::StartDecode(
m_status = error_status;
return m_status;
}
- bStart = pJpegModule->StartScanline(m_pJpegContext.get(), down_scale);
+
+ startStatus =
+ pJpegModule->StartScanline(m_pJpegContext.get(), down_scale);
}
int scanline_size = (m_SrcWidth + down_scale - 1) / down_scale;
scanline_size = (scanline_size * m_SrcComponents + 3) / 4 * 4;