1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2017 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker 9*c8dee2aaSAndroid Build Coastguard Worker #ifndef SkJpegPriv_DEFINED 10*c8dee2aaSAndroid Build Coastguard Worker #define SkJpegPriv_DEFINED 11*c8dee2aaSAndroid Build Coastguard Worker 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkEncodedOrigin.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkStream.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTArray.h" 15*c8dee2aaSAndroid Build Coastguard Worker 16*c8dee2aaSAndroid Build Coastguard Worker #include <setjmp.h> 17*c8dee2aaSAndroid Build Coastguard Worker // stdio is needed for jpeglib 18*c8dee2aaSAndroid Build Coastguard Worker #include <stdio.h> 19*c8dee2aaSAndroid Build Coastguard Worker 20*c8dee2aaSAndroid Build Coastguard Worker extern "C" { 21*c8dee2aaSAndroid Build Coastguard Worker #include "jpeglib.h" // NO_G3_REWRITE 22*c8dee2aaSAndroid Build Coastguard Worker #include "jerror.h" // NO_G3_REWRITE 23*c8dee2aaSAndroid Build Coastguard Worker } 24*c8dee2aaSAndroid Build Coastguard Worker 25*c8dee2aaSAndroid Build Coastguard Worker /* 26*c8dee2aaSAndroid Build Coastguard Worker * Error handling struct 27*c8dee2aaSAndroid Build Coastguard Worker */ 28*c8dee2aaSAndroid Build Coastguard Worker struct skjpeg_error_mgr : public jpeg_error_mgr { 29*c8dee2aaSAndroid Build Coastguard Worker class AutoPushJmpBuf { 30*c8dee2aaSAndroid Build Coastguard Worker public: AutoPushJmpBufskjpeg_error_mgr31*c8dee2aaSAndroid Build Coastguard Worker AutoPushJmpBuf(skjpeg_error_mgr* mgr) : fMgr(mgr) { fMgr->push(&fJmpBuf); } ~AutoPushJmpBufskjpeg_error_mgr32*c8dee2aaSAndroid Build Coastguard Worker ~AutoPushJmpBuf() { fMgr->pop(&fJmpBuf); } 33*c8dee2aaSAndroid Build Coastguard Worker operator jmp_buf&() { return fJmpBuf; } 34*c8dee2aaSAndroid Build Coastguard Worker 35*c8dee2aaSAndroid Build Coastguard Worker private: 36*c8dee2aaSAndroid Build Coastguard Worker skjpeg_error_mgr* const fMgr; 37*c8dee2aaSAndroid Build Coastguard Worker jmp_buf fJmpBuf; 38*c8dee2aaSAndroid Build Coastguard Worker }; 39*c8dee2aaSAndroid Build Coastguard Worker 40*c8dee2aaSAndroid Build Coastguard Worker // When libjpeg initializes the fields of a `jpeg_error_mgr` (in `jpeg_std_error`), it 41*c8dee2aaSAndroid Build Coastguard Worker // leaves the msg_parm fields uninitialized. This is safe, but confuses MSAN, so we 42*c8dee2aaSAndroid Build Coastguard Worker // explicitly zero out the structure when constructing it. (crbug.com/oss-fuzz/68691) skjpeg_error_mgrskjpeg_error_mgr43*c8dee2aaSAndroid Build Coastguard Worker skjpeg_error_mgr() : jpeg_error_mgr({}) {} 44*c8dee2aaSAndroid Build Coastguard Worker pushskjpeg_error_mgr45*c8dee2aaSAndroid Build Coastguard Worker void push(jmp_buf* j) { 46*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(fStack[3] == nullptr); // if we assert here, the stack has overflowed 47*c8dee2aaSAndroid Build Coastguard Worker fStack[3] = fStack[2]; 48*c8dee2aaSAndroid Build Coastguard Worker fStack[2] = fStack[1]; 49*c8dee2aaSAndroid Build Coastguard Worker fStack[1] = fStack[0]; 50*c8dee2aaSAndroid Build Coastguard Worker fStack[0] = j; 51*c8dee2aaSAndroid Build Coastguard Worker } 52*c8dee2aaSAndroid Build Coastguard Worker popskjpeg_error_mgr53*c8dee2aaSAndroid Build Coastguard Worker void pop(jmp_buf* j) { 54*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(fStack[0] == j); // if we assert here, the pushes and pops were unbalanced 55*c8dee2aaSAndroid Build Coastguard Worker fStack[0] = fStack[1]; 56*c8dee2aaSAndroid Build Coastguard Worker fStack[1] = fStack[2]; 57*c8dee2aaSAndroid Build Coastguard Worker fStack[2] = fStack[3]; 58*c8dee2aaSAndroid Build Coastguard Worker fStack[3] = nullptr; 59*c8dee2aaSAndroid Build Coastguard Worker } 60*c8dee2aaSAndroid Build Coastguard Worker 61*c8dee2aaSAndroid Build Coastguard Worker jmp_buf* fStack[4] = {}; 62*c8dee2aaSAndroid Build Coastguard Worker }; 63*c8dee2aaSAndroid Build Coastguard Worker 64*c8dee2aaSAndroid Build Coastguard Worker #endif 65