summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-12-20 11:32:31 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-01-04 13:03:43 +0000
commit51bfe4452921803d0a7a145785b11832f321aa2a (patch)
tree389fc85c59b3004aed035fcd2c374a64ea9ef4e4
parent7869641c98f998ce83bcb520e3046dafdd00fc80 (diff)
downloadqtwebengine-chromium-51bfe4452921803d0a7a145785b11832f321aa2a.tar.gz
[Backport] Fix UAF in SetVisible().
SetVisible() may be called during Destroy() which may be called during SetVisible(). This fixes the latest in a family of bugs that happen after an instance is freed by code triggered by JS code while it's executing a method. The CL has a lot of protection for many of these points where JS may be executed and potentially destroy objects. The return types of many methods that may execute JS have been changed to bool, indicating whether the instance is still alive after the call. Bug: chromium:770148 Reviewed-on: https://pdfium-review.googlesource.com/15190 (CVE-2017-15411) Change-Id: Id0f24bcd6d0d8ee482a03e5490e2eb91c9ae123d Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
-rw-r--r--chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_appstream.cpp3
-rw-r--r--chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_caret.cpp22
-rw-r--r--chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_caret.h4
-rw-r--r--chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_combo_box.cpp83
-rw-r--r--chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_combo_box.h6
-rw-r--r--chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_edit.cpp21
-rw-r--r--chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_edit.h2
-rw-r--r--chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_edit_ctrl.cpp27
-rw-r--r--chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_edit_ctrl.h4
-rw-r--r--chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_list_box.cpp6
-rw-r--r--chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_list_box.h2
-rw-r--r--chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_scroll_bar.cpp97
-rw-r--r--chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_scroll_bar.h6
-rw-r--r--chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_wnd.cpp63
-rw-r--r--chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_wnd.h17
15 files changed, 251 insertions, 112 deletions
diff --git a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_appstream.cpp b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_appstream.cpp
index f7b57365dff..dd504ac8495 100644
--- a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_appstream.cpp
+++ b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_appstream.cpp
@@ -605,7 +605,8 @@ CFX_ByteString GenerateIconAppStream(CPDF_IconFit& fit,
icon.Create(cp);
icon.SetIconFit(&fit);
icon.SetPDFStream(pIconStream);
- icon.Move(rcIcon, false, false);
+ if (!icon.Move(rcIcon, false, false))
+ return CFX_ByteString();
CFX_ByteString sAlias = icon.GetImageAlias();
if (sAlias.GetLength() <= 0)
diff --git a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_caret.cpp b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_caret.cpp
index 0870f71d9f6..b6033b15fb9 100644
--- a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_caret.cpp
+++ b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_caret.cpp
@@ -80,7 +80,7 @@ void CPWL_Caret::SetCaret(bool bVisible,
m_bFlash = true;
Move(m_rcInvalid, false, true);
// Note, |this| may no longer be viable at this point. If more work
- // needs to be done, add an observer.
+ // needs to be done, check the return value of Move().
}
} else {
m_ptHead = ptHead;
@@ -88,15 +88,13 @@ void CPWL_Caret::SetCaret(bool bVisible,
EndTimer();
BeginTimer(PWL_CARET_FLASHINTERVAL);
- ObservedPtr observer(this);
- CPWL_Wnd::SetVisible(true);
- if (!observer)
+ if (!CPWL_Wnd::SetVisible(true))
return;
m_bFlash = true;
Move(m_rcInvalid, false, true);
// Note, |this| may no longer be viable at this point. If more work needs
- // to be done, add an observer.
+ // to be done, check the return value of Move().
}
} else {
m_ptHead = CFX_PointF();
@@ -106,12 +104,12 @@ void CPWL_Caret::SetCaret(bool bVisible,
EndTimer();
CPWL_Wnd::SetVisible(false);
// Note, |this| may no longer be viable at this point. If more work needs
- // to be done, add an observer.
+ // to be done, check the return value of SetVisible().
}
}
}
-void CPWL_Caret::InvalidateRect(CFX_FloatRect* pRect) {
+bool CPWL_Caret::InvalidateRect(CFX_FloatRect* pRect) {
if (pRect) {
CFX_FloatRect rcRefresh = *pRect;
if (!rcRefresh.IsEmpty()) {
@@ -120,10 +118,12 @@ void CPWL_Caret::InvalidateRect(CFX_FloatRect* pRect) {
}
rcRefresh.top += 1;
rcRefresh.bottom -= 1;
- CPWL_Wnd::InvalidateRect(&rcRefresh);
+ return CPWL_Wnd::InvalidateRect(&rcRefresh);
} else {
- CPWL_Wnd::InvalidateRect(pRect);
+ return CPWL_Wnd::InvalidateRect(nullptr);
}
- // Note, |this| may no longer be viable at this point. If more work needs
- // to be done, add an observer.
+}
+
+bool CPWL_Caret::SetVisible(bool bVisible) {
+ return true;
}
diff --git a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_caret.h b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_caret.h
index 6d6dcd557e1..b4020108e3d 100644
--- a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_caret.h
+++ b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_caret.h
@@ -18,8 +18,8 @@ class CPWL_Caret : public CPWL_Wnd {
CFX_ByteString GetClassName() const override;
void DrawThisAppearance(CFX_RenderDevice* pDevice,
CFX_Matrix* pUser2Device) override;
- void InvalidateRect(CFX_FloatRect* pRect = nullptr) override;
- void SetVisible(bool bVisible) override {}
+ bool InvalidateRect(CFX_FloatRect* pRect = nullptr) override;
+ bool SetVisible(bool bVisible) override;
void TimerProc() override;
void SetCaret(bool bVisible,
diff --git a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_combo_box.cpp b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_combo_box.cpp
index d86c9db8a9d..66fd2023cd8 100644
--- a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_combo_box.cpp
+++ b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_combo_box.cpp
@@ -173,7 +173,9 @@ void CPWL_ComboBox::SetFocus() {
}
void CPWL_ComboBox::KillFocus() {
- SetPopup(false);
+ if (!SetPopup(false))
+ return;
+
CPWL_Wnd::KillFocus();
}
@@ -309,7 +311,9 @@ void CPWL_ComboBox::CreateListBox(const PWL_CREATEPARAM& cp) {
m_pList->Create(lcp);
}
-void CPWL_ComboBox::RePosChildWnd() {
+bool CPWL_ComboBox::RePosChildWnd() {
+ ObservedPtr thisObserved(this);
+
const CFX_FloatRect rcClient = GetClientRect();
if (m_bPopup) {
const float fOldWindowHeight = m_rcOldWindow.Height();
@@ -331,35 +335,58 @@ void CPWL_ComboBox::RePosChildWnd() {
rcList.bottom += fOldWindowHeight;
}
- if (m_pButton)
+ if (m_pButton) {
m_pButton->Move(rcButton, true, false);
+ if (!thisObserved)
+ return false;
+ }
- if (m_pEdit)
+ if (m_pEdit) {
m_pEdit->Move(rcEdit, true, false);
+ if (!thisObserved)
+ return false;
+ }
if (m_pList) {
- m_pList->SetVisible(true);
- m_pList->Move(rcList, true, false);
+ if (!m_pList->SetVisible(true) || !thisObserved)
+ return false;
+
+ if (!m_pList->Move(rcList, true, false) || !thisObserved)
+ return false;
+
m_pList->ScrollToListItem(m_nSelectItem);
+ if (!thisObserved)
+ return false;
}
- return;
+ return true;
}
CFX_FloatRect rcButton = rcClient;
rcButton.left =
std::max(rcButton.right - PWL_COMBOBOX_BUTTON_WIDTH, rcClient.left);
- if (m_pButton)
+ if (m_pButton) {
m_pButton->Move(rcButton, true, false);
+ if (!thisObserved)
+ return false;
+ }
CFX_FloatRect rcEdit = rcClient;
rcEdit.right = std::max(rcButton.left - 1.0f, rcEdit.left);
- if (m_pEdit)
+ if (m_pEdit) {
m_pEdit->Move(rcEdit, true, false);
+ if (!thisObserved)
+ return false;
+ }
- if (m_pList)
+ if (m_pList) {
m_pList->SetVisible(false);
+ if (!thisObserved)
+ return false;
+ }
+
+ return true;
}
void CPWL_ComboBox::SelectAll() {
@@ -371,27 +398,30 @@ CFX_FloatRect CPWL_ComboBox::GetFocusRect() const {
return CFX_FloatRect();
}
-void CPWL_ComboBox::SetPopup(bool bPopup) {
+bool CPWL_ComboBox::SetPopup(bool bPopup) {
if (!m_pList)
- return;
+ return true;
if (bPopup == m_bPopup)
- return;
+ return true;
float fListHeight = m_pList->GetContentRect().Height();
if (!IsFloatBigger(fListHeight, 0.0f))
- return;
+ return true;
if (!bPopup) {
m_bPopup = bPopup;
- Move(m_rcOldWindow, true, true);
- return;
+ return Move(m_rcOldWindow, true, true);
}
if (!m_pFillerNotify)
- return;
+ return true;
+
+ ObservedPtr thisObserved(this);
#ifdef PDF_ENABLE_XFA
if (m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), 0))
- return;
+ return !!thisObserved;
+ if (!thisObserved)
+ return false;
#endif // PDF_ENABLE_XFA
float fBorderWidth = m_pList->GetBorderWidth() * 2;
@@ -405,7 +435,7 @@ void CPWL_ComboBox::SetPopup(bool bPopup) {
m_pFillerNotify->QueryWherePopup(GetAttachedData(), fPopupMin, fPopupMax,
&bBottom, &fPopupRet);
if (!IsFloatBigger(fPopupRet, 0.0f))
- return;
+ return true;
m_rcOldWindow = CPWL_Wnd::GetWindowRect();
m_bPopup = bPopup;
@@ -417,10 +447,16 @@ void CPWL_ComboBox::SetPopup(bool bPopup) {
else
rcWindow.top += fPopupRet;
- Move(rcWindow, true, true);
+ if (!Move(rcWindow, true, true))
+ return false;
+
#ifdef PDF_ENABLE_XFA
m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), 0);
+ if (!thisObserved)
+ return false;
#endif // PDF_ENABLE_XFA
+
+ return !!thisObserved;
}
bool CPWL_ComboBox::OnKeyDown(uint16_t nChar, uint32_t nFlag) {
@@ -499,8 +535,11 @@ bool CPWL_ComboBox::OnChar(uint16_t nChar, uint32_t nFlag) {
}
void CPWL_ComboBox::NotifyLButtonDown(CPWL_Wnd* child, const CFX_PointF& pos) {
- if (child == m_pButton)
+ if (child == m_pButton) {
SetPopup(!m_bPopup);
+ // Note, |this| may no longer be viable at this point. If more work needs to
+ // be done, check the return value of SetPopup().
+ }
}
void CPWL_ComboBox::NotifyLButtonUp(CPWL_Wnd* child, const CFX_PointF& pos) {
@@ -511,6 +550,8 @@ void CPWL_ComboBox::NotifyLButtonUp(CPWL_Wnd* child, const CFX_PointF& pos) {
SelectAll();
m_pEdit->SetFocus();
SetPopup(false);
+ // Note, |this| may no longer be viable at this point. If more work needs to
+ // be done, check the return value of SetPopup().
}
bool CPWL_ComboBox::IsPopup() const {
diff --git a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_combo_box.h b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_combo_box.h
index 7dc348a7110..a4c998cd358 100644
--- a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_combo_box.h
+++ b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_combo_box.h
@@ -58,7 +58,7 @@ class CPWL_ComboBox : public CPWL_Wnd {
void NotifyLButtonDown(CPWL_Wnd* child, const CFX_PointF& pos) override;
void NotifyLButtonUp(CPWL_Wnd* child, const CFX_PointF& pos) override;
void CreateChildWnd(const PWL_CREATEPARAM& cp) override;
- void RePosChildWnd() override;
+ bool RePosChildWnd() override;
CFX_FloatRect GetFocusRect() const override;
void SetFocus() override;
void KillFocus() override;
@@ -86,7 +86,9 @@ class CPWL_ComboBox : public CPWL_Wnd {
void CreateEdit(const PWL_CREATEPARAM& cp);
void CreateButton(const PWL_CREATEPARAM& cp);
void CreateListBox(const PWL_CREATEPARAM& cp);
- void SetPopup(bool bPopup);
+
+ // Returns |true| iff this instance is still allocated.
+ bool SetPopup(bool bPopup);
CFX_UnownedPtr<CPWL_Edit> m_pEdit;
CFX_UnownedPtr<CPWL_CBButton> m_pButton;
diff --git a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_edit.cpp b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_edit.cpp
index 5dd72365804..ca1c49f4b39 100644
--- a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_edit.cpp
+++ b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_edit.cpp
@@ -79,13 +79,18 @@ void CPWL_Edit::SetText(const CFX_WideString& csText) {
m_pEdit->SetText(swText);
}
-void CPWL_Edit::RePosChildWnd() {
+bool CPWL_Edit::RePosChildWnd() {
if (CPWL_ScrollBar* pVSB = GetVScrollBar()) {
CFX_FloatRect rcWindow = m_rcOldWindow;
CFX_FloatRect rcVScroll =
CFX_FloatRect(rcWindow.right, rcWindow.bottom,
rcWindow.right + PWL_SCROLLBAR_WIDTH, rcWindow.top);
+
+ ObservedPtr thisObserved(this);
+
pVSB->Move(rcVScroll, true, false);
+ if (!thisObserved)
+ return false;
}
if (m_pEditCaret && !HasFlag(PES_TEXTOVERFLOW)) {
@@ -98,7 +103,7 @@ void CPWL_Edit::RePosChildWnd() {
m_pEditCaret->SetClipRect(rect);
}
- CPWL_EditCtrl::RePosChildWnd();
+ return CPWL_EditCtrl::RePosChildWnd();
}
CFX_FloatRect CPWL_Edit::GetClientRect() const {
@@ -290,8 +295,8 @@ bool CPWL_Edit::OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) {
CPWL_Wnd::OnLButtonDown(point, nFlag);
if (HasFlag(PES_TEXTOVERFLOW) || ClientHitTest(point)) {
- if (m_bMouseDown)
- InvalidateRect();
+ if (m_bMouseDown && !InvalidateRect(nullptr))
+ return true;
m_bMouseDown = true;
SetCapture();
@@ -355,17 +360,15 @@ void CPWL_Edit::OnKillFocus() {
if (!observed_ptr)
return;
- Move(m_rcOldWindow, true, true);
+ if (!Move(m_rcOldWindow, true, true))
+ return;
}
- if (!observed_ptr)
- return;
m_pEdit->SelectNone();
if (!observed_ptr)
return;
- SetCaret(false, CFX_PointF(), CFX_PointF());
- if (!observed_ptr)
+ if (!SetCaret(false, CFX_PointF(), CFX_PointF()))
return;
SetCharSet(FX_CHARSET_ANSI);
diff --git a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_edit.h b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_edit.h
index 366d085fdd4..d36f7292578 100644
--- a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_edit.h
+++ b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_edit.h
@@ -46,7 +46,7 @@ class CPWL_Edit : public CPWL_EditCtrl {
// CPWL_EditCtrl
CFX_ByteString GetClassName() const override;
void OnCreated() override;
- void RePosChildWnd() override;
+ bool RePosChildWnd() override;
CFX_FloatRect GetClientRect() const override;
void DrawThisAppearance(CFX_RenderDevice* pDevice,
CFX_Matrix* pUser2Device) override;
diff --git a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_edit_ctrl.cpp b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_edit_ctrl.cpp
index 63d03929e2f..d4315e376bf 100644
--- a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_edit_ctrl.cpp
+++ b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_edit_ctrl.cpp
@@ -59,8 +59,9 @@ CFX_WideString CPWL_EditCtrl::GetSelectedText() {
return CFX_WideString();
}
-void CPWL_EditCtrl::RePosChildWnd() {
+bool CPWL_EditCtrl::RePosChildWnd() {
m_pEdit->SetPlateRect(GetClientRect());
+ return true;
}
void CPWL_EditCtrl::SetScrollInfo(const PWL_SCROLL_INFO& info) {
@@ -256,8 +257,8 @@ bool CPWL_EditCtrl::OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) {
CPWL_Wnd::OnLButtonDown(point, nFlag);
if (ClientHitTest(point)) {
- if (m_bMouseDown)
- InvalidateRect();
+ if (m_bMouseDown && !InvalidateRect(nullptr))
+ return true;
m_bMouseDown = true;
SetCapture();
@@ -299,6 +300,8 @@ void CPWL_EditCtrl::SetEditCaret(bool bVisible) {
GetCaretInfo(&ptHead, &ptFoot);
SetCaret(bVisible, ptHead, ptFoot);
+ // Note, |this| may no longer be viable at this point. If more work needs to
+ // be done, check the return value of SetCaret().
}
void CPWL_EditCtrl::GetCaretInfo(CFX_PointF* ptHead, CFX_PointF* ptFoot) const {
@@ -319,15 +322,21 @@ void CPWL_EditCtrl::GetCaretInfo(CFX_PointF* ptHead, CFX_PointF* ptFoot) const {
}
}
-void CPWL_EditCtrl::SetCaret(bool bVisible,
+bool CPWL_EditCtrl::SetCaret(bool bVisible,
const CFX_PointF& ptHead,
const CFX_PointF& ptFoot) {
- if (m_pEditCaret) {
- if (!IsFocused() || m_pEdit->IsSelected())
- bVisible = false;
+ if (!m_pEditCaret)
+ return true;
- m_pEditCaret->SetCaret(bVisible, ptHead, ptFoot);
- }
+ if (!IsFocused() || m_pEdit->IsSelected())
+ bVisible = false;
+
+ ObservedPtr thisObserved(this);
+ m_pEditCaret->SetCaret(bVisible, ptHead, ptFoot);
+ if (!thisObserved)
+ return false;
+
+ return true;
}
CFX_WideString CPWL_EditCtrl::GetText() const {
diff --git a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_edit_ctrl.h b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_edit_ctrl.h
index 454e579622b..eaf375b6e43 100644
--- a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_edit_ctrl.h
+++ b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_edit_ctrl.h
@@ -56,13 +56,13 @@ class CPWL_EditCtrl : public CPWL_Wnd {
void SetScrollPosition(float pos) override;
void ScrollWindowVertically(float pos) override;
void CreateChildWnd(const PWL_CREATEPARAM& cp) override;
- void RePosChildWnd() override;
+ bool RePosChildWnd() override;
void SetFontSize(float fFontSize) override;
float GetFontSize() const override;
void SetCursor() override;
CFX_WideString GetSelectedText() override;
- void SetCaret(bool bVisible,
+ bool SetCaret(bool bVisible,
const CFX_PointF& ptHead,
const CFX_PointF& ptFoot);
diff --git a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_list_box.cpp b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_list_box.cpp
index ffa5b4780f3..aff9ff25f57 100644
--- a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_list_box.cpp
+++ b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_list_box.cpp
@@ -247,10 +247,12 @@ void CPWL_ListBox::KillFocus() {
CPWL_Wnd::KillFocus();
}
-void CPWL_ListBox::RePosChildWnd() {
- CPWL_Wnd::RePosChildWnd();
+bool CPWL_ListBox::RePosChildWnd() {
+ if (!CPWL_Wnd::RePosChildWnd())
+ return false;
m_pList->SetPlateRect(GetListRect());
+ return true;
}
bool CPWL_ListBox::OnNotifySelectionChanged(bool bKeyDown, uint32_t nFlag) {
diff --git a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_list_box.h b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_list_box.h
index 8bc7651ada0..6a529b54bca 100644
--- a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_list_box.h
+++ b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_list_box.h
@@ -62,7 +62,7 @@ class CPWL_ListBox : public CPWL_Wnd {
void SetScrollInfo(const PWL_SCROLL_INFO& info) override;
void SetScrollPosition(float pos) override;
void ScrollWindowVertically(float pos) override;
- void RePosChildWnd() override;
+ bool RePosChildWnd() override;
CFX_FloatRect GetFocusRect() const override;
void SetFontSize(float fFontSize) override;
float GetFontSize() const override;
diff --git a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_scroll_bar.cpp b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_scroll_bar.cpp
index c607ee795ed..bb6106534c7 100644
--- a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_scroll_bar.cpp
+++ b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_scroll_bar.cpp
@@ -344,7 +344,7 @@ void CPWL_ScrollBar::OnDestroy() {
CPWL_Wnd::OnDestroy();
}
-void CPWL_ScrollBar::RePosChildWnd() {
+bool CPWL_ScrollBar::RePosChildWnd() {
CFX_FloatRect rcClient = GetClientRect();
CFX_FloatRect rcMinButton, rcMaxButton;
float fBWidth = 0;
@@ -367,7 +367,8 @@ void CPWL_ScrollBar::RePosChildWnd() {
rcMaxButton = CFX_FloatRect(rcClient.right - fBWidth, rcClient.bottom,
rcClient.right, rcClient.top);
} else {
- SetVisible(false);
+ if (!SetVisible(false))
+ return false;
}
}
break;
@@ -389,17 +390,31 @@ void CPWL_ScrollBar::RePosChildWnd() {
CFX_FloatRect(rcClient.left, rcClient.bottom, rcClient.right,
rcClient.bottom + fBWidth);
} else {
- SetVisible(false);
+ if (!SetVisible(false))
+ return false;
}
}
break;
}
- if (m_pMinButton)
+ ObservedPtr thisObserved(this);
+
+ if (m_pMinButton) {
m_pMinButton->Move(rcMinButton, true, false);
- if (m_pMaxButton)
+ if (!thisObserved)
+ return false;
+ }
+
+ if (m_pMaxButton) {
m_pMaxButton->Move(rcMaxButton, true, false);
- MovePosButton(false);
+ if (!thisObserved)
+ return false;
+ }
+
+ if (!MovePosButton(false))
+ return false;
+
+ return true;
}
void CPWL_ScrollBar::DrawThisAppearance(CFX_RenderDevice* pDevice,
@@ -428,7 +443,8 @@ bool CPWL_ScrollBar::OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) {
if (HasFlag(PWS_AUTOTRANSPARENT)) {
if (GetTransparency() != 255) {
SetTransparency(255);
- InvalidateRect();
+ if (!InvalidateRect(nullptr))
+ return true;
}
}
@@ -459,13 +475,15 @@ bool CPWL_ScrollBar::OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) {
if (rcMinArea.Contains(point)) {
m_sData.SubBig();
- MovePosButton(true);
+ if (!MovePosButton(true))
+ return true;
NotifyScrollWindow();
}
if (rcMaxArea.Contains(point)) {
m_sData.AddBig();
- MovePosButton(true);
+ if (!MovePosButton(true))
+ return true;
NotifyScrollWindow();
}
}
@@ -479,7 +497,8 @@ bool CPWL_ScrollBar::OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) {
if (HasFlag(PWS_AUTOTRANSPARENT)) {
if (GetTransparency() != PWL_SCROLLBAR_TRANSPARENCY) {
SetTransparency(PWL_SCROLLBAR_TRANSPARENCY);
- InvalidateRect();
+ if (!InvalidateRect(nullptr))
+ return true;
}
}
@@ -560,7 +579,10 @@ void CPWL_ScrollBar::CreateButtons(const PWL_CREATEPARAM& cp) {
if (!m_pPosButton) {
m_pPosButton = new CPWL_SBButton(m_sbType, PSBT_POS);
- m_pPosButton->SetVisible(false);
+
+ ObservedPtr thisObserved(this);
+ if (!m_pPosButton->SetVisible(false) || !thisObserved)
+ return;
m_pPosButton->Create(scp);
}
}
@@ -575,24 +597,37 @@ float CPWL_ScrollBar::GetScrollBarWidth() const {
void CPWL_ScrollBar::SetScrollRange(float fMin,
float fMax,
float fClientWidth) {
- if (m_pPosButton) {
- m_sData.SetScrollRange(fMin, fMax);
- m_sData.SetClientWidth(fClientWidth);
+ if (!m_pPosButton)
+ return;
- if (IsFloatSmaller(m_sData.ScrollRange.GetWidth(), 0.0f)) {
- m_pPosButton->SetVisible(false);
- } else {
- m_pPosButton->SetVisible(true);
- MovePosButton(true);
- }
+ m_sData.SetScrollRange(fMin, fMax);
+ m_sData.SetClientWidth(fClientWidth);
+
+ ObservedPtr thisObserved(this);
+
+ if (IsFloatSmaller(m_sData.ScrollRange.GetWidth(), 0.0f)) {
+ m_pPosButton->SetVisible(false);
+ // Note, |this| may no longer be viable at this point. If more work needs
+ // to be done, check thisObserved.
+ return;
}
+
+ if (!m_pPosButton->SetVisible(true) || !thisObserved)
+ return;
+
+ MovePosButton(true);
+ // Note, |this| may no longer be viable at this point. If more work needs
+ // to be done, check the return value of MovePosButton().
}
void CPWL_ScrollBar::SetScrollPos(float fPos) {
float fOldPos = m_sData.fScrollPos;
m_sData.SetPos(fPos);
- if (!IsFloatEqual(m_sData.fScrollPos, fOldPos))
+ if (!IsFloatEqual(m_sData.fScrollPos, fOldPos)) {
MovePosButton(true);
+ // Note, |this| may no longer be viable at this point. If more work needs
+ // to be done, check the return value of MovePosButton().
+ }
}
void CPWL_ScrollBar::SetScrollStep(float fBigStep, float fSmallStep) {
@@ -600,7 +635,7 @@ void CPWL_ScrollBar::SetScrollStep(float fBigStep, float fSmallStep) {
m_sData.SetSmallStep(fSmallStep);
}
-void CPWL_ScrollBar::MovePosButton(bool bRefresh) {
+bool CPWL_ScrollBar::MovePosButton(bool bRefresh) {
ASSERT(m_pMinButton);
ASSERT(m_pMaxButton);
@@ -648,13 +683,20 @@ void CPWL_ScrollBar::MovePosButton(bool bRefresh) {
break;
}
+ ObservedPtr thisObserved(this);
+
m_pPosButton->Move(rcPosButton, true, bRefresh);
+ if (!thisObserved)
+ return false;
}
+
+ return true;
}
void CPWL_ScrollBar::OnMinButtonLBDown(const CFX_PointF& point) {
m_sData.SubSmall();
- MovePosButton(true);
+ if (!MovePosButton(true))
+ return;
NotifyScrollWindow();
m_bMinOrMax = true;
@@ -669,7 +711,8 @@ void CPWL_ScrollBar::OnMinButtonMouseMove(const CFX_PointF& point) {}
void CPWL_ScrollBar::OnMaxButtonLBDown(const CFX_PointF& point) {
m_sData.AddSmall();
- MovePosButton(true);
+ if (!MovePosButton(true))
+ return;
NotifyScrollWindow();
m_bMinOrMax = false;
@@ -758,7 +801,8 @@ void CPWL_ScrollBar::OnPosButtonMouseMove(const CFX_PointF& point) {
}
if (!IsFloatEqual(fOldScrollPos, m_sData.fScrollPos)) {
- MovePosButton(true);
+ if (!MovePosButton(true))
+ return;
if (m_bNotifyForever)
NotifyScrollWindow();
@@ -875,7 +919,8 @@ void CPWL_ScrollBar::TimerProc() {
m_sData.AddSmall();
if (sTemp != m_sData) {
- MovePosButton(true);
+ if (!MovePosButton(true))
+ return;
NotifyScrollWindow();
}
}
diff --git a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_scroll_bar.h b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_scroll_bar.h
index f9887e5610f..b4ca2e0537b 100644
--- a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_scroll_bar.h
+++ b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_scroll_bar.h
@@ -124,7 +124,7 @@ class CPWL_ScrollBar : public CPWL_Wnd {
CFX_ByteString GetClassName() const override;
void OnCreate(PWL_CREATEPARAM& cp) override;
void OnDestroy() override;
- void RePosChildWnd() override;
+ bool RePosChildWnd() override;
void DrawThisAppearance(CFX_RenderDevice* pDevice,
CFX_Matrix* pUser2Device) override;
bool OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) override;
@@ -145,7 +145,9 @@ class CPWL_ScrollBar : public CPWL_Wnd {
protected:
void SetScrollRange(float fMin, float fMax, float fClientWidth);
void SetScrollPos(float fPos);
- void MovePosButton(bool bRefresh);
+
+ // Returns |true| iff this instance is still allocated.
+ bool MovePosButton(bool bRefresh);
void SetScrollStep(float fBigStep, float fSmallStep);
void NotifyScrollWindow();
CFX_FloatRect GetScrollArea() const;
diff --git a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_wnd.cpp b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_wnd.cpp
index 223182c2967..cd0b7eb2713 100644
--- a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_wnd.cpp
+++ b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_wnd.cpp
@@ -179,7 +179,9 @@ void CPWL_Wnd::Create(const PWL_CREATEPARAM& cp) {
m_bVisible = HasFlag(PWS_VISIBLE);
OnCreated();
- RePosChildWnd();
+ if (!RePosChildWnd())
+ return;
+
m_bCreated = true;
}
@@ -205,7 +207,8 @@ void CPWL_Wnd::Destroy() {
if (m_bCreated) {
m_pVScrollBar = nullptr;
for (auto it = m_Children.rbegin(); it != m_Children.rend(); ++it) {
- if (CPWL_Wnd* pChild = *it) {
+ CPWL_Wnd* pChild = *it;
+ if (pChild) {
*it = nullptr;
pChild->Destroy();
delete pChild;
@@ -221,9 +224,9 @@ void CPWL_Wnd::Destroy() {
m_Children.clear();
}
-void CPWL_Wnd::Move(const CFX_FloatRect& rcNew, bool bReset, bool bRefresh) {
+bool CPWL_Wnd::Move(const CFX_FloatRect& rcNew, bool bReset, bool bRefresh) {
if (!IsValid())
- return;
+ return true;
CFX_FloatRect rcOld = GetWindowRect();
m_rcWindow = rcNew;
@@ -232,21 +235,23 @@ void CPWL_Wnd::Move(const CFX_FloatRect& rcNew, bool bReset, bool bRefresh) {
if (bReset) {
if (rcOld.left != rcNew.left || rcOld.right != rcNew.right ||
rcOld.top != rcNew.top || rcOld.bottom != rcNew.bottom) {
- RePosChildWnd();
+ if (!RePosChildWnd())
+ return false;
}
}
- if (bRefresh)
- InvalidateRectMove(rcOld, rcNew);
+ if (bRefresh && !InvalidateRectMove(rcOld, rcNew))
+ return false;
m_sPrivateParam.rcRectWnd = m_rcWindow;
+ return true;
}
-void CPWL_Wnd::InvalidateRectMove(const CFX_FloatRect& rcOld,
+bool CPWL_Wnd::InvalidateRectMove(const CFX_FloatRect& rcOld,
const CFX_FloatRect& rcNew) {
CFX_FloatRect rcUnion = rcOld;
rcUnion.Union(rcNew);
- InvalidateRect(&rcUnion);
+ return InvalidateRect(&rcUnion);
}
void CPWL_Wnd::DrawAppearance(CFX_RenderDevice* pDevice,
@@ -294,9 +299,10 @@ void CPWL_Wnd::DrawChildAppearance(CFX_RenderDevice* pDevice,
}
}
-void CPWL_Wnd::InvalidateRect(CFX_FloatRect* pRect) {
+bool CPWL_Wnd::InvalidateRect(CFX_FloatRect* pRect) {
+ ObservedPtr thisObserved(this);
if (!IsValid())
- return;
+ return true;
CFX_FloatRect rcRefresh = pRect ? *pRect : GetWindowRect();
@@ -317,8 +323,12 @@ void CPWL_Wnd::InvalidateRect(CFX_FloatRect* pRect) {
if (CPDFSDK_Widget* widget = static_cast<CPDFSDK_Widget*>(
m_sPrivateParam.pAttachedWidget.Get())) {
pSH->InvalidateRect(widget, rcWin);
+ if (!thisObserved)
+ return false;
}
}
+
+ return true;
}
#define PWL_IMPLEMENT_KEY_METHOD(key_method_name) \
@@ -576,19 +586,29 @@ const CPWL_Wnd* CPWL_Wnd::GetRootWnd() const {
return pParent ? pParent->GetRootWnd() : this;
}
-void CPWL_Wnd::SetVisible(bool bVisible) {
+bool CPWL_Wnd::SetVisible(bool bVisible) {
if (!IsValid())
- return;
+ return true;
+
+ ObservedPtr thisObserved(this);
for (auto* pChild : m_Children) {
- if (pChild)
+ if (pChild) {
pChild->SetVisible(bVisible);
+ if (!thisObserved)
+ return false;
+ }
}
+
if (bVisible != m_bVisible) {
m_bVisible = bVisible;
- RePosChildWnd();
- InvalidateRect();
+ if (!RePosChildWnd())
+ return false;
+
+ if (!InvalidateRect(nullptr))
+ return false;
}
+ return true;
}
void CPWL_Wnd::SetClipRect(const CFX_FloatRect& rect) {
@@ -604,10 +624,10 @@ bool CPWL_Wnd::IsReadOnly() const {
return HasFlag(PWS_READONLY);
}
-void CPWL_Wnd::RePosChildWnd() {
+bool CPWL_Wnd::RePosChildWnd() {
CPWL_ScrollBar* pVSB = GetVScrollBar();
if (!pVSB)
- return;
+ return true;
CFX_FloatRect rcContent = GetWindowRect();
if (!rcContent.IsEmpty()) {
@@ -618,7 +638,14 @@ void CPWL_Wnd::RePosChildWnd() {
CFX_FloatRect rcVScroll =
CFX_FloatRect(rcContent.right - PWL_SCROLLBAR_WIDTH, rcContent.bottom,
rcContent.right - 1.0f, rcContent.top);
+
+ ObservedPtr thisObserved(this);
+
pVSB->Move(rcVScroll, true, false);
+ if (!thisObserved)
+ return false;
+
+ return true;
}
void CPWL_Wnd::CreateChildWnd(const PWL_CREATEPARAM& cp) {}
diff --git a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_wnd.h b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_wnd.h
index 56fbb21baa0..a5b87e6572f 100644
--- a/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_wnd.h
+++ b/chromium/third_party/pdfium/fpdfsdk/pdfwindow/cpwl_wnd.h
@@ -174,7 +174,9 @@ class CPWL_Wnd : public CPWL_TimerHandler, public CFX_Observable<CPWL_Wnd> {
~CPWL_Wnd() override;
virtual CFX_ByteString GetClassName() const;
- virtual void InvalidateRect(CFX_FloatRect* pRect = nullptr);
+
+ // Returns |true| iff this instance is still allocated.
+ virtual bool InvalidateRect(CFX_FloatRect* pRect);
virtual bool OnKeyDown(uint16_t nChar, uint32_t nFlag);
virtual bool OnChar(uint16_t nChar, uint32_t nFlag);
@@ -196,7 +198,9 @@ class CPWL_Wnd : public CPWL_TimerHandler, public CFX_Observable<CPWL_Wnd> {
virtual void SetFocus();
virtual void KillFocus();
virtual void SetCursor();
- virtual void SetVisible(bool bVisible);
+
+ // Returns |true| iff this instance is still allocated.
+ virtual bool SetVisible(bool bVisible);
virtual void SetFontSize(float fFontSize);
virtual float GetFontSize() const;
@@ -208,7 +212,7 @@ class CPWL_Wnd : public CPWL_TimerHandler, public CFX_Observable<CPWL_Wnd> {
void InvalidateProvider(IPWL_Provider* provider);
void Create(const PWL_CREATEPARAM& cp);
void Destroy();
- void Move(const CFX_FloatRect& rcNew, bool bReset, bool bRefresh);
+ bool Move(const CFX_FloatRect& rcNew, bool bReset, bool bRefresh);
void SetCapture();
void ReleaseCapture();
@@ -273,7 +277,9 @@ class CPWL_Wnd : public CPWL_TimerHandler, public CFX_Observable<CPWL_Wnd> {
CFX_SystemHandler* GetSystemHandler() const override;
virtual void CreateChildWnd(const PWL_CREATEPARAM& cp);
- virtual void RePosChildWnd();
+
+ // Returns |true| iff this instance is still allocated.
+ virtual bool RePosChildWnd();
virtual void DrawThisAppearance(CFX_RenderDevice* pDevice,
CFX_Matrix* pUser2Device);
@@ -291,7 +297,8 @@ class CPWL_Wnd : public CPWL_TimerHandler, public CFX_Observable<CPWL_Wnd> {
const PWL_CREATEPARAM& GetCreationParam() const;
bool IsNotifying() const { return m_bNotifying; }
- void InvalidateRectMove(const CFX_FloatRect& rcOld,
+ // Returns |true| iff this instance is still allocated.
+ bool InvalidateRectMove(const CFX_FloatRect& rcOld,
const CFX_FloatRect& rcNew);
bool IsWndCaptureMouse(const CPWL_Wnd* pWnd) const;