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

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

Issue 1388203003: Sanitize CJBig2_SymbolDict's memory usage. (Closed) Base URL: https://pdfium.googlesource.com/pdfium@master
Patch Set: rebase Created 5 years, 2 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
« no previous file with comments | « no previous file | core/src/fxcodec/jbig2/JBig2_SddProc.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "JBig2_Context.h" 7 #include "JBig2_Context.h"
8 8
9 #include <list> 9 #include <list>
10 10
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 } else { 561 } else {
562 CJBig2_Segment* pSeg = 562 CJBig2_Segment* pSeg =
563 findReferredSegmentByTypeAndIndex(pSegment, 53, ++nIndex); 563 findReferredSegmentByTypeAndIndex(pSegment, 53, ++nIndex);
564 if (!pSeg) 564 if (!pSeg)
565 return JBIG2_ERROR_FATAL; 565 return JBIG2_ERROR_FATAL;
566 pSymbolDictDecoder->SDHUFFAGGINST = pSeg->m_Result.ht; 566 pSymbolDictDecoder->SDHUFFAGGINST = pSeg->m_Result.ht;
567 } 567 }
568 } 568 }
569 } 569 }
570 570
571 nonstd::unique_ptr<JBig2ArithCtx, FxFreeDeleter> gbContext; 571 const bool bUseGbContext = (pSymbolDictDecoder->SDHUFF == 0);
572 nonstd::unique_ptr<JBig2ArithCtx, FxFreeDeleter> grContext; 572 const bool bUseGrContext = (pSymbolDictDecoder->SDREFAGG == 1);
573 if ((wFlags & 0x0100) && pLRSeg && pLRSeg->m_Result.sd->m_bContextRetained) { 573 const size_t gbContextSize =
574 if (pSymbolDictDecoder->SDHUFF == 0) { 574 GetHuffContextSize(pSymbolDictDecoder->SDTEMPLATE);
575 const size_t size = GetHuffContextSize(pSymbolDictDecoder->SDTEMPLATE); 575 const size_t grContextSize =
576 gbContext.reset(FX_Alloc(JBig2ArithCtx, size)); 576 GetRefAggContextSize(pSymbolDictDecoder->SDRTEMPLATE);
577 JBIG2_memcpy(gbContext.get(), pLRSeg->m_Result.sd->m_gbContext, 577 std::vector<JBig2ArithCtx> gbContext;
578 sizeof(JBig2ArithCtx) * size); 578 std::vector<JBig2ArithCtx> grContext;
579 if ((wFlags & 0x0100) && pLRSeg) {
580 if (bUseGbContext) {
581 gbContext = pLRSeg->m_Result.sd->GbContext();
582 if (gbContext.size() != gbContextSize)
583 return JBIG2_ERROR_FATAL;
579 } 584 }
580 if (pSymbolDictDecoder->SDREFAGG == 1) { 585 if (bUseGrContext) {
581 const size_t size = GetRefAggContextSize(pSymbolDictDecoder->SDRTEMPLATE); 586 grContext = pLRSeg->m_Result.sd->GrContext();
582 grContext.reset(FX_Alloc(JBig2ArithCtx, size)); 587 if (grContext.size() != grContextSize)
583 JBIG2_memcpy(grContext.get(), pLRSeg->m_Result.sd->m_grContext, 588 return JBIG2_ERROR_FATAL;
584 sizeof(JBig2ArithCtx) * size);
585 } 589 }
586 } else { 590 } else {
587 if (pSymbolDictDecoder->SDHUFF == 0) { 591 if (bUseGbContext)
588 const size_t size = GetHuffContextSize(pSymbolDictDecoder->SDTEMPLATE); 592 gbContext.resize(gbContextSize);
589 gbContext.reset(FX_Alloc(JBig2ArithCtx, size)); 593 if (bUseGrContext)
590 JBIG2_memset(gbContext.get(), 0, sizeof(JBig2ArithCtx) * size); 594 grContext.resize(grContextSize);
591 }
592 if (pSymbolDictDecoder->SDREFAGG == 1) {
593 const size_t size = GetRefAggContextSize(pSymbolDictDecoder->SDRTEMPLATE);
594 grContext.reset(FX_Alloc(JBig2ArithCtx, size));
595 JBIG2_memset(grContext.get(), 0, sizeof(JBig2ArithCtx) * size);
596 }
597 } 595 }
596
598 CJBig2_CacheKey key = 597 CJBig2_CacheKey key =
599 CJBig2_CacheKey(pSegment->m_dwObjNum, pSegment->m_dwDataOffset); 598 CJBig2_CacheKey(pSegment->m_dwObjNum, pSegment->m_dwDataOffset);
600 FX_BOOL cache_hit = false; 599 FX_BOOL cache_hit = false;
601 pSegment->m_nResultType = JBIG2_SYMBOL_DICT_POINTER; 600 pSegment->m_nResultType = JBIG2_SYMBOL_DICT_POINTER;
602 if (m_bIsGlobal && key.first != 0) { 601 if (m_bIsGlobal && key.first != 0) {
603 for (auto it = m_pSymbolDictCache->begin(); it != m_pSymbolDictCache->end(); 602 for (auto it = m_pSymbolDictCache->begin(); it != m_pSymbolDictCache->end();
604 ++it) { 603 ++it) {
605 if (it->first == key) { 604 if (it->first == key) {
606 nonstd::unique_ptr<CJBig2_SymbolDict> copy(it->second->DeepCopy()); 605 nonstd::unique_ptr<CJBig2_SymbolDict> copy(it->second->DeepCopy());
607 pSegment->m_Result.sd = copy.release(); 606 pSegment->m_Result.sd = copy.release();
608 m_pSymbolDictCache->push_front(*it); 607 m_pSymbolDictCache->push_front(*it);
609 m_pSymbolDictCache->erase(it); 608 m_pSymbolDictCache->erase(it);
610 cache_hit = true; 609 cache_hit = true;
611 break; 610 break;
612 } 611 }
613 } 612 }
614 } 613 }
615 if (!cache_hit) { 614 if (!cache_hit) {
616 if (pSymbolDictDecoder->SDHUFF == 0) { 615 if (bUseGbContext) {
617 nonstd::unique_ptr<CJBig2_ArithDecoder> pArithDecoder( 616 nonstd::unique_ptr<CJBig2_ArithDecoder> pArithDecoder(
618 new CJBig2_ArithDecoder(m_pStream.get())); 617 new CJBig2_ArithDecoder(m_pStream.get()));
619 pSegment->m_Result.sd = pSymbolDictDecoder->decode_Arith( 618 pSegment->m_Result.sd = pSymbolDictDecoder->decode_Arith(
620 pArithDecoder.get(), gbContext.get(), grContext.get()); 619 pArithDecoder.get(), &gbContext, &grContext);
621 if (!pSegment->m_Result.sd) 620 if (!pSegment->m_Result.sd)
622 return JBIG2_ERROR_FATAL; 621 return JBIG2_ERROR_FATAL;
623 622
624 m_pStream->alignByte(); 623 m_pStream->alignByte();
625 m_pStream->offset(2); 624 m_pStream->offset(2);
626 } else { 625 } else {
627 pSegment->m_Result.sd = pSymbolDictDecoder->decode_Huffman( 626 pSegment->m_Result.sd = pSymbolDictDecoder->decode_Huffman(
628 m_pStream.get(), gbContext.get(), grContext.get(), pPause); 627 m_pStream.get(), &gbContext, &grContext, pPause);
629 if (!pSegment->m_Result.sd) 628 if (!pSegment->m_Result.sd)
630 return JBIG2_ERROR_FATAL; 629 return JBIG2_ERROR_FATAL;
631 m_pStream->alignByte(); 630 m_pStream->alignByte();
632 } 631 }
633 if (m_bIsGlobal && kSymbolDictCacheMaxSize > 0) { 632 if (m_bIsGlobal && kSymbolDictCacheMaxSize > 0) {
634 nonstd::unique_ptr<CJBig2_SymbolDict> value = 633 nonstd::unique_ptr<CJBig2_SymbolDict> value =
635 pSegment->m_Result.sd->DeepCopy(); 634 pSegment->m_Result.sd->DeepCopy();
636 if (value) { 635 while (m_pSymbolDictCache->size() >= kSymbolDictCacheMaxSize) {
637 while (m_pSymbolDictCache->size() >= kSymbolDictCacheMaxSize) { 636 delete m_pSymbolDictCache->back().second;
638 delete m_pSymbolDictCache->back().second; 637 m_pSymbolDictCache->pop_back();
639 m_pSymbolDictCache->pop_back();
640 }
641 m_pSymbolDictCache->push_front(CJBig2_CachePair(key, value.release()));
642 } 638 }
639 m_pSymbolDictCache->push_front(CJBig2_CachePair(key, value.release()));
643 } 640 }
644 } 641 }
645 if (wFlags & 0x0200) { 642 if (wFlags & 0x0200) {
646 pSegment->m_Result.sd->m_bContextRetained = TRUE; 643 if (bUseGbContext)
647 if (pSymbolDictDecoder->SDHUFF == 0) { 644 pSegment->m_Result.sd->SetGbContext(gbContext);
648 pSegment->m_Result.sd->m_gbContext = gbContext.release(); 645 if (bUseGrContext)
649 } 646 pSegment->m_Result.sd->SetGrContext(grContext);
650 if (pSymbolDictDecoder->SDREFAGG == 1) {
651 pSegment->m_Result.sd->m_grContext = grContext.release();
652 }
653 } 647 }
654 return JBIG2_SUCCESS; 648 return JBIG2_SUCCESS;
655 } 649 }
656 650
657 int32_t CJBig2_Context::parseTextRegion(CJBig2_Segment* pSegment) { 651 int32_t CJBig2_Context::parseTextRegion(CJBig2_Segment* pSegment) {
658 FX_WORD wFlags; 652 FX_WORD wFlags;
659 JBig2RegionInfo ri; 653 JBig2RegionInfo ri;
660 if (parseRegionInfo(&ri) != JBIG2_SUCCESS || 654 if (parseRegionInfo(&ri) != JBIG2_SUCCESS ||
661 m_pStream->readShortInteger(&wFlags) != 0) { 655 m_pStream->readShortInteger(&wFlags) != 0) {
662 return JBIG2_ERROR_TOO_SHORT; 656 return JBIG2_ERROR_TOO_SHORT;
(...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after
1426 SBSYMCODES[CURTEMP].code = CURCODE; 1420 SBSYMCODES[CURTEMP].code = CURCODE;
1427 CURCODE = CURCODE + 1; 1421 CURCODE = CURCODE + 1;
1428 } 1422 }
1429 CURTEMP = CURTEMP + 1; 1423 CURTEMP = CURTEMP + 1;
1430 } 1424 }
1431 CURLEN = CURLEN + 1; 1425 CURLEN = CURLEN + 1;
1432 } 1426 }
1433 FX_Free(LENCOUNT); 1427 FX_Free(LENCOUNT);
1434 FX_Free(FIRSTCODE); 1428 FX_Free(FIRSTCODE);
1435 } 1429 }
OLDNEW
« no previous file with comments | « no previous file | core/src/fxcodec/jbig2/JBig2_SddProc.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698