chromium / pdfium

The PDF library used by the Chromium project

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

pdfium out of bound bug

v4kst1z opened this issue · comments

Bug

Thread 1 "pdfium_test" received signal SIGTRAP, Trace/breakpoint trap.
0x000055555c2ff819 in CFDE_TextOut::Line::GetPieceAtIndex(unsigned long)::$_1::operator()() const () at ../../xfa/fde/cfde_textout.cpp:551
551       CHECK(pdfium::IndexInBounds(pieces_, index));
(gdb) bt
#0  0x000055555c2ff819 in CFDE_TextOut::Line::GetPieceAtIndex(unsigned long)::$_1::operator()() const () at ../../xfa/fde/cfde_textout.cpp:551
#1  0x000055555c2fca4b in CFDE_TextOut::Line::GetPieceAtIndex(unsigned long) () at ../../xfa/fde/cfde_textout.cpp:551
#2  0x000055555c2ff378 in CFDE_TextOut::ReloadLinePiece(CFDE_TextOut::Line*, CFX_RectF const&) () at ../../xfa/fde/cfde_textout.cpp:472
#3  0x000055555c2fc26c in CFDE_TextOut::Reload(CFX_RectF const&) () at ../../xfa/fde/cfde_textout.cpp:446
#4  0x000055555c2fab97 in CFDE_TextOut::DrawLogicText(CFX_RenderDevice*, fxcrt::StringViewTemplate<wchar_t>, CFX_RectF const&) () at ../../xfa/fde/cfde_textout.cpp:291

details

void CFDE_TextOut::ReloadLinePiece(Line* pLine, const CFX_RectF& rect) {
  ......
  while (iPieceIndex < iPieceCount) {
    size_t start = start_char;
    size_t end = pPiece->char_count + start;
    while (start < end) {
      dwBreakStatus = m_pTxtBreak->AppendChar(text_span[start]);
      if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus))
        RetrievePieces(dwBreakStatus, true, rect, &start_char, &iPieceWidths);

      ++start;
    }
    ++iPieceIndex;   //bug, after the step, the index may equal to iPieceCount, lead to oob
    pPiece = pLine->GetPieceAtIndex(iPieceIndex);
  }
  ......
  m_pTxtBreak->Reset();
}

fix

void CFDE_TextOut::ReloadLinePiece(Line* pLine, const CFX_RectF& rect) {
  ......
  while (iPieceIndex < iPieceCount) {
    if (iPieceIndex != 0 ) pPiece = pLine->GetPieceAtIndex(iPieceIndex);
    size_t start = start_char;
    size_t end = pPiece->char_count + start;
    while (start < end) {
      dwBreakStatus = m_pTxtBreak->AppendChar(text_span[start]);
      if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus))
        RetrievePieces(dwBreakStatus, true, rect, &start_char, &iPieceWidths);

      ++start;
    }
    ++iPieceIndex;  
  }
  ......
  m_pTxtBreak->Reset();
}