[Libreoffice-commits] core.git: 2 commits - editeng/Library_editeng.mk editeng/source framework/source include/editeng vcl/source
Caolán McNamara (via logerrit)
logerrit at kemper.freedesktop.org
Tue Jun 25 16:14:18 UTC 2019
editeng/Library_editeng.mk | 1
editeng/source/misc/weldeditview.cxx | 147 ++++++++++++++++++++++++++
framework/source/uielement/menubarmanager.cxx | 4
include/editeng/weldeditview.hxx | 62 ++++++++++
vcl/source/control/menubtn.cxx | 4
vcl/source/window/menu.cxx | 3
6 files changed, 220 insertions(+), 1 deletion(-)
New commits:
commit 0e79841b4f16ea71b019f298e7887c3c74efeb7e
Author: Caolán McNamara <caolanm at redhat.com>
AuthorDate: Tue Jun 25 14:00:20 2019 +0100
Commit: Caolán McNamara <caolanm at redhat.com>
CommitDate: Tue Jun 25 18:13:36 2019 +0200
tdf#126054 uses after free when menubutton and menu torn down during execution
Change-Id: Ib79da121941863421bc12afa27e27cdd7e2e81e3
Reviewed-on: https://gerrit.libreoffice.org/74695
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
Tested-by: Caolán McNamara <caolanm at redhat.com>
diff --git a/framework/source/uielement/menubarmanager.cxx b/framework/source/uielement/menubarmanager.cxx
index 2638f9a8c022..fd61a275caeb 100644
--- a/framework/source/uielement/menubarmanager.cxx
+++ b/framework/source/uielement/menubarmanager.cxx
@@ -890,7 +890,9 @@ IMPL_LINK( MenuBarManager, Select, Menu *, pMenu, bool )
}
}
- if ( xDispatch.is() )
+ // tdf#126054 don't let dispatch destroy this until after function completes
+ rtl::Reference<MenuBarManager> xRef(this);
+ if (xDispatch.is())
{
SolarMutexReleaser aReleaser;
xDispatch->dispatch( aTargetURL, aArgs );
diff --git a/vcl/source/control/menubtn.cxx b/vcl/source/control/menubtn.cxx
index c6f6123c1a92..ccf336a46375 100644
--- a/vcl/source/control/menubtn.cxx
+++ b/vcl/source/control/menubtn.cxx
@@ -51,6 +51,10 @@ void MenuButton::ExecuteMenu()
Point aPos(0, 1);
tools::Rectangle aRect(aPos, aSize );
mpMenu->Execute(this, aRect, PopupMenuFlags::ExecuteDown);
+
+ if (IsDisposed())
+ return;
+
mnCurItemId = mpMenu->GetCurItemId();
msCurItemIdent = mpMenu->GetCurItemIdent();
}
diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx
index 516d5930d183..87440cf3825d 100644
--- a/vcl/source/window/menu.cxx
+++ b/vcl/source/window/menu.cxx
@@ -2968,6 +2968,9 @@ sal_uInt16 PopupMenu::ImplExecute( const VclPtr<vcl::Window>& pW, const tools::R
aSz.setHeight( ImplCalcHeight( nEntries ) );
}
+ // tdf#126054 hold this until after function completes
+ VclPtr<PopupMenu> m_xThis(this);
+
pWin->SetFocusId( xFocusId );
pWin->SetOutputSizePixel( aSz );
if ( GetItemCount() )
commit 7b726e587ec7bbe8926fd00a50c0192ad32b3858
Author: Caolán McNamara <caolanm at redhat.com>
AuthorDate: Tue Jun 25 14:20:29 2019 +0100
Commit: Caolán McNamara <caolanm at redhat.com>
CommitDate: Tue Jun 25 18:13:24 2019 +0200
factor out to a common WeldEditView
Change-Id: Ife7b6f57c80d310bd11a8ed89e36fdc99742d158
Reviewed-on: https://gerrit.libreoffice.org/74698
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
Tested-by: Caolán McNamara <caolanm at redhat.com>
diff --git a/editeng/Library_editeng.mk b/editeng/Library_editeng.mk
index 9354071b3a70..fc47842b650f 100644
--- a/editeng/Library_editeng.mk
+++ b/editeng/Library_editeng.mk
@@ -98,6 +98,7 @@ $(eval $(call gb_Library_add_exception_objects,editeng,\
editeng/source/misc/swafopt \
editeng/source/misc/txtrange \
editeng/source/misc/unolingu \
+ editeng/source/misc/weldeditview \
editeng/source/outliner/outleeng \
editeng/source/outliner/outlin2 \
editeng/source/outliner/outliner \
diff --git a/editeng/source/misc/weldeditview.cxx b/editeng/source/misc/weldeditview.cxx
new file mode 100644
index 000000000000..dab3796f9b17
--- /dev/null
+++ b/editeng/source/misc/weldeditview.cxx
@@ -0,0 +1,147 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#include <editeng/weldeditview.hxx>
+#include <vcl/cursor.hxx>
+#include <vcl/event.hxx>
+#include <vcl/ptrstyle.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+
+Size WeldEditView::GetPreferredSize() const { return Size(500, 100); }
+
+void WeldEditView::SetDrawingArea(weld::DrawingArea* pDrawingArea)
+{
+ Size aSize(GetPreferredSize());
+ pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
+ SetOutputSizePixel(aSize);
+
+ weld::CustomWidgetController::SetDrawingArea(pDrawingArea);
+
+ EnableRTL(false);
+
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ Color aBgColor = rStyleSettings.GetWindowColor();
+
+ OutputDevice& rDevice = pDrawingArea->get_ref_device();
+
+ rDevice.SetMapMode(MapMode(MapUnit::MapTwip));
+ rDevice.SetBackground(aBgColor);
+
+ Size aOutputSize(rDevice.PixelToLogic(aSize));
+ aSize = aOutputSize;
+ aSize.setHeight(aSize.Height());
+
+ m_xEdEngine.reset(new EditEngine(EditEngine::CreatePool()));
+ m_xEdEngine->SetPaperSize(aSize);
+ m_xEdEngine->SetRefDevice(&rDevice);
+
+ m_xEdEngine->SetControlWord(m_xEdEngine->GetControlWord() | EEControlBits::MARKFIELDS);
+
+ m_xEdView.reset(new EditView(m_xEdEngine.get(), nullptr));
+ m_xEdView->setEditViewCallbacks(this);
+ m_xEdView->SetOutputArea(tools::Rectangle(Point(0, 0), aOutputSize));
+
+ m_xEdView->SetBackgroundColor(aBgColor);
+ m_xEdEngine->InsertView(m_xEdView.get());
+
+ pDrawingArea->set_cursor(PointerStyle::Text);
+}
+
+WeldEditView::~WeldEditView() {}
+
+void WeldEditView::Resize()
+{
+ OutputDevice& rDevice = GetDrawingArea()->get_ref_device();
+ Size aOutputSize(rDevice.PixelToLogic(GetOutputSizePixel()));
+ Size aSize(aOutputSize);
+ m_xEdEngine->SetPaperSize(aSize);
+ m_xEdView->SetOutputArea(tools::Rectangle(Point(0, 0), aOutputSize));
+ weld::CustomWidgetController::Resize();
+}
+
+void WeldEditView::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
+{
+ //note: ScEditWindow::Paint is similar
+
+ rRenderContext.Push(PushFlags::ALL);
+ rRenderContext.SetClipRegion();
+
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ Color aBgColor = rStyleSettings.GetWindowColor();
+
+ m_xEdView->SetBackgroundColor(aBgColor);
+
+ rRenderContext.SetBackground(aBgColor);
+
+ tools::Rectangle aLogicRect(rRenderContext.PixelToLogic(rRect));
+ m_xEdView->Paint(aLogicRect, &rRenderContext);
+
+ if (HasFocus())
+ {
+ m_xEdView->ShowCursor();
+ vcl::Cursor* pCursor = m_xEdView->GetCursor();
+ pCursor->DrawToDevice(rRenderContext);
+ }
+
+ std::vector<tools::Rectangle> aLogicRects;
+
+ // get logic selection
+ m_xEdView->GetSelectionRectangles(aLogicRects);
+
+ rRenderContext.SetLineColor();
+ rRenderContext.SetFillColor(COL_BLACK);
+ rRenderContext.SetRasterOp(RasterOp::Invert);
+
+ for (const auto& rSelectionRect : aLogicRects)
+ rRenderContext.DrawRect(rSelectionRect);
+
+ rRenderContext.Pop();
+}
+
+bool WeldEditView::MouseMove(const MouseEvent& rMEvt) { return m_xEdView->MouseMove(rMEvt); }
+
+bool WeldEditView::MouseButtonDown(const MouseEvent& rMEvt)
+{
+ if (!HasFocus())
+ GrabFocus();
+
+ return m_xEdView->MouseButtonDown(rMEvt);
+}
+
+bool WeldEditView::MouseButtonUp(const MouseEvent& rMEvt)
+{
+ return m_xEdView->MouseButtonUp(rMEvt);
+}
+
+bool WeldEditView::KeyInput(const KeyEvent& rKEvt)
+{
+ sal_uInt16 nKey = rKEvt.GetKeyCode().GetCode();
+
+ if (nKey == KEY_TAB)
+ {
+ return false;
+ }
+ else if (!m_xEdView->PostKeyEvent(rKEvt))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void WeldEditView::GetFocus()
+{
+ m_xEdView->ShowCursor();
+
+ weld::CustomWidgetController::GetFocus();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/editeng/weldeditview.hxx b/include/editeng/weldeditview.hxx
new file mode 100644
index 000000000000..3d31f589d14f
--- /dev/null
+++ b/include/editeng/weldeditview.hxx
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#ifndef INCLUDED_EDITENG_WELDEDITVIEW_HXX
+#define INCLUDED_EDITENG_WELDEDITVIEW_HXX
+
+#include <sal/config.h>
+#include <editeng/editengdllapi.h>
+#include <editeng/editeng.hxx>
+#include <editeng/editview.hxx>
+#include <vcl/customweld.hxx>
+#include <vcl/outdev.hxx>
+
+class EDITENG_DLLPUBLIC WeldEditView : public weld::CustomWidgetController, public EditViewCallbacks
+{
+public:
+ WeldEditView();
+ virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
+ virtual ~WeldEditView() override;
+
+ std::unique_ptr<EditEngine> m_xEdEngine;
+ std::unique_ptr<EditView> m_xEdView;
+
+protected:
+ virtual Size GetPreferredSize() const;
+ virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override;
+ virtual bool MouseMove(const MouseEvent& rMEvt) override;
+ virtual bool MouseButtonDown(const MouseEvent& rMEvt) override;
+ virtual bool MouseButtonUp(const MouseEvent& rMEvt) override;
+ virtual bool KeyInput(const KeyEvent& rKEvt) override;
+ virtual void GetFocus() override;
+ virtual void Resize() override;
+
+ virtual void EditViewInvalidate(const tools::Rectangle& rRect) const override
+ {
+ weld::DrawingArea* pDrawingArea = GetDrawingArea();
+ pDrawingArea->queue_draw_area(rRect.Left(), rRect.Top(), rRect.GetWidth(),
+ rRect.GetHeight());
+ }
+
+ virtual void EditViewSelectionChange() const override
+ {
+ weld::DrawingArea* pDrawingArea = GetDrawingArea();
+ pDrawingArea->queue_draw();
+ }
+
+ virtual OutputDevice& EditViewOutputDevice() const override
+ {
+ return GetDrawingArea()->get_ref_device();
+ }
+};
+
+#endif // INCLUDED_EDITENG_WELDEDITVIEW_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
More information about the Libreoffice-commits
mailing list