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 <scroggo@google.com>
Commit-Queue: Leon Scroggins <scroggo@google.com>
diff --git a/src/images/SkJpegEncoder.cpp b/src/images/SkJpegEncoder.cpp
index 9fade24..1c542a6 100644
--- a/src/images/SkJpegEncoder.cpp
+++ b/src/images/SkJpegEncoder.cpp
@@ -40,7 +40,7 @@
 
     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<SkJpegEncoderMgr> 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() {}
 
 bool SkJpegEncoder::onEncodeRows(int numRows) {
-    if (setjmp(fEncoderMgr->jmpBuf())) {
+    skjpeg_error_mgr::AutoPushJmpBuf jmp(fEncoderMgr->errorMgr());
+    if (setjmp(jmp)) {
         return false;
     }