tdf#158913 secure Primitive 'visit' using mutex
See text in tdf task for detailed description. Change-Id: I4677c9f2ecfdcb760d05fe916a2aa2dd25ad40b6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161543 Tested-by: Jenkins Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
This commit is contained in:
parent
69181dd430
commit
e1402abc5c
4 changed files with 84 additions and 46 deletions
|
@ -70,32 +70,38 @@ BufferedDecompositionGroupPrimitive2D::getBuffered2DDecomposition() const
|
|||
|
||||
void BufferedDecompositionGroupPrimitive2D::setBuffered2DDecomposition(Primitive2DContainer&& rNew)
|
||||
{
|
||||
if (0 != maCallbackSeconds)
|
||||
if (0 == maCallbackSeconds)
|
||||
{
|
||||
if (maCallbackTimer.is())
|
||||
{
|
||||
if (rNew.empty())
|
||||
{
|
||||
// stop timer
|
||||
maCallbackTimer->stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
// decomposition changed, touch
|
||||
maCallbackTimer->setRemainingTime(salhelper::TTimeValue(maCallbackSeconds, 0));
|
||||
if (!maCallbackTimer->isTicking())
|
||||
maCallbackTimer->start();
|
||||
}
|
||||
}
|
||||
else if (!rNew.empty())
|
||||
{
|
||||
// decomposition defined/set/changed, init & start timer
|
||||
maCallbackTimer.set(new LocalCallbackTimer(*this));
|
||||
maCallbackTimer->setRemainingTime(salhelper::TTimeValue(maCallbackSeconds, 0));
|
||||
maCallbackTimer->start();
|
||||
}
|
||||
// no flush used, just set
|
||||
maBuffered2DDecomposition = std::move(rNew);
|
||||
return;
|
||||
}
|
||||
|
||||
if (maCallbackTimer.is())
|
||||
{
|
||||
if (rNew.empty())
|
||||
{
|
||||
// stop timer
|
||||
maCallbackTimer->stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
// decomposition changed, touch
|
||||
maCallbackTimer->setRemainingTime(salhelper::TTimeValue(maCallbackSeconds, 0));
|
||||
if (!maCallbackTimer->isTicking())
|
||||
maCallbackTimer->start();
|
||||
}
|
||||
}
|
||||
else if (!rNew.empty())
|
||||
{
|
||||
// decomposition defined/set/changed, init & start timer
|
||||
maCallbackTimer.set(new LocalCallbackTimer(*this));
|
||||
maCallbackTimer->setRemainingTime(salhelper::TTimeValue(maCallbackSeconds, 0));
|
||||
maCallbackTimer->start();
|
||||
}
|
||||
|
||||
// tdf#158913 need to secure change when flush/multithreading is in use
|
||||
std::lock_guard Guard(maCallbackLock);
|
||||
maBuffered2DDecomposition = std::move(rNew);
|
||||
}
|
||||
|
||||
|
@ -103,6 +109,7 @@ BufferedDecompositionGroupPrimitive2D::BufferedDecompositionGroupPrimitive2D(
|
|||
Primitive2DContainer&& aChildren)
|
||||
: GroupPrimitive2D(std::move(aChildren))
|
||||
, maCallbackTimer()
|
||||
, maCallbackLock()
|
||||
, maCallbackSeconds(0)
|
||||
{
|
||||
}
|
||||
|
@ -129,6 +136,17 @@ void BufferedDecompositionGroupPrimitive2D::get2DDecomposition(
|
|||
std::move(aNewSequence));
|
||||
}
|
||||
|
||||
if (0 == maCallbackSeconds)
|
||||
{
|
||||
// no flush/multithreading is in use, just call
|
||||
rVisitor.visit(getBuffered2DDecomposition());
|
||||
return;
|
||||
}
|
||||
|
||||
// tdf#158913 need to secure 'visit' when flush/multithreading is in use,
|
||||
// so that the local non-ref-Counted instance of the decomposition gets not
|
||||
// manipulated (e.g. deleted)
|
||||
std::lock_guard Guard(maCallbackLock);
|
||||
rVisitor.visit(getBuffered2DDecomposition());
|
||||
}
|
||||
|
||||
|
|
|
@ -69,38 +69,45 @@ const Primitive2DContainer& BufferedDecompositionPrimitive2D::getBuffered2DDecom
|
|||
|
||||
void BufferedDecompositionPrimitive2D::setBuffered2DDecomposition(Primitive2DContainer&& rNew)
|
||||
{
|
||||
if (0 != maCallbackSeconds)
|
||||
if (0 == maCallbackSeconds)
|
||||
{
|
||||
if (maCallbackTimer.is())
|
||||
{
|
||||
if (rNew.empty())
|
||||
{
|
||||
// stop timer
|
||||
maCallbackTimer->stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
// decomposition changed, touch
|
||||
maCallbackTimer->setRemainingTime(salhelper::TTimeValue(maCallbackSeconds, 0));
|
||||
if (!maCallbackTimer->isTicking())
|
||||
maCallbackTimer->start();
|
||||
}
|
||||
}
|
||||
else if (!rNew.empty())
|
||||
{
|
||||
// decomposition defined/set/changed, init & start timer
|
||||
maCallbackTimer.set(new LocalCallbackTimer(*this));
|
||||
maCallbackTimer->setRemainingTime(salhelper::TTimeValue(maCallbackSeconds, 0));
|
||||
maCallbackTimer->start();
|
||||
}
|
||||
// no flush used, just set
|
||||
maBuffered2DDecomposition = std::move(rNew);
|
||||
return;
|
||||
}
|
||||
|
||||
if (maCallbackTimer.is())
|
||||
{
|
||||
if (rNew.empty())
|
||||
{
|
||||
// stop timer
|
||||
maCallbackTimer->stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
// decomposition changed, touch
|
||||
maCallbackTimer->setRemainingTime(salhelper::TTimeValue(maCallbackSeconds, 0));
|
||||
if (!maCallbackTimer->isTicking())
|
||||
maCallbackTimer->start();
|
||||
}
|
||||
}
|
||||
else if (!rNew.empty())
|
||||
{
|
||||
// decomposition defined/set/changed, init & start timer
|
||||
maCallbackTimer.set(new LocalCallbackTimer(*this));
|
||||
maCallbackTimer->setRemainingTime(salhelper::TTimeValue(maCallbackSeconds, 0));
|
||||
maCallbackTimer->start();
|
||||
}
|
||||
|
||||
// tdf#158913 need to secure change when flush/multithreading is in use
|
||||
std::lock_guard Guard(maCallbackLock);
|
||||
maBuffered2DDecomposition = std::move(rNew);
|
||||
}
|
||||
|
||||
BufferedDecompositionPrimitive2D::BufferedDecompositionPrimitive2D()
|
||||
: maBuffered2DDecomposition()
|
||||
, maCallbackTimer()
|
||||
, maCallbackLock()
|
||||
, maCallbackSeconds(0)
|
||||
, mnTransparenceForShadow(0)
|
||||
{
|
||||
|
@ -128,6 +135,17 @@ void BufferedDecompositionPrimitive2D::get2DDecomposition(
|
|||
std::move(aNewSequence));
|
||||
}
|
||||
|
||||
if (0 == maCallbackSeconds)
|
||||
{
|
||||
// no flush/multithreading is in use, just call
|
||||
rVisitor.visit(getBuffered2DDecomposition());
|
||||
return;
|
||||
}
|
||||
|
||||
// tdf#158913 need to secure 'visit' when flush/multithreading is in use,
|
||||
// so that the local non-ref-Counted instance of the decomposition gets not
|
||||
// manipulated (e.g. deleted)
|
||||
std::lock_guard Guard(maCallbackLock);
|
||||
rVisitor.visit(getBuffered2DDecomposition());
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ private:
|
|||
|
||||
/// offer callback mechanism to flush buffered content timer-based
|
||||
::rtl::Reference<::salhelper::Timer> maCallbackTimer;
|
||||
mutable std::mutex maCallbackLock;
|
||||
sal_uInt16 maCallbackSeconds;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -71,6 +71,7 @@ private:
|
|||
|
||||
/// offer callback mechanism to flush buffered content timer-based
|
||||
::rtl::Reference<::salhelper::Timer> maCallbackTimer;
|
||||
mutable std::mutex maCallbackLock;
|
||||
sal_uInt16 maCallbackSeconds;
|
||||
|
||||
/// When a shadow wraps a list of primitives, this primitive wants to influence the transparency
|
||||
|
|
Loading…
Reference in a new issue