Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: core/src/fxcodec/jbig2/JBig2_Context.cpp

Issue 1365903002: Fix a leak in CJBig2_Context. (Closed) Base URL: https://pdfium.googlesource.com/pdfium@master
Patch Set: CJBig2_Context::decodeFile cannot be reached (please sanity check) Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 PDFium Authors. All rights reserved. 1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 6
7 #include <list> 7 #include <list>
8 #include "JBig2_Context.h" 8 #include "JBig2_Context.h"
9 9
10 // Implement a very small least recently used (LRU) cache. It is very 10 // Implement a very small least recently used (LRU) cache. It is very
11 // common for a JBIG2 dictionary to span multiple pages in a PDF file, 11 // common for a JBIG2 dictionary to span multiple pages in a PDF file,
12 // and we do not want to decode the same dictionary over and over 12 // and we do not want to decode the same dictionary over and over
13 // again. We key off of the memory location of the dictionary. The 13 // again. We key off of the memory location of the dictionary. The
14 // list keeps track of the freshness of entries, with freshest ones 14 // list keeps track of the freshness of entries, with freshest ones
15 // at the front. Even a tiny cache size like 2 makes a dramatic 15 // at the front. Even a tiny cache size like 2 makes a dramatic
16 // difference for typical JBIG2 documents. 16 // difference for typical JBIG2 documents.
17 const int kSymbolDictCacheMaxSize = 2; 17 const int kSymbolDictCacheMaxSize = 2;
18 18
19 CJBig2_Context* CJBig2_Context::CreateContext( 19 CJBig2_Context* CJBig2_Context::CreateContext(
20 const uint8_t* pGlobalData, 20 const uint8_t* pGlobalData,
21 FX_DWORD dwGlobalLength, 21 FX_DWORD dwGlobalLength,
22 const uint8_t* pData, 22 const uint8_t* pData,
23 FX_DWORD dwLength, 23 FX_DWORD dwLength,
24 int32_t nStreamType,
25 std::list<CJBig2_CachePair>* pSymbolDictCache, 24 std::list<CJBig2_CachePair>* pSymbolDictCache,
26 IFX_Pause* pPause) { 25 IFX_Pause* pPause) {
27 return new CJBig2_Context(pGlobalData, dwGlobalLength, pData, dwLength, 26 return new CJBig2_Context(pGlobalData, dwGlobalLength, pData, dwLength,
28 nStreamType, pSymbolDictCache, pPause); 27 pSymbolDictCache, pPause);
29 } 28 }
30 void CJBig2_Context::DestroyContext(CJBig2_Context* pContext) { 29 void CJBig2_Context::DestroyContext(CJBig2_Context* pContext) {
31 delete pContext; 30 delete pContext;
32 } 31 }
33 CJBig2_Context::CJBig2_Context(const uint8_t* pGlobalData, 32 CJBig2_Context::CJBig2_Context(const uint8_t* pGlobalData,
34 FX_DWORD dwGlobalLength, 33 FX_DWORD dwGlobalLength,
35 const uint8_t* pData, 34 const uint8_t* pData,
36 FX_DWORD dwLength, 35 FX_DWORD dwLength,
37 int32_t nStreamType,
38 std::list<CJBig2_CachePair>* pSymbolDictCache, 36 std::list<CJBig2_CachePair>* pSymbolDictCache,
39 IFX_Pause* pPause) { 37 IFX_Pause* pPause) {
40 if (pGlobalData && (dwGlobalLength > 0)) { 38 if (pGlobalData && (dwGlobalLength > 0)) {
41 m_pGlobalContext = 39 m_pGlobalContext = new CJBig2_Context(
42 new CJBig2_Context(NULL, 0, pGlobalData, dwGlobalLength, 40 nullptr, 0, pGlobalData, dwGlobalLength, pSymbolDictCache, pPause);
43 JBIG2_EMBED_STREAM, pSymbolDictCache, pPause);
44 } else { 41 } else {
45 m_pGlobalContext = NULL; 42 m_pGlobalContext = nullptr;
46 } 43 }
44
47 m_pStream = new CJBig2_BitStream(pData, dwLength); 45 m_pStream = new CJBig2_BitStream(pData, dwLength);
48 m_nStreamType = nStreamType;
49 m_nState = JBIG2_OUT_OF_PAGE; 46 m_nState = JBIG2_OUT_OF_PAGE;
50 m_pPage = NULL; 47 m_pPage = NULL;
51 m_bBufSpecified = FALSE; 48 m_bBufSpecified = FALSE;
52 m_pPause = pPause; 49 m_pPause = pPause;
53 m_nSegmentDecoded = 0; 50 m_nSegmentDecoded = 0;
54 m_PauseStep = 10; 51 m_PauseStep = 10;
55 m_pArithDecoder = NULL; 52 m_pArithDecoder = NULL;
56 m_pGRD = NULL; 53 m_pGRD = NULL;
57 m_gbContext = NULL; 54 m_gbContext = NULL;
58 m_dwOffset = 0; 55 m_dwOffset = 0;
(...skipping 10 matching lines...) Expand all
69 delete m_pGlobalContext; 66 delete m_pGlobalContext;
70 m_pGlobalContext = NULL; 67 m_pGlobalContext = NULL;
71 if (m_bBufSpecified) { 68 if (m_bBufSpecified) {
72 delete m_pPage; 69 delete m_pPage;
73 } 70 }
74 m_pPage = NULL; 71 m_pPage = NULL;
75 delete m_pStream; 72 delete m_pStream;
76 m_pStream = NULL; 73 m_pStream = NULL;
77 } 74 }
78 75
79 int32_t CJBig2_Context::decodeFile(IFX_Pause* pPause) {
80 if (m_pStream->getByteLeft() < 8)
81 return JBIG2_ERROR_TOO_SHORT;
82
83 const uint8_t fileID[] = {0x97, 0x4A, 0x42, 0x32, 0x0D, 0x0A, 0x1A, 0x0A};
84 if (JBIG2_memcmp(m_pStream->getPointer(), fileID, 8) != 0)
85 return JBIG2_ERROR_FILE_FORMAT;
86
87 m_pStream->offset(8);
88
89 uint8_t cFlags;
90 if (m_pStream->read1Byte(&cFlags) != 0)
91 return JBIG2_ERROR_TOO_SHORT;
92
93 if (!(cFlags & 0x02)) {
94 FX_DWORD dwTemp;
95 if (m_pStream->readInteger(&dwTemp) != 0)
96 return JBIG2_ERROR_TOO_SHORT;
97
98 if (dwTemp > 0) {
99 m_PageInfoList.clear();
100 m_PageInfoList.resize(dwTemp);
101 }
102 }
103
104 if (cFlags & 0x01) {
105 m_nStreamType = JBIG2_SQUENTIAL_STREAM;
106 return decode_SquentialOrgnazation(pPause);
107 }
108
109 m_nStreamType = JBIG2_RANDOM_STREAM;
110 return decode_RandomOrgnazation_FirstPage(pPause);
111 }
112
113 int32_t CJBig2_Context::decode_SquentialOrgnazation(IFX_Pause* pPause) { 76 int32_t CJBig2_Context::decode_SquentialOrgnazation(IFX_Pause* pPause) {
114 int32_t nRet; 77 int32_t nRet;
115 if (m_pStream->getByteLeft() <= 0) 78 if (m_pStream->getByteLeft() <= 0)
116 return JBIG2_END_OF_FILE; 79 return JBIG2_END_OF_FILE;
117 80
118 while (m_pStream->getByteLeft() >= JBIG2_MIN_SEGMENT_SIZE) { 81 while (m_pStream->getByteLeft() >= JBIG2_MIN_SEGMENT_SIZE) {
119 if (!m_pSegment) { 82 if (!m_pSegment) {
120 m_pSegment.reset(new CJBig2_Segment); 83 m_pSegment.reset(new CJBig2_Segment);
121 nRet = parseSegmentHeader(m_pSegment.get()); 84 nRet = parseSegmentHeader(m_pSegment.get());
122 if (nRet != JBIG2_SUCCESS) { 85 if (nRet != JBIG2_SUCCESS) {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 m_ProcessingStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE; 182 m_ProcessingStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
220 return nRet; 183 return nRet;
221 } 184 }
222 int ret = Continue(pPause); 185 int ret = Continue(pPause);
223 return ret; 186 return ret;
224 } 187 }
225 int32_t CJBig2_Context::Continue(IFX_Pause* pPause) { 188 int32_t CJBig2_Context::Continue(IFX_Pause* pPause) {
226 m_ProcessingStatus = FXCODEC_STATUS_DECODE_READY; 189 m_ProcessingStatus = FXCODEC_STATUS_DECODE_READY;
227 int32_t nRet; 190 int32_t nRet;
228 if (m_PauseStep <= 1) { 191 if (m_PauseStep <= 1) {
229 switch (m_nStreamType) { 192 nRet = decode_EmbedOrgnazation(pPause);
230 case JBIG2_FILE_STREAM:
231 nRet = decodeFile(pPause);
232 break;
233 case JBIG2_SQUENTIAL_STREAM:
234 nRet = decode_SquentialOrgnazation(pPause);
235 break;
236 case JBIG2_RANDOM_STREAM:
237 if (m_bFirstPage) {
238 nRet = decode_RandomOrgnazation_FirstPage(pPause);
239 } else {
240 nRet = decode_RandomOrgnazation(pPause);
241 }
242 break;
243 case JBIG2_EMBED_STREAM:
244 nRet = decode_EmbedOrgnazation(pPause);
245 break;
246 default:
247 m_ProcessingStatus = FXCODEC_STATUS_ERROR;
248 return JBIG2_ERROR_STREAM_TYPE;
249 }
250 } else if (m_PauseStep == 2) { 193 } else if (m_PauseStep == 2) {
251 nRet = decode_SquentialOrgnazation(pPause); 194 nRet = decode_SquentialOrgnazation(pPause);
252 } else if (m_PauseStep == 3) { 195 } else if (m_PauseStep == 3) {
253 nRet = decode_RandomOrgnazation_FirstPage(pPause); 196 nRet = decode_RandomOrgnazation_FirstPage(pPause);
254 } else if (m_PauseStep == 4) { 197 } else if (m_PauseStep == 4) {
255 nRet = decode_RandomOrgnazation(pPause); 198 nRet = decode_RandomOrgnazation(pPause);
256 } else if (m_PauseStep == 5) { 199 } else if (m_PauseStep == 5) {
257 m_ProcessingStatus = FXCODEC_STATUS_DECODE_FINISH; 200 m_ProcessingStatus = FXCODEC_STATUS_DECODE_FINISH;
258 return JBIG2_SUCCESS; 201 return JBIG2_SUCCESS;
259 } 202 }
260 if (m_ProcessingStatus == FXCODEC_STATUS_DECODE_TOBECONTINUE) { 203 if (m_ProcessingStatus == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
261 return nRet; 204 return nRet;
262 } 205 }
263 m_PauseStep = 5; 206 m_PauseStep = 5;
264 if (!m_bBufSpecified && nRet == JBIG2_SUCCESS) { 207 if (!m_bBufSpecified && nRet == JBIG2_SUCCESS) {
265 m_ProcessingStatus = FXCODEC_STATUS_DECODE_FINISH; 208 m_ProcessingStatus = FXCODEC_STATUS_DECODE_FINISH;
266 return JBIG2_SUCCESS; 209 return JBIG2_SUCCESS;
267 } 210 }
268 if (nRet == JBIG2_SUCCESS) { 211 if (nRet == JBIG2_SUCCESS) {
269 m_ProcessingStatus = FXCODEC_STATUS_DECODE_FINISH; 212 m_ProcessingStatus = FXCODEC_STATUS_DECODE_FINISH;
270 } else { 213 } else {
271 m_ProcessingStatus = FXCODEC_STATUS_ERROR; 214 m_ProcessingStatus = FXCODEC_STATUS_ERROR;
272 } 215 }
273 return nRet; 216 return nRet;
274 } 217 }
275 int32_t CJBig2_Context::getFirstPage(CJBig2_Image** image, IFX_Pause* pPause) { 218
276 int32_t nRet;
277 m_bFirstPage = TRUE;
278 m_PauseStep = 0;
279 if (m_pGlobalContext) {
280 nRet = m_pGlobalContext->decode_EmbedOrgnazation(pPause);
281 if (nRet != JBIG2_SUCCESS) {
282 return nRet;
283 }
284 }
285 m_bBufSpecified = FALSE;
286 return Continue(pPause);
287 }
288 CJBig2_Segment* CJBig2_Context::findSegmentByNumber(FX_DWORD dwNumber) { 219 CJBig2_Segment* CJBig2_Context::findSegmentByNumber(FX_DWORD dwNumber) {
289 CJBig2_Segment* pSeg; 220 CJBig2_Segment* pSeg;
290 if (m_pGlobalContext) { 221 if (m_pGlobalContext) {
291 pSeg = m_pGlobalContext->findSegmentByNumber(dwNumber); 222 pSeg = m_pGlobalContext->findSegmentByNumber(dwNumber);
292 if (pSeg) { 223 if (pSeg) {
293 return pSeg; 224 return pSeg;
294 } 225 }
295 } 226 }
296 for (size_t i = 0; i < m_SegmentList.size(); ++i) { 227 for (size_t i = 0; i < m_SegmentList.size(); ++i) {
297 pSeg = m_SegmentList.get(i); 228 pSeg = m_SegmentList.get(i);
(...skipping 1328 matching lines...) Expand 10 before | Expand all | Expand 10 after
1626 SBSYMCODES[CURTEMP].code = CURCODE; 1557 SBSYMCODES[CURTEMP].code = CURCODE;
1627 CURCODE = CURCODE + 1; 1558 CURCODE = CURCODE + 1;
1628 } 1559 }
1629 CURTEMP = CURTEMP + 1; 1560 CURTEMP = CURTEMP + 1;
1630 } 1561 }
1631 CURLEN = CURLEN + 1; 1562 CURLEN = CURLEN + 1;
1632 } 1563 }
1633 FX_Free(LENCOUNT); 1564 FX_Free(LENCOUNT);
1634 FX_Free(FIRSTCODE); 1565 FX_Free(FIRSTCODE);
1635 } 1566 }
OLDNEW
« core/src/fxcodec/jbig2/JBig2_Context.h ('K') | « core/src/fxcodec/jbig2/JBig2_Context.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698