[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-5.3' - 9 commits - configure.ac filter/source include/o3tl shell/source sw/inc sw/qa sw/source vcl/headless vcl/source vcl/unx

Andras Timar andras.timar at collabora.com
Thu May 18 13:42:04 UTC 2017


 configure.ac                              |    2 
 filter/source/graphicfilter/ieps/ieps.cxx |    2 
 filter/source/xsltfilter/OleHandler.cxx   |   10 +-
 include/o3tl/safeint.hxx                  |   89 +++++++++++++++++++
 shell/source/win32/SysShExec.cxx          |   22 ++++
 sw/inc/swtypes.hxx                        |    6 -
 sw/qa/extras/uiwriter/uiwriter.cxx        |  134 ++++++++++++++++++++++++++++++
 sw/source/core/layout/findfrm.cxx         |    2 
 sw/source/core/layout/flowfrm.cxx         |    2 
 sw/source/core/layout/tabfrm.cxx          |   16 +++
 sw/source/core/txtnode/thints.cxx         |   12 ++
 sw/source/core/undo/undobj1.cxx           |    2 
 sw/source/filter/ww8/ww8par.cxx           |    2 
 vcl/headless/svpbmp.cxx                   |   18 +++-
 vcl/source/gdi/salmisc.cxx                |   19 ++++
 vcl/unx/generic/gdi/salbmp.cxx            |   17 +++
 16 files changed, 339 insertions(+), 16 deletions(-)

New commits:
commit e639c2ad9c05a793b16db13bd879342ed75dcf95
Author: Andras Timar <andras.timar at collabora.com>
Date:   Thu May 18 15:38:18 2017 +0200

    Bump version to 5.3-13
    
    Change-Id: I6c5390ed7a6bb8298433c7897c5c3df7a220a82a

diff --git a/configure.ac b/configure.ac
index 0a0fb569b4ff..a157a0341cd4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -9,7 +9,7 @@ dnl in order to create a configure script.
 # several non-alphanumeric characters, those are split off and used only for the
 # ABOUTBOXPRODUCTVERSIONSUFFIX in openoffice.lst. Why that is necessary, no idea.
 
-AC_INIT([Collabora Office],[5.3.10.12],[],[],[https://collaboraoffice.com/])
+AC_INIT([Collabora Office],[5.3.10.13],[],[],[https://collaboraoffice.com/])
 
 AC_PREREQ([2.59])
 
commit 668e824b8885345d8c8d7847df5e8db002a57afc
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Mon May 15 11:17:57 2017 +0100

    ofz#1605 check multiply and shift
    
    Change-Id: I6aad9ad23e7bf080b3b610223f92df7074530beb
    Reviewed-on: https://gerrit.libreoffice.org/37642
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    (cherry picked from commit d881d77429371c3a04b758b151b091267c13d167)

diff --git a/include/o3tl/safeint.hxx b/include/o3tl/safeint.hxx
new file mode 100644
index 000000000000..ce144d22d9ea
--- /dev/null
+++ b/include/o3tl/safeint.hxx
@@ -0,0 +1,89 @@
+/* -*- 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_O3TL_SAFEINT_HXX
+#define INCLUDED_O3TL_SAFEINT_HXX
+
+#include <limits>
+#if defined(_MSC_VER)
+#include <safeint.h>
+#else
+#ifndef __has_builtin
+#   define __has_builtin(x) 0
+#endif
+#endif
+
+namespace o3tl
+{
+
+#if defined(_MSC_VER)
+
+template<typename T> inline bool checked_multiply(T a, T b, T& result)
+{
+    return !msl::utilities::SafeMultiply(a, b, result);
+}
+
+#elif (defined __GNUC__ && __GNUC__ >= 5) || (__has_builtin(__builtin_mul_overflow))
+
+template<typename T> inline bool checked_multiply(T a, T b, T& result)
+{
+    return __builtin_mul_overflow(a, b, &result);
+}
+
+#else
+
+//https://www.securecoding.cert.org/confluence/display/c/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow
+template<typename T> inline typename std::enable_if<std::is_signed<T>::value, bool>::type checked_multiply(T a, T b, T& result)
+{
+  if (a > 0) {  /* a is positive */
+    if (b > 0) {  /* a and b are positive */
+      if (a > (std::numeric_limits<T>::max() / b)) {
+        return true; /* Handle error */
+      }
+    } else { /* a positive, b nonpositive */
+      if (b < (std::numeric_limits<T>::min() / a)) {
+        return true; /* Handle error */
+      }
+    } /* a positive, b nonpositive */
+  } else { /* a is nonpositive */
+    if (b > 0) { /* a is nonpositive, b is positive */
+      if (a < (std::numeric_limits<T>::min() / b)) {
+        return true; /* Handle error */
+      }
+    } else { /* a and b are nonpositive */
+      if ( (a != 0) && (b < (std::numeric_limits<T>::max() / a))) {
+        return true; /* Handle error */
+      }
+    } /* End if a and b are nonpositive */
+  } /* End if a is nonpositive */
+
+  result = a * b;
+
+  return false;
+}
+
+//https://www.securecoding.cert.org/confluence/display/c/INT30-C.+Ensure+that+unsigned+integer+operations+do+not+wrap
+template<typename T> inline typename std::enable_if<std::is_unsigned<T>::value, bool>::type checked_multiply(T a, T b, T& result)
+{
+    if (b && a > std::numeric_limits<T>::max() / b) {
+        return true;/* Handle error */
+    }
+
+    result = a * b;
+
+    return false;
+}
+
+#endif
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/headless/svpbmp.cxx b/vcl/headless/svpbmp.cxx
index 202d63c0a84e..71c5e52586c6 100644
--- a/vcl/headless/svpbmp.cxx
+++ b/vcl/headless/svpbmp.cxx
@@ -27,7 +27,7 @@
 
 #include <basegfx/vector/b2ivector.hxx>
 #include <basegfx/range/b2ibox.hxx>
-
+#include <o3tl/safeint.hxx>
 #include <vcl/salbtype.hxx>
 #include <vcl/bitmap.hxx>
 
@@ -110,7 +110,21 @@ BitmapBuffer* ImplCreateDIB(
             pDIB->mnFormat |= ScanlineFormat::TopDown;
             pDIB->mnWidth = rSize.Width();
             pDIB->mnHeight = rSize.Height();
-            pDIB->mnScanlineSize = AlignedWidth4Bytes( pDIB->mnWidth * nBitCount );
+            long nScanlineBase;
+            bool bFail = o3tl::checked_multiply<long>(pDIB->mnWidth, nBitCount, nScanlineBase);
+            if (bFail)
+            {
+                SAL_WARN("vcl.gdi", "checked multiply failed");
+                delete pDIB;
+                return nullptr;
+            }
+            pDIB->mnScanlineSize = AlignedWidth4Bytes(nScanlineBase);
+            if (pDIB->mnScanlineSize < nScanlineBase/8)
+            {
+                SAL_WARN("vcl.gdi", "scanline calculation wraparound");
+                delete pDIB;
+                return nullptr;
+            }
             pDIB->mnBitCount = nBitCount;
 
             if( nColors )
diff --git a/vcl/source/gdi/salmisc.cxx b/vcl/source/gdi/salmisc.cxx
index 84c7becceea4..0218c320e92b 100644
--- a/vcl/source/gdi/salmisc.cxx
+++ b/vcl/source/gdi/salmisc.cxx
@@ -20,6 +20,7 @@
 #include <vcl/bitmapaccess.hxx>
 #include <vcl/salbtype.hxx>
 #include <bmpfast.hxx>
+#include <o3tl/safeint.hxx>
 #include <osl/diagnose.h>
 #include <memory>
 
@@ -330,7 +331,23 @@ BitmapBuffer* StretchAndConvert(
     pDstBuffer->mnFormat = nDstBitmapFormat;
     pDstBuffer->mnWidth = rTwoRect.mnDestWidth;
     pDstBuffer->mnHeight = rTwoRect.mnDestHeight;
-    pDstBuffer->mnScanlineSize = AlignedWidth4Bytes( pDstBuffer->mnBitCount * pDstBuffer->mnWidth );
+    long nScanlineBase;
+    bool bFail = o3tl::checked_multiply<long>(pDstBuffer->mnBitCount, pDstBuffer->mnWidth, nScanlineBase);
+    if (bFail)
+    {
+        SAL_WARN("vcl.gdi", "checked multiply failed");
+        pDstBuffer->mpBits = nullptr;
+        delete pDstBuffer;
+        return nullptr;
+    }
+    pDstBuffer->mnScanlineSize = AlignedWidth4Bytes(nScanlineBase);
+    if (pDstBuffer->mnScanlineSize < nScanlineBase/8)
+    {
+        SAL_WARN("vcl.gdi", "scanline calculation wraparound");
+        pDstBuffer->mpBits = nullptr;
+        delete pDstBuffer;
+        return nullptr;
+    }
     try
     {
         pDstBuffer->mpBits = new sal_uInt8[ pDstBuffer->mnScanlineSize * pDstBuffer->mnHeight ];
diff --git a/vcl/unx/generic/gdi/salbmp.cxx b/vcl/unx/generic/gdi/salbmp.cxx
index 158a2f52d0fc..905232319123 100644
--- a/vcl/unx/generic/gdi/salbmp.cxx
+++ b/vcl/unx/generic/gdi/salbmp.cxx
@@ -41,6 +41,7 @@
 #include <unx/salinst.h>
 #include <unx/x11/xlimits.hxx>
 
+#include <o3tl/safeint.hxx>
 #include <opengl/salbmp.hxx>
 #include <vcl/opengl/OpenGLHelper.hxx>
 
@@ -193,7 +194,21 @@ BitmapBuffer* X11SalBitmap::ImplCreateDIB(
 
             pDIB->mnWidth = rSize.Width();
             pDIB->mnHeight = rSize.Height();
-            pDIB->mnScanlineSize = AlignedWidth4Bytes( pDIB->mnWidth * nBitCount );
+            long nScanlineBase;
+            bool bFail = o3tl::checked_multiply<long>(pDIB->mnWidth, nBitCount, nScanlineBase);
+            if (bFail)
+            {
+                SAL_WARN("vcl.gdi", "checked multiply failed");
+                delete pDIB;
+                return nullptr;
+            }
+            pDIB->mnScanlineSize = AlignedWidth4Bytes(nScanlineBase);
+            if (pDIB->mnScanlineSize < nScanlineBase/8)
+            {
+                SAL_WARN("vcl.gdi", "scanline calculation wraparound");
+                delete pDIB;
+                return nullptr;
+            }
             pDIB->mnBitCount = nBitCount;
 
             if( nColors )
commit a93cb675c67b80fbb0005757a80bae039ba35c01
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Mon May 15 11:29:11 2017 +0100

    ofz#1542 check remaining size of dest
    
    Change-Id: I37cff45afdb242b31919a8a02e737424e2ecfd52
    Reviewed-on: https://gerrit.libreoffice.org/37634
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    (cherry picked from commit 9304956306025194a671a90d4559746660a27010)

diff --git a/filter/source/graphicfilter/ieps/ieps.cxx b/filter/source/graphicfilter/ieps/ieps.cxx
index 1ec3257eb5aa..fecad6b73d75 100644
--- a/filter/source/graphicfilter/ieps/ieps.cxx
+++ b/filter/source/graphicfilter/ieps/ieps.cxx
@@ -643,7 +643,7 @@ ipsGraphicImport( SvStream & rStream, Graphic & rGraphic, FilterConfigItem* )
                     long nHeight = ImplGetNumber(pDest, nSecurityCount);
                     long nBitDepth = ImplGetNumber(pDest, nSecurityCount);
                     long nScanLines = ImplGetNumber(pDest, nSecurityCount);
-                    pDest = ImplSearchEntry( pDest, reinterpret_cast<sal_uInt8 const *>("%"), 16, 1 );       // go to the first Scanline
+                    pDest = nSecurityCount ? ImplSearchEntry(pDest, reinterpret_cast<sal_uInt8 const *>("%"), 16, 1) : nullptr;       // go to the first Scanline
                     if ( nSecurityCount && pDest && nWidth && nHeight && ( ( nBitDepth == 1 ) || ( nBitDepth == 8 ) ) && nScanLines )
                     {
                         rStream.Seek( nBufStartPos + ( pDest - pBuf.get() ) );
commit 1348233d9deb3d683d65104e3ee6743338ea7b26
Author: Michael Stahl <mstahl at redhat.com>
Date:   Fri May 12 18:34:17 2017 +0200

    sw: table-in-footnote: delete SwFootnoteFrame if it becomes empty
    
    Crashed in a11y code with a SwFootnoteFrame that survived a JoinNode and
    subsequent deletion of its reference-containing SwTextFrame and thus had
    a stale "pRef" member; presumably the SwTableFrame needs to delete an
    empty footnote frame like the SwTextFrame does from SwContentFrame::Cut(),
    called from DelFrames(), called from CutImpl().
    
    Change-Id: I5a30357ecd3bf474bfc4a5451de89beb245fb0ae
    (cherry picked from commit c9fb347642729017ad0c613fe26310befd021db8)
    Reviewed-on: https://gerrit.libreoffice.org/37562
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    (cherry picked from commit 23c333b10c270397dd7ff4bb36c94d6076dec003)

diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx
index b2e56e8bbbc6..d08468aaa1e1 100644
--- a/sw/source/core/layout/tabfrm.cxx
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -3463,6 +3463,22 @@ void SwTabFrame::Cut()
                 pSct->InvalidateSize_();
             }
         }
+        // table-in-footnote: delete empty footnote frames (like SwContentFrame::Cut)
+        else if (!pUp->Lower() && pUp->IsFootnoteFrame() && !pUp->IsColLocked())
+        {
+            if (pUp->GetNext() && !pUp->GetPrev())
+            {
+                if (SwFrame *const pTmp = static_cast<SwLayoutFrame*>(pUp->GetNext())->ContainsAny())
+                {
+                    pTmp->InvalidatePrt_();
+                }
+            }
+            if (!pUp->IsDeleteForbidden())
+            {
+                pUp->Cut();
+                SwFrame::DestroyFrame(pUp);
+            }
+        }
         else if( (Frame().*aRectFnSet->fnGetHeight)() )
         {
             // OD 26.08.2003 #i18103# - *no* 'ColUnlock' of section -
diff --git a/sw/source/core/txtnode/thints.cxx b/sw/source/core/txtnode/thints.cxx
index 0e6f73fd5939..eb2180702b1e 100644
--- a/sw/source/core/txtnode/thints.cxx
+++ b/sw/source/core/txtnode/thints.cxx
@@ -1400,6 +1400,10 @@ bool SwTextNode::InsertHint( SwTextAttr * const pAttr, const SetAttrMode nMode )
                         SwContentNode* pCNd = rNodes[ nSttIdx ]->GetContentNode();
                         if( nullptr != pCNd )
                             pCNd->DelFrames();
+                        else if (SwTableNode *const pTable = rNodes[nSttIdx]->GetTableNode())
+                        {
+                            pTable->DelFrames();
+                        }
                     }
                 }
 
commit 820db3a48d0bfd8872eb33cf380ce45c0d3b4758
Author: Michael Stahl <mstahl at redhat.com>
Date:   Fri May 12 17:08:01 2017 +0200

    tdf#107568 sw: prevent moving/splitting of tables in footnotes
    
    The problem here is that for a table in a footnote on page 42,
    SwTabFrm::MakeAll() calls Split(), which first creates a
    follow-table-frame and then reformats the last row of the table;
    somehow the SwTextFrame id="4636" in that row doesn't fit and wants
    to split and then move to the following page with that page's footnote
    container as its parent.
    
    So this doesn't work currently.
    
    commit 971adcd9e19e0bcab5855aae9be58d2203b46169 tried to prevent just
    the moving forward of the table itself, but the table can still be split;
    if IsMoveable() returns false then that also prevents splitting the table.
    
    Change-Id: I1977c65f97cb0f66dbe5b89d7ef7e2cd05125331
    (cherry picked from commit f6785b99a3f7e7531c8ef7ed16402cc4e02c9750)
    Reviewed-on: https://gerrit.libreoffice.org/37561
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    (cherry picked from commit c4b55ea03da881590e5fac1ffc97177e4ce16b0b)

diff --git a/sw/source/core/layout/findfrm.cxx b/sw/source/core/layout/findfrm.cxx
index 89cf31663e2c..9caa4894e1f9 100644
--- a/sw/source/core/layout/findfrm.cxx
+++ b/sw/source/core/layout/findfrm.cxx
@@ -1330,7 +1330,7 @@ bool SwFrame::IsMoveable( const SwLayoutFrame* _pLayoutFrame ) const
                         }
                     }
                 }
-                else
+                else if (!(_pLayoutFrame->IsInFootnote() && (IsTabFrame() || IsInTab())))
                 {
                     bRetVal = true;
                 }
diff --git a/sw/source/core/layout/flowfrm.cxx b/sw/source/core/layout/flowfrm.cxx
index 7ab8e85c7119..c2ccaddaf66c 100644
--- a/sw/source/core/layout/flowfrm.cxx
+++ b/sw/source/core/layout/flowfrm.cxx
@@ -1805,6 +1805,8 @@ bool SwFlowFrame::MoveFwd( bool bMakePage, bool bPageBreak, bool bMoveAlways )
         return false;
     if (m_rThis.IsInFootnote())
     {
+        assert(!m_rThis.IsTabFrame()); // prevented by IsMoveable()
+        assert(!m_rThis.IsInTab());
         if (!m_rThis.IsContentFrame() || !pOldBoss)
         {
             SAL_WARN("sw.core", "Tables in footnotes are not truly supported");
commit 792c0f0d3931aaf1dfa334f9fd503aaf323c61ba
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Fri May 12 13:59:36 2017 +0100

    Resolves: tdf#107786 crash on null pointer access
    
    Change-Id: I371d509e7ab6e7e0ef757e302d54ab75aa6c4c9b
    (cherry picked from commit 858d1e065530997a695dc303b9224fd136137c8d)
    Reviewed-on: https://gerrit.libreoffice.org/37537
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    (cherry picked from commit b462870a3a5053b1efd507960c2d0d2a13a838c7)

diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index 1b010ef149c2..f13535e64728 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -4344,7 +4344,7 @@ void wwSectionManager::SetSegmentToPageDesc(const wwSection &rSection,
         Rectangle aRect(0, 0, 100, 100); // A dummy, we don't care about the size
         SvxMSDffImportData aData(aRect);
         SdrObject* pObject = nullptr;
-        if (mrReader.m_pMSDffManager->GetShape(0x401, pObject, aData))
+        if (mrReader.m_pMSDffManager->GetShape(0x401, pObject, aData) && !aData.empty())
         {
             // Only handle shape if it is a background shape
             if (((*aData.begin())->nFlags & 0x400) != 0)
commit 355b7372a42d55cb4bfbbd85e61d6ff7cd8f990a
Author: Michael Stahl <mstahl at redhat.com>
Date:   Wed May 10 17:45:14 2017 +0200

    tdf#107512 sw: fix rollback of text attributes in SwUndoDelete
    
    The problem is that in SwUndoDelete::UndoImpl(), first the formatting
    attributes are restored via TmpRollback(), and then all footnote/fly
    attributes are restored via Rollback(). This means that the SwHistory
    doesn't actually store the original positions of the formatting hints;
    ideally there wouldn't be 2 separate steps here, but that appears
    difficult to change now given the plethora of calls to
    DelContentIndex() ...
    
    So work around the problem by adding a new SetAttrMode::NOHINTEXPAND
    to prevent expanding the existing hints when the CH_TXTATR_BREAKWORD
    are inserted from SwUndoDelLayFormat.
    
    This fixes 2 problematic cases: at the start of the paragraph,
    and if the hint ends at the position before the CH_TXTATR_BREAKWORD.
    
    Let's hope this won't break anything anybody cares about.
    
    (cherry picked from commit 771d85baf18e5b503eb6248e1f41928b00265d8d)
    
    sw: CPPUNIT_ASSERT_EQUAL vs. integer FAIL
    (cherry picked from commit 7f44ca113170a641a1aecc8a48e2b99860e1e2f7)
    
    Change-Id: I557c4c9136f4225ca502019730fb9f0a9c03d23b
    Reviewed-on: https://gerrit.libreoffice.org/37485
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    (cherry picked from commit 4820c9b981e060a55b3511272824dca7c2eb67d5)

diff --git a/sw/inc/swtypes.hxx b/sw/inc/swtypes.hxx
index 2c88e9fe99c9..d5114cd033c6 100644
--- a/sw/inc/swtypes.hxx
+++ b/sw/inc/swtypes.hxx
@@ -193,11 +193,13 @@ enum class SetAttrMode
     /// Force hint expand (only matters for hints with CH_TXTATR).
     FORCEHINTEXPAND = 0x0040,
     /// The inserted item is a copy -- intended for use in ndtxt.cxx.
-    IS_COPY         = 0x0080
+    IS_COPY         = 0x0080,
+    /// for Undo, translated to SwInsertFlags::NOHINTEXPAND
+    NOHINTEXPAND    = 0x0100,
 };
 namespace o3tl
 {
-    template<> struct typed_flags<SetAttrMode> : is_typed_flags<SetAttrMode, 0x0ff> {};
+    template<> struct typed_flags<SetAttrMode> : is_typed_flags<SetAttrMode, 0x1ff> {};
 }
 
 #define SW_ISPRINTABLE( c ) ( c >= ' ' && 127 != c )
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index 4dda340ddd71..4594b5ba4936 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -181,6 +181,7 @@ public:
     void testTableBackgroundColor();
     void testTdf88899();
     void testTdf90362();
+    void testUndoDelAsCharTdf107512();
     void testUndoCharAttribute();
     void testTdf86639();
     void testTdf90883TableBoxGetCoordinates();
@@ -302,6 +303,7 @@ public:
     CPPUNIT_TEST(testTableBackgroundColor);
     CPPUNIT_TEST(testTdf88899);
     CPPUNIT_TEST(testTdf90362);
+    CPPUNIT_TEST(testUndoDelAsCharTdf107512);
     CPPUNIT_TEST(testUndoCharAttribute);
     CPPUNIT_TEST(testTdf86639);
     CPPUNIT_TEST(testTdf90883TableBoxGetCoordinates);
@@ -3139,6 +3141,138 @@ void SwUiWriterTest::testTdf90362()
     comphelper::ConfigurationHelper::writeDirectKey(xComponentContext, "org.openoffice.Office.Writer/", "Cursor/Option", "IgnoreProtectedArea", css::uno::Any(false), comphelper::EConfigurationModes::Standard);
 }
 
+void SwUiWriterTest::testUndoDelAsCharTdf107512()
+{
+    SwDoc * pDoc(createDoc());
+    sw::UndoManager & rUndoManager(pDoc->GetUndoManager());
+    IDocumentContentOperations & rIDCO(pDoc->getIDocumentContentOperations());
+    SwCursorShell * pShell(pDoc->GetEditShell());
+    SfxItemSet frameSet(pDoc->GetAttrPool(), RES_FRMATR_BEGIN, RES_FRMATR_END-1);
+    SfxItemSet grfSet(pDoc->GetAttrPool(), RES_GRFATR_BEGIN, RES_GRFATR_END-1);
+    rIDCO.InsertString(*pShell->GetCursor(), "foo");
+    pShell->ClearMark();
+    SwFormatAnchor anchor(RndStdIds::FLY_AS_CHAR);
+    frameSet.Put(anchor);
+    GraphicObject grf;
+    pShell->SttEndDoc(true);
+    CPPUNIT_ASSERT(rIDCO.Insert(*pShell->GetCursor(), grf, &frameSet, &grfSet, nullptr));
+    pShell->SttEndDoc(false);
+    CPPUNIT_ASSERT(rIDCO.Insert(*pShell->GetCursor(), grf, &frameSet, &grfSet, nullptr));
+    CPPUNIT_ASSERT_EQUAL(size_t(2), pDoc->GetFlyCount(FLYCNTTYPE_GRF));
+    SvxCharHiddenItem hidden(true, RES_CHRATR_HIDDEN);
+    pShell->SelectText(1, 4);
+    rIDCO.InsertPoolItem(*pShell->GetCursor(), hidden);
+    // now we have "\1foo\1" with the "foo" hidden
+    CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(0, RES_TXTATR_FLYCNT));
+    CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(4, RES_TXTATR_FLYCNT));
+    CPPUNIT_ASSERT_EQUAL(OUString(OUStringLiteral1(CH_TXTATR_BREAKWORD) + "foo" + OUStringLiteral1(CH_TXTATR_BREAKWORD)), pShell->GetCursor()->GetNode().GetTextNode()->GetText());
+    SfxPoolItem const* pItem;
+    SfxItemSet query(pDoc->GetAttrPool(), RES_CHRATR_HIDDEN, RES_CHRATR_HIDDEN);
+    pShell->GetCursor()->GetNode().GetTextNode()->GetAttr(query, 1, 4);
+//    CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+    CPPUNIT_ASSERT(SfxItemState::SET == query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+    CPPUNIT_ASSERT(static_cast<SvxCharHiddenItem const*>(pItem)->GetValue());
+    query.ClearItem(RES_CHRATR_HIDDEN);
+
+    // delete from the start
+    pShell->SelectText(0, 4);
+    rIDCO.DeleteAndJoin(*pShell->GetCursor());
+    CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(0, RES_TXTATR_FLYCNT));
+    CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_GRF));
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pShell->GetCursor()->GetNode().GetTextNode()->Len());
+    pShell->GetCursor()->GetNode().GetTextNode()->GetAttr(query, 0, 1);
+//    CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+    CPPUNIT_ASSERT(SfxItemState::DEFAULT == query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+    query.ClearItem(RES_CHRATR_HIDDEN);
+    rUndoManager.Undo();
+    CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(0, RES_TXTATR_FLYCNT));
+    CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(4, RES_TXTATR_FLYCNT));
+    CPPUNIT_ASSERT_EQUAL(size_t(2), pDoc->GetFlyCount(FLYCNTTYPE_GRF));
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pShell->GetCursor()->GetNode().GetTextNode()->Len());
+    CPPUNIT_ASSERT_EQUAL(OUString(OUStringLiteral1(CH_TXTATR_BREAKWORD) + "foo" + OUStringLiteral1(CH_TXTATR_BREAKWORD)), pShell->GetCursor()->GetNode().GetTextNode()->GetText());
+    pShell->GetCursor()->GetNode().GetTextNode()->GetAttr(query, 0, 1);
+//    CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+    CPPUNIT_ASSERT(SfxItemState::DEFAULT == query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+    query.ClearItem(RES_CHRATR_HIDDEN);
+    pShell->GetCursor()->GetNode().GetTextNode()->GetAttr(query, 1, 4);
+//    CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+    CPPUNIT_ASSERT(SfxItemState::SET == query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+    CPPUNIT_ASSERT(static_cast<SvxCharHiddenItem const*>(pItem)->GetValue());
+    query.ClearItem(RES_CHRATR_HIDDEN);
+    rUndoManager.Redo();
+    CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(0, RES_TXTATR_FLYCNT));
+    CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_GRF));
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pShell->GetCursor()->GetNode().GetTextNode()->Len());
+    pShell->GetCursor()->GetNode().GetTextNode()->GetAttr(query, 0, 1);
+//    CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+    CPPUNIT_ASSERT(SfxItemState::DEFAULT == query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+    query.ClearItem(RES_CHRATR_HIDDEN);
+    rUndoManager.Undo();
+    CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(0, RES_TXTATR_FLYCNT));
+    CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(4, RES_TXTATR_FLYCNT));
+    CPPUNIT_ASSERT_EQUAL(size_t(2), pDoc->GetFlyCount(FLYCNTTYPE_GRF));
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pShell->GetCursor()->GetNode().GetTextNode()->Len());
+    CPPUNIT_ASSERT_EQUAL(OUString(OUStringLiteral1(CH_TXTATR_BREAKWORD) + "foo" + OUStringLiteral1(CH_TXTATR_BREAKWORD)), pShell->GetCursor()->GetNode().GetTextNode()->GetText());
+    pShell->GetCursor()->GetNode().GetTextNode()->GetAttr(query, 0, 1);
+//    CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+    CPPUNIT_ASSERT(SfxItemState::DEFAULT == query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+    query.ClearItem(RES_CHRATR_HIDDEN);
+    pShell->GetCursor()->GetNode().GetTextNode()->GetAttr(query, 1, 4);
+//    CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+    CPPUNIT_ASSERT(SfxItemState::SET == query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+    CPPUNIT_ASSERT(static_cast<SvxCharHiddenItem const*>(pItem)->GetValue());
+    query.ClearItem(RES_CHRATR_HIDDEN);
+
+    // delete from the end
+    pShell->SelectText(1, 5);
+    rIDCO.DeleteAndJoin(*pShell->GetCursor());
+    CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(0, RES_TXTATR_FLYCNT));
+    CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_GRF));
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pShell->GetCursor()->GetNode().GetTextNode()->Len());
+    pShell->GetCursor()->GetNode().GetTextNode()->GetAttr(query, 4, 5);
+//    CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+    CPPUNIT_ASSERT(SfxItemState::DEFAULT == query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+    query.ClearItem(RES_CHRATR_HIDDEN);
+    rUndoManager.Undo();
+    CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(0, RES_TXTATR_FLYCNT));
+    CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(4, RES_TXTATR_FLYCNT));
+    CPPUNIT_ASSERT_EQUAL(size_t(2), pDoc->GetFlyCount(FLYCNTTYPE_GRF));
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pShell->GetCursor()->GetNode().GetTextNode()->Len());
+    CPPUNIT_ASSERT_EQUAL(OUString(OUStringLiteral1(CH_TXTATR_BREAKWORD) + "foo" + OUStringLiteral1(CH_TXTATR_BREAKWORD)), pShell->GetCursor()->GetNode().GetTextNode()->GetText());
+    pShell->GetCursor()->GetNode().GetTextNode()->GetAttr(query, 4, 5);
+//    CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+    CPPUNIT_ASSERT(SfxItemState::DEFAULT == query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+    query.ClearItem(RES_CHRATR_HIDDEN);
+    pShell->GetCursor()->GetNode().GetTextNode()->GetAttr(query, 1, 4);
+//    CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+    CPPUNIT_ASSERT(SfxItemState::SET == query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+    CPPUNIT_ASSERT(static_cast<SvxCharHiddenItem const*>(pItem)->GetValue());
+    query.ClearItem(RES_CHRATR_HIDDEN);
+    rUndoManager.Redo();
+    CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(0, RES_TXTATR_FLYCNT));
+    CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_GRF));
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pShell->GetCursor()->GetNode().GetTextNode()->Len());
+    pShell->GetCursor()->GetNode().GetTextNode()->GetAttr(query, 4, 5);
+//    CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+    CPPUNIT_ASSERT(SfxItemState::DEFAULT == query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+    query.ClearItem(RES_CHRATR_HIDDEN);
+    rUndoManager.Undo();
+    CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(0, RES_TXTATR_FLYCNT));
+    CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(4, RES_TXTATR_FLYCNT));
+    CPPUNIT_ASSERT_EQUAL(size_t(2), pDoc->GetFlyCount(FLYCNTTYPE_GRF));
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pShell->GetCursor()->GetNode().GetTextNode()->Len());
+    CPPUNIT_ASSERT_EQUAL(OUString(OUStringLiteral1(CH_TXTATR_BREAKWORD) + "foo" + OUStringLiteral1(CH_TXTATR_BREAKWORD)), pShell->GetCursor()->GetNode().GetTextNode()->GetText());
+    pShell->GetCursor()->GetNode().GetTextNode()->GetAttr(query, 4, 5);
+//    CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+    CPPUNIT_ASSERT(SfxItemState::DEFAULT == query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+    query.ClearItem(RES_CHRATR_HIDDEN);
+    pShell->GetCursor()->GetNode().GetTextNode()->GetAttr(query, 1, 4);
+//    CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+    CPPUNIT_ASSERT(SfxItemState::SET == query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+    CPPUNIT_ASSERT(static_cast<SvxCharHiddenItem const*>(pItem)->GetValue());
+    query.ClearItem(RES_CHRATR_HIDDEN);
+}
+
 void SwUiWriterTest::testUndoCharAttribute()
 {
     // Create a new empty Writer document
diff --git a/sw/source/core/txtnode/thints.cxx b/sw/source/core/txtnode/thints.cxx
index b091b6fe920c..0e6f73fd5939 100644
--- a/sw/source/core/txtnode/thints.cxx
+++ b/sw/source/core/txtnode/thints.cxx
@@ -1251,9 +1251,11 @@ bool SwTextNode::InsertHint( SwTextAttr * const pAttr, const SetAttrMode nMode )
 
     // translate from SetAttrMode to InsertMode (for hints with CH_TXTATR)
     const SwInsertFlags nInsertFlags =
-        (nMode & SetAttrMode::FORCEHINTEXPAND)
-        ? (SwInsertFlags::FORCEHINTEXPAND | SwInsertFlags::EMPTYEXPAND)
-        : SwInsertFlags::EMPTYEXPAND;
+        (nMode & SetAttrMode::NOHINTEXPAND)
+        ? SwInsertFlags::NOHINTEXPAND
+        : (nMode & SetAttrMode::FORCEHINTEXPAND)
+            ? (SwInsertFlags::FORCEHINTEXPAND | SwInsertFlags::EMPTYEXPAND)
+            : SwInsertFlags::EMPTYEXPAND;
 
     // need this after TryInsertHint, when pAttr may be deleted
     const sal_Int32 nStart( pAttr->GetStart() );
diff --git a/sw/source/core/undo/undobj1.cxx b/sw/source/core/undo/undobj1.cxx
index 2fcc24efc98e..ed97d013c904 100644
--- a/sw/source/core/undo/undobj1.cxx
+++ b/sw/source/core/undo/undobj1.cxx
@@ -114,7 +114,7 @@ void SwUndoFlyBase::InsFly(::sw::UndoRedoContext & rContext, bool bShowSelFrame)
         SwContentNode* pCNd = aAnchor.GetContentAnchor()->nNode.GetNode().GetContentNode();
         OSL_ENSURE( pCNd->IsTextNode(), "no Text Node at position." );
         SwFormatFlyCnt aFormat( pFrameFormat );
-        pCNd->GetTextNode()->InsertItem( aFormat, nCntPos, nCntPos );
+        pCNd->GetTextNode()->InsertItem(aFormat, nCntPos, nCntPos, SetAttrMode::NOHINTEXPAND);
     }
 
     pFrameFormat->MakeFrames();
