From 783a7e048c677d26aaf3884304627bbe27cff546 Mon Sep 17 00:00:00 2001 From: tsepez Date: Tue, 17 Jan 2017 11:05:57 -0800 Subject: Avoid endless loop deleting CFGAS_GEFont. It's a ref-counted class, so if we're in the destructor, the ref count has hit zero. We can't make a new ref pointer to itself here, as it will re-invoke the destructor when it goes out of scope. This should have been an obvious anti-pattern in hindsight. The object in question can't be in the m_pFontManager, since the font manager retains a reference, and we wouldn't get to this destructor while that is present. So the cleanup isn't required. Fixing this revealed a free-delete mismatch in cxfa_textlayout.cpp. I also converted to use unique_ptrs in a few places near this issue. Fixing this revealed a UAF in CFGAS_GEFont, memcpy'ing a RetainPtr is not a good idea as it doesn't bump the ref count. Also protect and friend the CFGAS_GEFont destructor, to make sure random deletes don't happen. Also kill off a const cast, and remove unnecessary conversion to retain_ptr when we already have one. TEST=look for absence of -11 in XFA corpus test logs, bots not currently noticing the segv. Argh. Review-Url: https://codereview.chromium.org/2631703003 --- core/fxcrt/cfx_retain_ptr.h | 1 + xfa/fde/cfde_txtedtengine.cpp | 2 +- xfa/fgas/font/cfgas_gefont.cpp | 11 ++-- xfa/fgas/font/cfgas_gefont.h | 7 +-- xfa/fxfa/app/cxfa_pieceline.cpp | 2 + xfa/fxfa/app/cxfa_pieceline.h | 5 +- xfa/fxfa/app/cxfa_textlayout.cpp | 107 +++++++++++++++------------------------ xfa/fxfa/app/cxfa_textlayout.h | 11 ++-- xfa/fxfa/app/xfa_fftext.cpp | 21 +++----- xfa/fxfa/app/xfa_textpiece.cpp | 5 +- 10 files changed, 75 insertions(+), 97 deletions(-) diff --git a/core/fxcrt/cfx_retain_ptr.h b/core/fxcrt/cfx_retain_ptr.h index f70faf1464..62b26942ba 100644 --- a/core/fxcrt/cfx_retain_ptr.h +++ b/core/fxcrt/cfx_retain_ptr.h @@ -83,6 +83,7 @@ class CFX_Retainable { void Retain() { ++m_nRefCount; } void Release() { + ASSERT(m_nRefCount > 0); if (--m_nRefCount == 0) delete this; } diff --git a/xfa/fde/cfde_txtedtengine.cpp b/xfa/fde/cfde_txtedtengine.cpp index 8bb944712a..7ef6b3ff06 100644 --- a/xfa/fde/cfde_txtedtengine.cpp +++ b/xfa/fde/cfde_txtedtengine.cpp @@ -84,7 +84,7 @@ void CFDE_TxtEdtEngine::SetEditParams(const FDE_TXTEDTPARAMS& params) { if (!m_pTextBreak) m_pTextBreak = pdfium::MakeUnique(FX_TXTBREAKPOLICY_None); - FXSYS_memcpy(&m_Param, ¶ms, sizeof(FDE_TXTEDTPARAMS)); + m_Param = params; m_wLineEnd = params.wLineBreakChar; m_bAutoLineEnd = (m_Param.nLineEnd == FDE_TXTEDIT_LINEEND_Auto); UpdateTxtBreak(); diff --git a/xfa/fgas/font/cfgas_gefont.cpp b/xfa/fgas/font/cfgas_gefont.cpp index 49639c2005..d0e7f13c3a 100644 --- a/xfa/fgas/font/cfgas_gefont.cpp +++ b/xfa/fgas/font/cfgas_gefont.cpp @@ -27,8 +27,7 @@ CFX_RetainPtr CFGAS_GEFont::LoadFont( if (!pFontMgr) return nullptr; - return CFX_RetainPtr( - pFontMgr->GetFontByCodePage(wCodePage, dwFontStyles, pszFontFamily)); + return pFontMgr->GetFontByCodePage(wCodePage, dwFontStyles, pszFontFamily); #else auto pFont = pdfium::MakeRetain(pFontMgr); if (!pFont->LoadFontInternal(pszFontFamily, dwFontStyles, wCodePage)) @@ -119,9 +118,6 @@ CFGAS_GEFont::CFGAS_GEFont(const CFX_RetainPtr& src, } CFGAS_GEFont::~CFGAS_GEFont() { - if (m_pFontMgr) - m_pFontMgr->RemoveFont(CFX_RetainPtr(this)); - if (!m_bExternalFont) delete m_pFont; } @@ -429,10 +425,9 @@ int32_t CFGAS_GEFont::GetDescent() const { return m_pFont->GetDescent(); } -CFX_RetainPtr CFGAS_GEFont::GetSubstFont( - int32_t iGlyphIndex) const { +CFX_RetainPtr CFGAS_GEFont::GetSubstFont(int32_t iGlyphIndex) { iGlyphIndex = static_cast(iGlyphIndex) >> 24; if (iGlyphIndex == 0) - return CFX_RetainPtr(const_cast(this)); + return CFX_RetainPtr(this); return m_SubstFonts[iGlyphIndex - 1]; } diff --git a/xfa/fgas/font/cfgas_gefont.h b/xfa/fgas/font/cfgas_gefont.h index de4f9639e0..6c9d890df4 100644 --- a/xfa/fgas/font/cfgas_gefont.h +++ b/xfa/fgas/font/cfgas_gefont.h @@ -24,6 +24,8 @@ class CXFA_PDFFontMgr; class CFGAS_GEFont : public CFX_Retainable { public: + template + friend class CFX_RetainPtr; template friend CFX_RetainPtr pdfium::MakeRetain(Args&&... args); @@ -46,8 +48,6 @@ class CFGAS_GEFont : public CFX_Retainable { bool bSaveStream); #endif - ~CFGAS_GEFont() override; - CFX_RetainPtr Derive(uint32_t dwFontStyles, uint16_t wCodePage = 0); uint32_t GetFontStyles() const; @@ -57,7 +57,7 @@ class CFGAS_GEFont : public CFX_Retainable { int32_t GetDescent() const; bool GetCharBBox(FX_WCHAR wUnicode, CFX_Rect* bbox, bool bCharCode = false); bool GetBBox(CFX_Rect* bbox); - CFX_RetainPtr GetSubstFont(int32_t iGlyphIndex) const; + CFX_RetainPtr GetSubstFont(int32_t iGlyphIndex); CFX_Font* GetDevFont() const { return m_pFont; } void SetFontProvider(CXFA_PDFFontMgr* pProvider) { m_pProvider = pProvider; } #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ @@ -70,6 +70,7 @@ class CFGAS_GEFont : public CFX_Retainable { private: explicit CFGAS_GEFont(CFGAS_FontMgr* pFontMgr); CFGAS_GEFont(const CFX_RetainPtr& src, uint32_t dwFontStyles); + ~CFGAS_GEFont() override; #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ bool LoadFontInternal(const FX_WCHAR* pszFontFamily, diff --git a/xfa/fxfa/app/cxfa_pieceline.cpp b/xfa/fxfa/app/cxfa_pieceline.cpp index 465896fd18..b906cf26e3 100644 --- a/xfa/fxfa/app/cxfa_pieceline.cpp +++ b/xfa/fxfa/app/cxfa_pieceline.cpp @@ -6,6 +6,8 @@ #include "xfa/fxfa/app/cxfa_pieceline.h" +#include "xfa/fxfa/app/xfa_textpiece.h" + CXFA_PieceLine::CXFA_PieceLine() {} CXFA_PieceLine::~CXFA_PieceLine() {} diff --git a/xfa/fxfa/app/cxfa_pieceline.h b/xfa/fxfa/app/cxfa_pieceline.h index 48dfdae04d..3e6bb99876 100644 --- a/xfa/fxfa/app/cxfa_pieceline.h +++ b/xfa/fxfa/app/cxfa_pieceline.h @@ -7,6 +7,9 @@ #ifndef XFA_FXFA_APP_CXFA_PIECELINE_H_ #define XFA_FXFA_APP_CXFA_PIECELINE_H_ +#include +#include + #include "core/fxcrt/fx_basic.h" class XFA_TextPiece; @@ -16,7 +19,7 @@ class CXFA_PieceLine { CXFA_PieceLine(); ~CXFA_PieceLine(); - CFX_ArrayTemplate m_textPieces; + std::vector> m_textPieces; CFX_ArrayTemplate m_charCounts; }; diff --git a/xfa/fxfa/app/cxfa_textlayout.cpp b/xfa/fxfa/app/cxfa_textlayout.cpp index 3f3058bf4e..d831b600dc 100644 --- a/xfa/fxfa/app/cxfa_textlayout.cpp +++ b/xfa/fxfa/app/cxfa_textlayout.cpp @@ -7,6 +7,7 @@ #include "xfa/fxfa/app/cxfa_textlayout.h" #include +#include #include "third_party/base/ptr_util.h" #include "third_party/base/stl_util.h" @@ -46,28 +47,10 @@ CXFA_TextLayout::~CXFA_TextLayout() { } void CXFA_TextLayout::Unload() { - for (int32_t i = 0; i < m_pieceLines.GetSize(); i++) { - CXFA_PieceLine* pLine = m_pieceLines.GetAt(i); - for (int32_t i = 0; i < pLine->m_textPieces.GetSize(); i++) { - XFA_TextPiece* pPiece = pLine->m_textPieces.GetAt(i); - // Release text and widths in a text piece. - delete pPiece->pszText; - delete pPiece->pWidths; - // Release text piece. - delete pPiece; - } - pLine->m_textPieces.RemoveAll(); - // Release line. - delete pLine; - } - m_pieceLines.RemoveAll(); + m_pieceLines.clear(); m_pBreak.reset(); } -const CFX_ArrayTemplate* CXFA_TextLayout::GetPieceLines() { - return &m_pieceLines; -} - void CXFA_TextLayout::GetTextDataNode() { if (!m_pTextProvider) return; @@ -586,7 +569,7 @@ bool CXFA_TextLayout::DrawString(CFX_RenderDevice* pFxDevice, auto pSolidBrush = pdfium::MakeUnique(); auto pPen = pdfium::MakeUnique(); - if (m_pieceLines.GetSize() == 0) { + if (m_pieceLines.empty()) { int32_t iBlockCount = CountBlocks(); for (int32_t i = 0; i < iBlockCount; i++) Layout(i); @@ -595,7 +578,7 @@ bool CXFA_TextLayout::DrawString(CFX_RenderDevice* pFxDevice, FXTEXT_CHARPOS* pCharPos = nullptr; int32_t iCharCount = 0; int32_t iLineStart = 0; - int32_t iPieceLines = m_pieceLines.GetSize(); + int32_t iPieceLines = pdfium::CollectionSize(m_pieceLines); int32_t iCount = m_Blocks.GetSize(); if (iCount > 0) { iBlock *= 2; @@ -608,14 +591,14 @@ bool CXFA_TextLayout::DrawString(CFX_RenderDevice* pFxDevice, } for (int32_t i = 0; i < iPieceLines; i++) { - if (i + iLineStart >= m_pieceLines.GetSize()) + if (i + iLineStart >= pdfium::CollectionSize(m_pieceLines)) break; - CXFA_PieceLine* pPieceLine = m_pieceLines.GetAt(i + iLineStart); - int32_t iPieces = pPieceLine->m_textPieces.GetSize(); + CXFA_PieceLine* pPieceLine = m_pieceLines[i + iLineStart].get(); + int32_t iPieces = pdfium::CollectionSize(pPieceLine->m_textPieces); int32_t j = 0; for (j = 0; j < iPieces; j++) { - const XFA_TextPiece* pPiece = pPieceLine->m_textPieces.GetAt(j); + const XFA_TextPiece* pPiece = pPieceLine->m_textPieces[j].get(); int32_t iChars = pPiece->iChars; if (iCharCount < iChars) { FX_Free(pCharPos); @@ -651,15 +634,9 @@ void CXFA_TextLayout::UpdateAlign(FX_FLOAT fHeight, FX_FLOAT fBottom) { return; } - int32_t iCount = m_pieceLines.GetSize(); - for (int32_t i = 0; i < iCount; i++) { - CXFA_PieceLine* pPieceLine = m_pieceLines.GetAt(i); - int32_t iPieces = pPieceLine->m_textPieces.GetSize(); - for (int32_t j = 0; j < iPieces; j++) { - XFA_TextPiece* pPiece = pPieceLine->m_textPieces.GetAt(j); - CFX_RectF& rect = pPiece->rtPiece; - rect.top += fHeight; - } + for (const auto& pPieceLine : m_pieceLines) { + for (const auto& pPiece : pPieceLine->m_textPieces) + pPiece->rtPiece.top += fHeight; } } @@ -1004,11 +981,11 @@ void CXFA_TextLayout::DoTabstops(CFDE_CSSComputedStyle* pStyle, if (!pStyle || !pPieceLine) return; - int32_t iPieces = pPieceLine->m_textPieces.GetSize(); + int32_t iPieces = pdfium::CollectionSize(pPieceLine->m_textPieces); if (iPieces == 0) return; - XFA_TextPiece* pPiece = pPieceLine->m_textPieces.GetAt(iPieces - 1); + XFA_TextPiece* pPiece = pPieceLine->m_textPieces[iPieces - 1].get(); int32_t& iTabstopsIndex = m_pTabstopContext->m_iTabIndex; int32_t iCount = m_textParser.CountTabs(pStyle); if (iTabstopsIndex > m_pTabstopContext->m_iTabCount - 1) @@ -1019,7 +996,7 @@ void CXFA_TextLayout::DoTabstops(CFDE_CSSComputedStyle* pStyle, m_pTabstopContext->m_bTabstops = true; FX_FLOAT fRight = 0; if (iPieces > 1) { - XFA_TextPiece* p = pPieceLine->m_textPieces.GetAt(iPieces - 2); + XFA_TextPiece* p = pPieceLine->m_textPieces[iPieces - 2].get(); fRight = p->rtPiece.right(); } m_pTabstopContext->m_fTabWidth = @@ -1063,8 +1040,9 @@ void CXFA_TextLayout::AppendTextLine(uint32_t dwStatus, CFDE_CSSComputedStyle* pStyle = nullptr; if (bSavePieces) { - CXFA_PieceLine* pPieceLine = new CXFA_PieceLine; - m_pieceLines.Add(pPieceLine); + auto pNew = pdfium::MakeUnique(); + CXFA_PieceLine* pPieceLine = pNew.get(); + m_pieceLines.push_back(std::move(pNew)); if (m_pTabstopContext) m_pTabstopContext->Reset(); @@ -1077,11 +1055,9 @@ void CXFA_TextLayout::AppendTextLine(uint32_t dwStatus, pStyle = pUserData->m_pStyle; FX_FLOAT fVerScale = pPiece->m_iVerticalScale / 100.0f; - XFA_TextPiece* pTP = new XFA_TextPiece(); - pTP->pszText = - (FX_WCHAR*)FX_Alloc(uint8_t, pPiece->m_iChars * sizeof(FX_WCHAR)); - pTP->pWidths = - (int32_t*)FX_Alloc(uint8_t, pPiece->m_iChars * sizeof(int32_t)); + auto pTP = pdfium::MakeUnique(); + pTP->pszText = FX_Alloc(FX_WCHAR, pPiece->m_iChars); + pTP->pWidths = FX_Alloc(int32_t, pPiece->m_iChars); pTP->iChars = pPiece->m_iChars; pPiece->GetString(pTP->pszText); pPiece->GetWidths(pTP->pWidths); @@ -1100,7 +1076,6 @@ void CXFA_TextLayout::AppendTextLine(uint32_t dwStatus, FX_FLOAT fBaseLineTemp = m_textParser.GetBaseline(m_pTextProvider, pStyle); pTP->rtPiece.top = fBaseLineTemp; - pPieceLine->m_textPieces.Add(pTP); FX_FLOAT fLineHeight = m_textParser.GetLineHeight( m_pTextProvider, pStyle, m_iLines == 0, fVerScale); @@ -1120,10 +1095,10 @@ void CXFA_TextLayout::AppendTextLine(uint32_t dwStatus, } else { pTP->pLinkData = nullptr; } + pPieceLine->m_textPieces.push_back(std::move(pTP)); DoTabstops(pStyle, pPieceLine); } - for (i = 0; i < iPieces; i++) { - XFA_TextPiece* pTP = pPieceLine->m_textPieces.GetAt(i); + for (const auto& pTP : pPieceLine->m_textPieces) { FX_FLOAT& fTop = pTP->rtPiece.top; FX_FLOAT fBaseLineTemp = fTop; fTop = fLinePos + fLineStep - pTP->rtPiece.height - fBaseLineTemp; @@ -1206,7 +1181,7 @@ void CXFA_TextLayout::RenderString(CFDE_RenderDevice* pDevice, int32_t iPiece, FXTEXT_CHARPOS* pCharPos, const CFX_Matrix& tmDoc2Device) { - const XFA_TextPiece* pPiece = pPieceLine->m_textPieces.GetAt(iPiece); + const XFA_TextPiece* pPiece = pPieceLine->m_textPieces[iPiece].get(); int32_t iCount = GetDisplayPos(pPiece, pCharPos); if (iCount > 0) { pBrush->SetColor(pPiece->dwColor); @@ -1222,7 +1197,7 @@ void CXFA_TextLayout::RenderPath(CFDE_RenderDevice* pDevice, int32_t iPiece, FXTEXT_CHARPOS* pCharPos, const CFX_Matrix& tmDoc2Device) { - XFA_TextPiece* pPiece = pPieceLine->m_textPieces.GetAt(iPiece); + XFA_TextPiece* pPiece = pPieceLine->m_textPieces[iPiece].get(); bool bNoUnderline = pPiece->iUnderline < 1 || pPiece->iUnderline > 2; bool bNoLineThrough = pPiece->iLineThrough < 1 || pPiece->iLineThrough > 2; if (bNoUnderline && bNoLineThrough) @@ -1282,7 +1257,7 @@ void CXFA_TextLayout::RenderPath(CFDE_RenderDevice* pDevice, return; iCharsTmp = 0; - int32_t iPieces = pPieceLine->m_textPieces.GetSize(); + int32_t iPieces = pdfium::CollectionSize(pPieceLine->m_textPieces); while (iPieceNext < iPieces - 1) { iPieceNext++; iCharsTmp = pPieceLine->m_charCounts.GetAt(iPieceNext); @@ -1294,14 +1269,14 @@ void CXFA_TextLayout::RenderPath(CFDE_RenderDevice* pDevice, FX_FLOAT fOrgX = 0.0f; FX_FLOAT fEndX = 0.0f; - pPiece = pPieceLine->m_textPieces.GetAt(iPiecePrev); + pPiece = pPieceLine->m_textPieces[iPiecePrev].get(); iChars = GetDisplayPos(pPiece, pCharPos); if (iChars < 1) return; fOrgX = pCharPos[iChars - 1].m_OriginX + pCharPos[iChars - 1].m_FontCharWidth * pPiece->fFontSize / 1000.0f; - pPiece = pPieceLine->m_textPieces.GetAt(iPieceNext); + pPiece = pPieceLine->m_textPieces[iPieceNext].get(); iChars = GetDisplayPos(pPiece, pCharPos); if (iChars < 1) return; @@ -1332,27 +1307,27 @@ int32_t CXFA_TextLayout::GetDisplayPos(const XFA_TextPiece* pPiece, return 0; FX_RTFTEXTOBJ tr; - if (!ToRun(pPiece, tr)) + if (!ToRun(pPiece, &tr)) return 0; return m_pBreak->GetDisplayPos(&tr, pCharPos, bCharCode); } -bool CXFA_TextLayout::ToRun(const XFA_TextPiece* pPiece, FX_RTFTEXTOBJ& tr) { +bool CXFA_TextLayout::ToRun(const XFA_TextPiece* pPiece, FX_RTFTEXTOBJ* tr) { int32_t iLength = pPiece->iChars; if (iLength < 1) return false; - tr.pStr = pPiece->pszText; - tr.pFont = pPiece->pFont; - tr.pRect = &pPiece->rtPiece; - tr.pWidths = pPiece->pWidths; - tr.iLength = iLength; - tr.fFontSize = pPiece->fFontSize; - tr.iBidiLevel = pPiece->iBidiLevel; - tr.iCharRotation = 0; - tr.wLineBreakChar = L'\n'; - tr.iVerticalScale = pPiece->iVerScale; - tr.dwLayoutStyles = FX_RTFLAYOUTSTYLE_ExpandTab; - tr.iHorizontalScale = pPiece->iHorScale; + tr->pStr = pPiece->pszText; + tr->pFont = pPiece->pFont; + tr->pRect = &pPiece->rtPiece; + tr->pWidths = pPiece->pWidths; + tr->iLength = iLength; + tr->fFontSize = pPiece->fFontSize; + tr->iBidiLevel = pPiece->iBidiLevel; + tr->iCharRotation = 0; + tr->wLineBreakChar = L'\n'; + tr->iVerticalScale = pPiece->iVerScale; + tr->dwLayoutStyles = FX_RTFLAYOUTSTYLE_ExpandTab; + tr->iHorizontalScale = pPiece->iHorScale; return true; } diff --git a/xfa/fxfa/app/cxfa_textlayout.h b/xfa/fxfa/app/cxfa_textlayout.h index 8575071faa..4de53d1eb0 100644 --- a/xfa/fxfa/app/cxfa_textlayout.h +++ b/xfa/fxfa/app/cxfa_textlayout.h @@ -8,6 +8,7 @@ #define XFA_FXFA_APP_CXFA_TEXTLAYOUT_H_ #include +#include #include "core/fxcrt/fx_basic.h" #include "core/fxcrt/fx_coordinates.h" @@ -52,9 +53,11 @@ class CXFA_TextLayout { const CFX_Matrix& tmDoc2Device, const CFX_RectF& rtClip, int32_t iBlock = 0); - bool IsLoaded() const { return m_pieceLines.GetSize() > 0; } + bool IsLoaded() const { return !m_pieceLines.empty(); } void Unload(); - const CFX_ArrayTemplate* GetPieceLines(); + const std::vector>* GetPieceLines() const { + return &m_pieceLines; + } bool m_bHasBlock; CFX_Int32Array m_Blocks; @@ -112,7 +115,7 @@ class CXFA_TextLayout { int32_t GetDisplayPos(const XFA_TextPiece* pPiece, FXTEXT_CHARPOS* pCharPos, bool bCharCode = false); - bool ToRun(const XFA_TextPiece* pPiece, FX_RTFTEXTOBJ& tr); + bool ToRun(const XFA_TextPiece* pPiece, FX_RTFTEXTOBJ* tr); void DoTabstops(CFDE_CSSComputedStyle* pStyle, CXFA_PieceLine* pPieceLine); bool Layout(int32_t iBlock); int32_t CountBlocks() const; @@ -125,7 +128,7 @@ class CXFA_TextLayout { int32_t m_iLines; FX_FLOAT m_fMaxWidth; CXFA_TextParser m_textParser; - CFX_ArrayTemplate m_pieceLines; + std::vector> m_pieceLines; std::unique_ptr m_pTabstopContext; bool m_bBlockContinue; }; diff --git a/xfa/fxfa/app/xfa_fftext.cpp b/xfa/fxfa/app/xfa_fftext.cpp index 2307ea0dc4..3d2c9a6ea0 100644 --- a/xfa/fxfa/app/xfa_fftext.cpp +++ b/xfa/fxfa/app/xfa_fftext.cpp @@ -153,22 +153,17 @@ FWL_WidgetHit CXFA_FFText::OnHitTest(FX_FLOAT fx, FX_FLOAT fy) { } const FX_WCHAR* CXFA_FFText::GetLinkURLAtPoint(FX_FLOAT fx, FX_FLOAT fy) { CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout(); - if (!pTextLayout) { + if (!pTextLayout) return nullptr; - } - FX_FLOAT x(fx), y(fy); + + FX_FLOAT x(fx); + FX_FLOAT y(fy); FWLToClient(x, y); - const CFX_ArrayTemplate* pPieceLines = - pTextLayout->GetPieceLines(); - int32_t iCount = pPieceLines->GetSize(); - for (int32_t i = 0; i < iCount; i++) { - CXFA_PieceLine* pPieceLine = pPieceLines->GetAt(i); - int32_t iPieces = pPieceLine->m_textPieces.GetSize(); - for (int32_t j = 0; j < iPieces; j++) { - XFA_TextPiece* pPiece = pPieceLine->m_textPieces.GetAt(j); - if (pPiece->pLinkData && pPiece->rtPiece.Contains(x, y)) { + + for (const auto& pPieceLine : *pTextLayout->GetPieceLines()) { + for (const auto& pPiece : pPieceLine->m_textPieces) { + if (pPiece->pLinkData && pPiece->rtPiece.Contains(x, y)) return pPiece->pLinkData->GetLinkURL(); - } } } return nullptr; diff --git a/xfa/fxfa/app/xfa_textpiece.cpp b/xfa/fxfa/app/xfa_textpiece.cpp index 4b57aa82d9..933af6c92f 100644 --- a/xfa/fxfa/app/xfa_textpiece.cpp +++ b/xfa/fxfa/app/xfa_textpiece.cpp @@ -9,9 +9,12 @@ #include "xfa/fxfa/app/cxfa_linkuserdata.h" XFA_TextPiece::XFA_TextPiece() - : pszText(nullptr), pFont(nullptr), pLinkData(nullptr) {} + : pszText(nullptr), pWidths(nullptr), pFont(nullptr), pLinkData(nullptr) {} XFA_TextPiece::~XFA_TextPiece() { if (pLinkData) pLinkData->Release(); + + FX_Free(pszText); + FX_Free(pWidths); } -- cgit v1.2.3