From 3e794595fdcb90f47e80cd8c69f0a1f09176efa2 Mon Sep 17 00:00:00 2001 From: Chris Dalton Date: Fri, 1 Dec 2017 13:11:09 -0700 Subject: Fix setjmp/longjump usage in JPEG error handling Pushes and pops nested jmp_bufs in a stack for proper handling of nested setjmp calls. Ensures longjmp is never called to a stack frame that has exited. Bug: skia: Change-Id: I18d62504f6e5e3eb53026c3b48617b92ea74b905 Reviewed-on: https://skia-review.googlesource.com/79241 Reviewed-by: Leon Scroggins Commit-Queue: Leon Scroggins --- src/images/SkJPEGWriteUtility.cpp | 5 ++++- src/images/SkJpegEncoder.cpp | 9 ++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'src/images') diff --git a/src/images/SkJPEGWriteUtility.cpp b/src/images/SkJPEGWriteUtility.cpp index aa0d3ec4d9..118662d68d 100644 --- a/src/images/SkJPEGWriteUtility.cpp +++ b/src/images/SkJPEGWriteUtility.cpp @@ -60,5 +60,8 @@ void skjpeg_error_exit(j_common_ptr cinfo) { /* Let the memory manager delete any temp files before we die */ jpeg_destroy(cinfo); - longjmp(error->fJmpBuf, -1); + if (error->fJmpBufStack.empty()) { + SK_ABORT("JPEG error with no jmp_buf set."); + } + longjmp(*error->fJmpBufStack.back(), -1); } diff --git a/src/images/SkJpegEncoder.cpp b/src/images/SkJpegEncoder.cpp index 9fade2449a..1c542a66a7 100644 --- a/src/images/SkJpegEncoder.cpp +++ b/src/images/SkJpegEncoder.cpp @@ -40,7 +40,7 @@ public: jpeg_compress_struct* cinfo() { return &fCInfo; } - jmp_buf& jmpBuf() { return fErrMgr.fJmpBuf; } + skjpeg_error_mgr* errorMgr() { return &fErrMgr; } transform_scanline_proc proc() const { return fProc; } @@ -187,7 +187,9 @@ std::unique_ptr SkJpegEncoder::Make(SkWStream* dst, const SkPixmap& s } std::unique_ptr encoderMgr = SkJpegEncoderMgr::Make(dst); - if (setjmp(encoderMgr->jmpBuf())) { + + skjpeg_error_mgr::AutoPushJmpBuf jmp(encoderMgr->errorMgr()); + if (setjmp(jmp)) { return nullptr; } @@ -224,7 +226,8 @@ SkJpegEncoder::SkJpegEncoder(std::unique_ptr encoderMgr, const SkJpegEncoder::~SkJpegEncoder() {} bool SkJpegEncoder::onEncodeRows(int numRows) { - if (setjmp(fEncoderMgr->jmpBuf())) { + skjpeg_error_mgr::AutoPushJmpBuf jmp(fEncoderMgr->errorMgr()); + if (setjmp(jmp)) { return false; } -- cgit v1.2.3