commit ca243c9f2bf47126391417753c04733bf75bc9be
Author: Michael Stahl <mstahl at redhat.com>
Date:   Wed May 10 21:19:58 2017 +0200

    tdf#107709 filter: MSO2003XML import: fix invalid OLE lengths
    
    The oleLength was -28160 for the bugdoc, so i guess the shifting of
    signed chars there is perhaps not ideal, better upcast and
    shift as unsigned.
    
    Change-Id: I068013a10e18043c1534c7c61be8ff8a5556d460
    (cherry picked from commit 088b898856a82d7ac4851a6e7dfe4d189d881f8e)
    Reviewed-on: https://gerrit.libreoffice.org/37486
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    (cherry picked from commit 5d474fc14581eaceb1defa7eabf5bcd335143b2d)

diff --git a/filter/source/xsltfilter/OleHandler.cxx b/filter/source/xsltfilter/OleHandler.cxx
index 6564d2ea88a9..2f2bd04f9eef 100644
--- a/filter/source/xsltfilter/OleHandler.cxx
+++ b/filter/source/xsltfilter/OleHandler.cxx
@@ -117,8 +117,14 @@ namespace XSLT
             {
                 return "Can not read the length.";
             }
-        int oleLength = (aLength[0] << 0) + (aLength[1] << 8)
-                + (aLength[2] << 16) + (aLength[3] << 24);
+        sal_Int32 const oleLength = (static_cast<sal_uInt8>(aLength[0]) <<  0U)
+                                  | (static_cast<sal_uInt8>(aLength[1]) <<  8U)
+                                  | (static_cast<sal_uInt8>(aLength[2]) << 16U)
+                                  | (static_cast<sal_uInt8>(aLength[3]) << 24U);
+        if (oleLength < 0)
+        {
+            return "invalid oleLength";
+        }
         Sequence<sal_Int8> content(oleLength);
         //Read all bytes. The compressed length should less then the uncompressed length
         readbytes = subStream->readBytes(content, oleLength);
commit 0dd7d7dd6868d0da8649a1db89fbda24866f4400
Author: Thomas Beck <thomas.beck at cib.de>
Date:   Wed May 3 12:57:11 2017 +0200

    tdf#107587 Opening Hyperlink opens Browser in Background.
    
    Added neccessary WinAPI calls to bring called window into the
    Foreground.
    
    Change-Id: I080968f655e2230d1a514b3ef91bf916d904d844
    Reviewed-on: https://gerrit.libreoffice.org/37196
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    (cherry picked from commit ad711bc6e2cc35c2ed114fff15008d5bbcfcf21c)
    Reviewed-on: https://gerrit.libreoffice.org/37266
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    (cherry picked from commit 45b2e11a6756ed322cda932142c31366fc2b6da6)

diff --git a/shell/source/win32/SysShExec.cxx b/shell/source/win32/SysShExec.cxx
index c69d3f2a0c59..6cb31942ba02 100644
--- a/shell/source/win32/SysShExec.cxx
+++ b/shell/source/win32/SysShExec.cxx
@@ -323,6 +323,28 @@ void SAL_CALL CSysShExec::execute( const OUString& aCommand, const OUString& aPa
             static_cast< XSystemShellExecute* >(this),
             psxErr);
     }
+    else
+    {
+        // Get Permission make changes to the Window of the created Process
+        HWND procHandle = 0;
+        DWORD procId = GetProcessId(sei.hProcess);
+        AllowSetForegroundWindow(procId);
+
+        // Get the handle of the created Window
+        DWORD check = 0;
+        GetWindowThreadProcessId(procHandle, &check);
+        SAL_WARN_IF(check != procId, "shell", "Could not get handle of process called by shell.");
+
+        // Move created Window into the foreground
+        if(procHandle != 0)
+        {
+            SetForegroundWindow(procHandle);
+            SetActiveWindow(procHandle);
+        }
+    }
+
+    // Close the handle for the created childprocess when we are done
+    CloseHandle(sei.hProcess);
 }
 
 // XServiceInfo


More information about the Libreoffice-commits mailing list