[Libreoffice-commits] core.git: sw/source

Caolán McNamara caolanm at redhat.com
Tue Apr 11 12:41:10 UTC 2017


 sw/source/filter/ww8/ww8par.cxx  |   34 ++--
 sw/source/filter/ww8/ww8par.hxx  |    2 
 sw/source/filter/ww8/ww8par2.cxx |   69 +++++----
 sw/source/filter/ww8/ww8par2.hxx |    2 
 sw/source/filter/ww8/ww8par3.cxx |   49 +++---
 sw/source/filter/ww8/ww8par4.cxx |   10 -
 sw/source/filter/ww8/ww8par5.cxx |    4 
 sw/source/filter/ww8/ww8par6.cxx |  277 ++++++++++++++++++++++-----------------
 sw/source/filter/ww8/ww8scan.cxx |  123 ++++++++++-------
 sw/source/filter/ww8/ww8scan.hxx |   43 ++++--
 10 files changed, 357 insertions(+), 256 deletions(-)

New commits:
commit b897cc4dfc7111eb8dfd5d8aa8c970f21ab035d6
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Mon Apr 10 21:10:57 2017 +0100

    consistently track amount of buffers remaining
    
    Change-Id: Ib9746a045edf2146b8cc3bd69124ab74462df094
    Reviewed-on: https://gerrit.libreoffice.org/36405
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index 831082c032a3..93bcea47f060 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -2534,7 +2534,7 @@ bool SwWW8ImplReader::ProcessSpecial(bool &rbReSync, WW8_CP nStartCp)
     OSL_ENSURE(m_nInTable >= 0,"nInTable < 0!");
 
     // TabRowEnd
-    bool bTableRowEnd = (m_pPlcxMan->HasParaSprm(m_bVer67 ? 25 : 0x2417) != nullptr );
+    bool bTableRowEnd = (m_pPlcxMan->HasParaSprm(m_bVer67 ? 25 : 0x2417).pSprm != nullptr);
 
 // Unfortunately, for every paragraph we need to check first whether
 // they contain a sprm 29 (0x261B), which starts an APO.
@@ -2565,12 +2565,12 @@ bool SwWW8ImplReader::ProcessSpecial(bool &rbReSync, WW8_CP nStartCp)
     sal_uInt8 nCellLevel = 0;
 
     if (m_bVer67)
-        nCellLevel = int(nullptr != m_pPlcxMan->HasParaSprm(24));
+        nCellLevel = int(nullptr != m_pPlcxMan->HasParaSprm(24).pSprm);
     else
     {
-        nCellLevel = int(nullptr != m_pPlcxMan->HasParaSprm(0x2416));
+        nCellLevel = int(nullptr != m_pPlcxMan->HasParaSprm(0x2416).pSprm);
         if (!nCellLevel)
-            nCellLevel = int(nullptr != m_pPlcxMan->HasParaSprm(0x244B));
+            nCellLevel = int(nullptr != m_pPlcxMan->HasParaSprm(0x244B).pSprm);
     }
     do
     {
@@ -2584,8 +2584,9 @@ bool SwWW8ImplReader::ProcessSpecial(bool &rbReSync, WW8_CP nStartCp)
             WW8PLCFx_Cp_FKP* pPap = m_pPlcxMan->GetPapPLCF();
             WW8_CP nMyStartCp=nStartCp;
 
-            if (const sal_uInt8 *pLevel = m_pPlcxMan->HasParaSprm(0x6649))
-                nCellLevel = *pLevel;
+            SprmResult aLevel = m_pPlcxMan->HasParaSprm(0x6649);
+            if (aLevel.pSprm && aLevel.nRemainingData >= 1)
+                nCellLevel = *aLevel.pSprm;
 
             bool bHasRowEnd = SearchRowEnd(pPap, nMyStartCp, (m_nInTable<nCellLevel?m_nInTable:nCellLevel-1));
 
@@ -2617,8 +2618,9 @@ bool SwWW8ImplReader::ProcessSpecial(bool &rbReSync, WW8_CP nStartCp)
         //  Test for Anl (Numbering) and process all events in the right order
         if( m_bAnl && !bTableRowEnd )
         {
-            const sal_uInt8* pSprm13 = m_pPlcxMan->HasParaSprm( 13 );
-            if( pSprm13 )
+            SprmResult aSprm13 = m_pPlcxMan->HasParaSprm(13);
+            const sal_uInt8* pSprm13 = aSprm13.pSprm;
+            if (pSprm13 && aSprm13.nRemainingData >= 1)
             {   // Still Anl left?
                 sal_uInt8 nT = static_cast< sal_uInt8 >(GetNumType( *pSprm13 ));
                 if( ( nT != WW8_Pause && nT != m_nWwNumType ) // Anl change
@@ -4018,20 +4020,20 @@ bool SwWW8ImplReader::ReadText(WW8_CP nStartCp, WW8_CP nTextLen, ManTypes nType)
             // If we have found a dropcap store the textnode
             pPreviousNode = m_pPaM->GetNode().GetTextNode();
 
-            const sal_uInt8 *pDCS;
-
+            SprmResult aDCS;
             if (m_bVer67)
-                pDCS = m_pPlcxMan->GetPapPLCF()->HasSprm(46);
+                aDCS = m_pPlcxMan->GetPapPLCF()->HasSprm(46);
             else
-                pDCS = m_pPlcxMan->GetPapPLCF()->HasSprm(0x442C);
+                aDCS = m_pPlcxMan->GetPapPLCF()->HasSprm(0x442C);
 
-            if (pDCS)
-                nDropLines = (*pDCS) >> 3;
+            if (aDCS.pSprm && aDCS.nRemainingData >= 1)
+                nDropLines = (*aDCS.pSprm) >> 3;
             else    // There is no Drop Cap Specifier hence no dropcap
                 pPreviousNode = nullptr;
 
-            if (const sal_uInt8 *pDistance = m_pPlcxMan->GetPapPLCF()->HasSprm(0x842F))
-                nDistance = SVBT16ToShort( pDistance );
+            SprmResult aDistance = m_pPlcxMan->GetPapPLCF()->HasSprm(0x842F);
+            if (aDistance.pSprm && aDistance.nRemainingData >= 2)
+                nDistance = SVBT16ToShort(aDistance.pSprm);
             else
                 nDistance = 0;
 
diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx
index 95481dc9622b..9c3d471f645b 100644
--- a/sw/source/filter/ww8/ww8par.hxx
+++ b/sw/source/filter/ww8/ww8par.hxx
@@ -164,7 +164,7 @@ private:
     std::vector<WW8LSTInfo* > maLSTInfos;
     std::vector<std::unique_ptr<WW8LFOInfo>> m_LFOInfos;// D. from PLF LFO, sorted exactly like in the WW8 Stream
     sal_uInt16       nUniqueList; // current number for creating unique list names
-    sal_uInt8* GrpprlHasSprm(sal_uInt16 nId, sal_uInt8& rSprms, sal_uInt8 nLen);
+    SprmResult GrpprlHasSprm(sal_uInt16 nId, sal_uInt8& rSprms, sal_uInt8 nLen);
     WW8LSTInfo* GetLSTByListId(    sal_uInt32  nIdLst     ) const;
     //the rParaSprms returns back the original word paragraph indent
     //sprms which are attached to this numbering level
diff --git a/sw/source/filter/ww8/ww8par2.cxx b/sw/source/filter/ww8/ww8par2.cxx
index f9252ad0423b..6e488a1328bc 100644
--- a/sw/source/filter/ww8/ww8par2.cxx
+++ b/sw/source/filter/ww8/ww8par2.cxx
@@ -466,11 +466,13 @@ bool SwWW8ImplReader::SearchRowEnd(WW8PLCFx_Cp_FKP* pPap, WW8_CP &rStartCp,
     {
         if (pPap->Where() != WW8_CP_MAX)
         {
-            const sal_uInt8* pB = pPap->HasSprm(TabRowSprm(nLevel));
-            if (pB && *pB == 1)
+            SprmResult aSprmRes = pPap->HasSprm(TabRowSprm(nLevel));
+            const sal_uInt8* pB = aSprmRes.pSprm;
+            if (pB && aSprmRes.nRemainingData >= 1 && *pB == 1)
             {
-                const sal_uInt8 *pLevel = nullptr;
-                if (nullptr != (pLevel = pPap->HasSprm(0x6649)))
+                aSprmRes = pPap->HasSprm(0x6649);
+                const sal_uInt8 *pLevel = aSprmRes.pSprm;
+                if (pLevel && aSprmRes.nRemainingData >= 1)
                 {
                     if (nLevel + 1 == *pLevel)
                         return true;
@@ -537,10 +539,11 @@ ApoTestResults SwWW8ImplReader::TestApo(int nCellLevel, bool bTableRowEnd,
     to see if we are still in that frame.
     */
 
-    aRet.m_bHasSprm37 = m_pPlcxMan->HasParaSprm( m_bVer67 ? 37 : 0x2423 );
-    const sal_uInt8 *pSrpm29 = m_pPlcxMan->HasParaSprm( m_bVer67 ? 29 : 0x261B );
+    aRet.m_bHasSprm37 = m_pPlcxMan->HasParaSprm(m_bVer67 ? 37 : 0x2423).pSprm != nullptr;
+    SprmResult aSrpm29 = m_pPlcxMan->HasParaSprm(m_bVer67 ? 29 : 0x261B);
+    const sal_uInt8 *pSrpm29 = aSrpm29.pSprm;
     aRet.m_bHasSprm29 = pSrpm29 != nullptr;
-    aRet.m_nSprm29 = pSrpm29 ? *pSrpm29 : 0;
+    aRet.m_nSprm29 = (pSrpm29 && aSrpm29.nRemainingData >= 1) ? *pSrpm29 : 0;
 
     // Is there some frame data here
     bool bNowApo = aRet.HasFrame() || pTopLevelTable;
@@ -1005,7 +1008,7 @@ void SwWW8ImplReader::StartAnl(const sal_uInt8* pSprm13)
     SwNumRule *pNumRule = m_aANLDRules.GetNumRule(m_nWwNumType);
 
     // check for COL numbering:
-    const sal_uInt8* pS12 = nullptr;// sprmAnld
+    SprmResult aS12; // sprmAnld
     OUString sNumRule;
 
     if (m_pTableDesc)
@@ -1019,8 +1022,8 @@ void SwWW8ImplReader::StartAnl(const sal_uInt8* pSprm13)
             else
             {
                 // this is ROW numbering ?
-                pS12 = m_pPlcxMan->HasParaSprm(m_bVer67 ? 12 : NS_sprm::LN_PAnld); // sprmAnld
-                if (pS12 && 0 != reinterpret_cast<WW8_ANLD const *>(pS12)->fNumberAcross)
+                aS12 = m_pPlcxMan->HasParaSprm(m_bVer67 ? 12 : NS_sprm::LN_PAnld); // sprmAnld
+                if (aS12.pSprm && aS12.nRemainingData >= sal_Int32(sizeof(WW8_ANLD)) && 0 != reinterpret_cast<WW8_ANLD const *>(aS12.pSprm)->fNumberAcross)
                     sNumRule.clear();
             }
         }
@@ -1046,9 +1049,9 @@ void SwWW8ImplReader::StartAnl(const sal_uInt8* pSprm13)
         }
         if (m_pTableDesc)
         {
-            if (!pS12)
-                pS12 = m_pPlcxMan->HasParaSprm(m_bVer67 ? 12 : NS_sprm::LN_PAnld); // sprmAnld
-            if (!pS12 || !reinterpret_cast<WW8_ANLD const *>(pS12)->fNumberAcross)
+            if (!aS12.pSprm)
+                aS12 = m_pPlcxMan->HasParaSprm(m_bVer67 ? 12 : NS_sprm::LN_PAnld); // sprmAnld
+            if (!aS12.pSprm || aS12.nRemainingData < sal_Int32(sizeof(WW8_ANLD)) || !reinterpret_cast<WW8_ANLD const *>(aS12.pSprm)->fNumberAcross)
                 m_pTableDesc->SetNumRuleName(pNumRule->GetName());
         }
     }
@@ -1083,8 +1086,9 @@ void SwWW8ImplReader::NextAnlLine(const sal_uInt8* pSprm13)
         {
             // not defined yet
             // sprmAnld o. 0
-            const sal_uInt8* pS12 = m_pPlcxMan->HasParaSprm(m_bVer67 ? 12 : NS_sprm::LN_PAnld);
-            SetAnld(pNumRule, reinterpret_cast<WW8_ANLD const *>(pS12), m_nSwNumLevel, false);
+            SprmResult aS12 = m_pPlcxMan->HasParaSprm(m_bVer67 ? 12 : NS_sprm::LN_PAnld);
+            if (aS12.nRemainingData >= sal_Int32(sizeof(WW8_ANLD)))
+                SetAnld(pNumRule, reinterpret_cast<WW8_ANLD const *>(aS12.pSprm), m_nSwNumLevel, false);
         }
     }
     else if( *pSprm13 > 0 && *pSprm13 <= MAXLEVEL )          // range WW:1..9 -> SW:0..8
@@ -1107,8 +1111,9 @@ void SwWW8ImplReader::NextAnlLine(const sal_uInt8* pSprm13)
             else                                // no Olst -> use Anld
             {
                 // sprmAnld
-                const sal_uInt8* pS12 = m_pPlcxMan->HasParaSprm(m_bVer67 ? 12 : NS_sprm::LN_PAnld);
-                SetAnld(pNumRule, reinterpret_cast<WW8_ANLD const *>(pS12), m_nSwNumLevel, false);
+                SprmResult aS12 = m_pPlcxMan->HasParaSprm(m_bVer67 ? 12 : NS_sprm::LN_PAnld);
+                if (aS12.nRemainingData >= sal_Int32(sizeof(WW8_ANLD)))
+                    SetAnld(pNumRule, reinterpret_cast<WW8_ANLD const *>(aS12.pSprm), m_nSwNumLevel, false);
             }
         }
     }
@@ -1656,17 +1661,17 @@ void WW8TabBandDesc::setcelldefaults(WW8_TCell *pCells, short nCols)
     memset( pCells, 0, nCols * sizeof( WW8_TCell ) );
 }
 
-const sal_uInt8 *HasTabCellSprm(WW8PLCFx_Cp_FKP* pPap, bool bVer67)
+namespace
 {
-    const sal_uInt8 *pParams;
-    if (bVer67)
-        pParams = pPap->HasSprm(24);
-    else
+    SprmResult HasTabCellSprm(WW8PLCFx_Cp_FKP* pPap, bool bVer67)
     {
-        if (nullptr == (pParams = pPap->HasSprm(0x244B)))
-            pParams = pPap->HasSprm(0x2416);
+        if (bVer67)
+            return pPap->HasSprm(24);
+        SprmResult aRes = pPap->HasSprm(0x244B);
+        if (aRes.pSprm == nullptr)
+            aRes = pPap->HasSprm(0x2416);
+        return aRes;
     }
-    return pParams;
 }
 
 enum wwTableSprm
@@ -2054,11 +2059,13 @@ WW8TabDesc::WW8TabDesc(SwWW8ImplReader* pIoClass, WW8_CP nStartCp) :
         }
 
         //Are we still in a table cell
-        const sal_uInt8* pParams = HasTabCellSprm(pPap, bOldVer);
-        const sal_uInt8 *pLevel = pPap->HasSprm(0x6649);
+        SprmResult aParamsRes = HasTabCellSprm(pPap, bOldVer);
+        const sal_uInt8* pParams = aParamsRes.pSprm;
+        SprmResult aLevelRes = pPap->HasSprm(0x6649);
+        const sal_uInt8 *pLevel = aLevelRes.pSprm;
         // InTable
-        if (!pParams || (1 != *pParams) ||
-            (pLevel && (*pLevel <= m_pIo->m_nInTable)))
+        if (!pParams || aParamsRes.nRemainingData < 1 || (1 != *pParams) ||
+            (pLevel && aLevelRes.nRemainingData >= 1 && (*pLevel <= m_pIo->m_nInTable)))
         {
             break;
         }
@@ -3663,10 +3670,10 @@ const SwFormat* SwWW8ImplReader::GetStyleWithOrgWWName( OUString& rName ) const
 
 //          class WW8RStyle
 
-const sal_uInt8* WW8RStyle::HasParaSprm( sal_uInt16 nId ) const
+SprmResult WW8RStyle::HasParaSprm(sal_uInt16 nId) const
 {
     if( !pParaSprms || !nSprmsLen )
-        return nullptr;
+        return SprmResult();
 
     return maSprmParser.findSprmData(nId, pParaSprms, nSprmsLen);
 }
diff --git a/sw/source/filter/ww8/ww8par2.hxx b/sw/source/filter/ww8/ww8par2.hxx
index 3e9b6db04103..f2c98070d24e 100644
--- a/sw/source/filter/ww8/ww8par2.hxx
+++ b/sw/source/filter/ww8/ww8par2.hxx
@@ -130,7 +130,7 @@ public:
     WW8RStyle( WW8Fib& rFib, SwWW8ImplReader* pI );
     void Import();
     void PostProcessStyles();
-    const sal_uInt8* HasParaSprm( sal_uInt16 nId ) const;
+    SprmResult HasParaSprm(sal_uInt16 nId) const;
 };
 
 class WW8FlySet: public SfxItemSet
diff --git a/sw/source/filter/ww8/ww8par3.cxx b/sw/source/filter/ww8/ww8par3.cxx
index b033133b5953..bb1287fe45d0 100644
--- a/sw/source/filter/ww8/ww8par3.cxx
+++ b/sw/source/filter/ww8/ww8par3.cxx
@@ -439,7 +439,7 @@ WW8LFOInfo::WW8LFOInfo(const WW8LFO& rLFO)
 // Helper methods
 
 // find Sprm-Parameter-Data, if Sprm is included in Grpprl
-sal_uInt8* WW8ListManager::GrpprlHasSprm(sal_uInt16 nId, sal_uInt8& rSprms,
+SprmResult WW8ListManager::GrpprlHasSprm(sal_uInt16 nId, sal_uInt8& rSprms,
     sal_uInt8 nLen)
 {
     return maSprmParser.findSprmData(nId, &rSprms, nLen);
@@ -563,34 +563,39 @@ bool WW8ListManager::ReadLVL(SwNumFormat& rNumFormat, SfxItemSet*& rpItemSet,
         if (aLVL.nLenGrpprlPapx != rSt.ReadBytes(&aGrpprlPapx, aLVL.nLenGrpprlPapx))
             return false;
         // "sprmPDxaLeft"  pap.dxaLeft;dxa;word;
-        sal_uInt8* pSprm;
-        if (
-            (nullptr != (pSprm = GrpprlHasSprm(0x840F,aGrpprlPapx[0],aLVL.nLenGrpprlPapx))) ||
-            (nullptr != (pSprm = GrpprlHasSprm(0x845E,aGrpprlPapx[0],aLVL.nLenGrpprlPapx)))
-            )
+        SprmResult aSprm;
+
+        aSprm = GrpprlHasSprm(0x840F,aGrpprlPapx[0],aLVL.nLenGrpprlPapx);
+        if (!aSprm.pSprm)
+            aSprm = GrpprlHasSprm(0x845E,aGrpprlPapx[0],aLVL.nLenGrpprlPapx);
+
+        if (aSprm.pSprm && aSprm.nRemainingData >= 2)
         {
-            sal_uInt8 *pBegin = pSprm-2;
+            const sal_uInt8 *pBegin = aSprm.pSprm - 2;
             for(int i=0;i<4;++i)
                 rParaSprms.push_back(*pBegin++);
-            short nDxaLeft = SVBT16ToShort( pSprm );
+            short nDxaLeft = SVBT16ToShort(aSprm.pSprm);
             aLVL.nDxaLeft = (0 < nDxaLeft) ? (sal_uInt16)nDxaLeft
                             : (sal_uInt16)(-nDxaLeft);
         }
 
         // "sprmPDxaLeft1" pap.dxaLeft1;dxa;word;
-        if (
-            (nullptr != (pSprm = GrpprlHasSprm(0x8411,aGrpprlPapx[0],aLVL.nLenGrpprlPapx)) ) ||
-            (nullptr != (pSprm = GrpprlHasSprm(0x8460,aGrpprlPapx[0],aLVL.nLenGrpprlPapx)) )
-            )
+        aSprm = GrpprlHasSprm(0x8411,aGrpprlPapx[0],aLVL.nLenGrpprlPapx);
+        if (!aSprm.pSprm)
+            aSprm = GrpprlHasSprm(0x8460,aGrpprlPapx[0],aLVL.nLenGrpprlPapx);
+
+        if (aSprm.pSprm && aSprm.nRemainingData >= 2)
         {
-            sal_uInt8 *pBegin = pSprm-2;
+            const sal_uInt8 *pBegin = aSprm.pSprm - 2;
             for(int i=0;i<4;++i)
                 rParaSprms.push_back(*pBegin++);
-            aLVL.nDxaLeft1 = SVBT16ToShort(  pSprm );
+            aLVL.nDxaLeft1 = SVBT16ToShort(aSprm.pSprm);
         }
 
         // #i86652# - read tab setting
-        if(nullptr != (pSprm = GrpprlHasSprm(0xC615,aGrpprlPapx[0],aLVL.nLenGrpprlPapx)) )
+        aSprm = GrpprlHasSprm(0xC615,aGrpprlPapx[0],aLVL.nLenGrpprlPapx);
+        const sal_uInt8* pSprm = aSprm.pSprm;
+        if (pSprm && aSprm.nRemainingData >= 5)
         {
             bool bDone = false;
             if (*(pSprm-1) == 5)
@@ -664,15 +669,15 @@ bool WW8ListManager::ReadLVL(SwNumFormat& rNumFormat, SfxItemSet*& rpItemSet,
             return false;
 
         //For i120928,parse the graphic info of bullets
-        sal_uInt8 *pSprmWhichPis = GrpprlHasSprm(NS_sprm::sprmCPbiIBullet, aGrpprlChpx[0],aLVL.nLenGrpprlChpx);
-        sal_uInt8 *pSprmIsPicBullet = GrpprlHasSprm(NS_sprm::sprmCPbiGrf, aGrpprlChpx[0],aLVL.nLenGrpprlChpx);
-        if (pSprmWhichPis)
+        SprmResult aSprmWhichPis = GrpprlHasSprm(NS_sprm::sprmCPbiIBullet, aGrpprlChpx[0],aLVL.nLenGrpprlChpx);
+        SprmResult aSprmIsPicBullet = GrpprlHasSprm(NS_sprm::sprmCPbiGrf, aGrpprlChpx[0],aLVL.nLenGrpprlChpx);
+        if (aSprmWhichPis.pSprm && aSprmWhichPis.nRemainingData >= 1)
         {
-            nWitchPicIsBullet = *pSprmWhichPis;
+            nWitchPicIsBullet = *aSprmWhichPis.pSprm;
         }
-        if (pSprmIsPicBullet)
+        if (aSprmIsPicBullet.pSprm && aSprmIsPicBullet.nRemainingData >= 1)
         {
-            bIsPicBullet = (*pSprmIsPicBullet) & 0x0001;
+            bIsPicBullet = (*aSprmIsPicBullet.pSprm) & 0x0001;
         }
 
         // create new Itemset for character attributes
@@ -2053,7 +2058,7 @@ void SwWW8ImplReader::Read_LFOPosition(sal_uInt16, const sal_uInt8* pData,
                         m_nListLevel = WW8ListManager::nMaxLevel;
                     }
                 }
-                else if (m_pPlcxMan && m_pPlcxMan->HasParaSprm(NS_sprm::LN_PAnld))
+                else if (m_pPlcxMan && m_pPlcxMan->HasParaSprm(NS_sprm::LN_PAnld).pSprm)
                 {
                     /*
                      #i8114# Horrific backwards compatible ww7- lists in ww8+
diff --git a/sw/source/filter/ww8/ww8par4.cxx b/sw/source/filter/ww8/ww8par4.cxx
index a34427f880aa..b090f15106f2 100644
--- a/sw/source/filter/ww8/ww8par4.cxx
+++ b/sw/source/filter/ww8/ww8par4.cxx
@@ -485,23 +485,23 @@ void SwWW8ImplReader::Read_CRevisionMark(RedlineType_t eType,
          * of the change, (possibly a word bug) so we must use the "get a full
          * list" variant of HasCharSprm and take the last one as the true one.
          */
-        std::vector<const sal_uInt8 *> aResult;
+        std::vector<SprmResult> aResult;
         bool bIns = (nsRedlineType_t::REDLINE_INSERT == eType);
         if( m_bVer67 )
         {
             m_pPlcxMan->HasCharSprm(69, aResult);
-            pSprmCIbstRMark = aResult.empty() ? nullptr : aResult.back();
+            pSprmCIbstRMark = (aResult.empty() || aResult.back().nRemainingData < 2) ? nullptr : aResult.back().pSprm;
             aResult.clear();
             m_pPlcxMan->HasCharSprm(70, aResult);
-            pSprmCDttmRMark = aResult.empty() ? nullptr : aResult.back();
+            pSprmCDttmRMark = (aResult.empty() || aResult.back().nRemainingData < 4) ? nullptr : aResult.back().pSprm;
         }
         else
         {
             m_pPlcxMan->HasCharSprm( bIns ? 0x4804 : 0x4863, aResult);
-            pSprmCIbstRMark = aResult.empty() ? nullptr : aResult.back();
+            pSprmCIbstRMark = (aResult.empty() || aResult.back().nRemainingData < 2) ? nullptr : aResult.back().pSprm;
             aResult.clear();
             m_pPlcxMan->HasCharSprm( bIns ? 0x6805 : NS_sprm::sprmCDttmRMarkDel, aResult);
-            pSprmCDttmRMark = aResult.empty() ? nullptr : aResult.back();
+            pSprmCDttmRMark = (aResult.empty() || aResult.back().nRemainingData < 4) ? nullptr : aResult.back().pSprm;
         }
     }
 
diff --git a/sw/source/filter/ww8/ww8par5.cxx b/sw/source/filter/ww8/ww8par5.cxx
index 493c18bb4d4f..3c254f99dc71 100644
--- a/sw/source/filter/ww8/ww8par5.cxx
+++ b/sw/source/filter/ww8/ww8par5.cxx
@@ -437,8 +437,8 @@ short SwWW8ImplReader::GetTimeDatePara(OUString& rStr, sal_uInt32& rFormat,
     bool bRTL = false;
     if (m_pPlcxMan && !m_bVer67)
     {
-        const sal_uInt8 *pResult = m_pPlcxMan->HasCharSprm(0x85A);
-        if (pResult && *pResult)
+        SprmResult aResult = m_pPlcxMan->HasCharSprm(0x85A);
+        if (aResult.pSprm && aResult.nRemainingData >= 1 && *aResult.pSprm)
             bRTL = true;
     }
     RES_CHRATR eLang = bRTL ? RES_CHRATR_CTL_LANGUAGE : RES_CHRATR_LANGUAGE;
diff --git a/sw/source/filter/ww8/ww8par6.cxx b/sw/source/filter/ww8/ww8par6.cxx
index 339350f54750..ae0b67c52613 100644
--- a/sw/source/filter/ww8/ww8par6.cxx
+++ b/sw/source/filter/ww8/ww8par6.cxx
@@ -139,22 +139,25 @@ inline sal_uInt32 MSRoundTweak(sal_uInt32 x)
 // (except OLST which stays a normal attribute)
 static short ReadSprm( const WW8PLCFx_SEPX* pSep, sal_uInt16 nId, short nDefaultVal )
 {
-    const sal_uInt8* pS = pSep->HasSprm( nId );          // sprm here?
-    short nVal = ( pS ) ? SVBT16ToShort( pS ) : nDefaultVal;
+    SprmResult aRes = pSep->HasSprm(nId);          // sprm here?
+    const sal_uInt8* pS = aRes.pSprm;
+    short nVal = (pS && aRes.nRemainingData >= 2) ? SVBT16ToShort(pS) : nDefaultVal;
     return nVal;
 }
 
 static sal_uInt16 ReadUSprm( const WW8PLCFx_SEPX* pSep, sal_uInt16 nId, short nDefaultVal )
 {
-    const sal_uInt8* pS = pSep->HasSprm( nId );          // sprm here?
-    sal_uInt16 nVal = ( pS ) ? SVBT16ToShort( pS ) : nDefaultVal;
+    SprmResult aRes = pSep->HasSprm(nId);          // sprm here?
+    const sal_uInt8* pS = aRes.pSprm;
+    sal_uInt16 nVal = (pS && aRes.nRemainingData >= 2) ? SVBT16ToShort(pS) : nDefaultVal;
     return nVal;
 }
 
 static sal_uInt8 ReadBSprm( const WW8PLCFx_SEPX* pSep, sal_uInt16 nId, sal_uInt8 nDefaultVal )
 {
-    const sal_uInt8* pS = pSep->HasSprm( nId );          // sprm here?
-    sal_uInt8 nVal = pS ? *pS : nDefaultVal;
+    SprmResult aRes = pSep->HasSprm(nId);          // sprm here?
+    const sal_uInt8* pS = aRes.pSprm;
+    sal_uInt8 nVal = (pS && aRes.nRemainingData >= 1) ? *pS : nDefaultVal;
     return nVal;
 }
 
@@ -886,7 +889,9 @@ void wwSectionManager::CreateSep(const long nTextPos, bool /*bMustHaveBreak*/)
         // 2 New page
         // 3 Even page
         // 4 Odd page
-        if (const sal_uInt8* pSprmBkc = pSep->HasSprm(pIds[0]))
+        SprmResult aRes = pSep->HasSprm(pIds[0]);
+        const sal_uInt8* pSprmBkc = aRes.pSprm;
+        if (pSprmBkc && aRes.nRemainingData >= 1)
             aNewSection.maSep.bkc = *pSprmBkc;
     }
 
@@ -936,20 +941,22 @@ void wwSectionManager::CreateSep(const long nTextPos, bool /*bMustHaveBreak*/)
             for ( sal_uInt8 nColumn = 0; nColumn < nColumnCount; ++nColumn )
             {
                 //sprmSDxaColWidth
-                const sal_uInt8* pSW = pSep->HasSprm( nColumnWidthSprmId, nColumn );
+                SprmResult aSWRes = pSep->HasSprm(nColumnWidthSprmId, nColumn);
+                const sal_uInt8* pSW = aSWRes.pSprm;
 
                 OSL_ENSURE( pSW, "+Sprm 136 (resp. 0xF203) (ColWidth) missing" );
-                sal_uInt16 nWidth = pSW ? SVBT16ToShort(pSW + 1) : 1440;
+                sal_uInt16 nWidth = (pSW && aSWRes.nRemainingData >= 3) ? SVBT16ToShort(pSW + 1) : 1440;
 
                 aNewSection.maSep.rgdxaColumnWidthSpacing[++nColumnDataIdx] = nWidth;
 
                 if ( nColumn < nColumnCount - 1 )
                 {
                     //sprmSDxaColSpacing
-                    const sal_uInt8* pSD = pSep->HasSprm( nColumnSpacingSprmId, nColumn );
+                    SprmResult aSDRes = pSep->HasSprm(nColumnSpacingSprmId, nColumn);
+                    const sal_uInt8* pSD = aSDRes.pSprm;
 
                     OSL_ENSURE( pSD, "+Sprm 137 (resp. 0xF204) (Colspacing) missing" );
-                    if( pSD )
+                    if (pSD && aSDRes.nRemainingData >= 3)
                     {
                         nWidth = SVBT16ToShort(pSD + 1);
                         aNewSection.maSep.rgdxaColumnWidthSpacing[++nColumnDataIdx] = nWidth;
@@ -997,7 +1004,7 @@ void wwSectionManager::CreateSep(const long nTextPos, bool /*bMustHaveBreak*/)
         /*sprmSDzaGutter*/      0xB025,
         /*sprmSFPgnRestart*/    0x3011,
         /*sprmSPgnStart97*/     0x501C,
-           /*sprmSDmBinFirst*/     0x5007,
+        /*sprmSDmBinFirst*/     0x5007,
         /*sprmSDmBinOther*/     0x5008
     };
 
@@ -1036,19 +1043,27 @@ void wwSectionManager::CreateSep(const long nTextPos, bool /*bMustHaveBreak*/)
 
     aNewSection.maSep.pgnStart = ReadUSprm( pSep, pIds[7], 0 );
 
+    SprmResult aRes;
+
     if (eVer >= ww::eWW6)
     {
-        if (const sal_uInt8* p = pSep->HasSprm( (eVer <= ww::eWW7 ? 132 : 0x3001) ))
-            aNewSection.maSep.iHeadingPgn = *p;
+        aRes = pSep->HasSprm((eVer <= ww::eWW7 ? 132 : 0x3001));
+        if (aRes.pSprm && aRes.nRemainingData >= 1)
+            aNewSection.maSep.iHeadingPgn = *aRes.pSprm;
 
-        if (const sal_uInt8* p = pSep->HasSprm( (eVer <= ww::eWW7 ? 131 : 0x3000) ))
-            aNewSection.maSep.cnsPgn = *p;
+        aRes = pSep->HasSprm((eVer <= ww::eWW7 ? 131 : 0x3000));
+        if (aRes.pSprm && aRes.nRemainingData >= 1)
+            aNewSection.maSep.cnsPgn = *aRes.pSprm;
     }
 
-    if(const sal_uInt8* pSprmSDmBinFirst = pSep->HasSprm( pIds[8] ))
+    aRes = pSep->HasSprm(pIds[8]);
+    const sal_uInt8* pSprmSDmBinFirst = aRes.pSprm;
+    if (pSprmSDmBinFirst && aRes.nRemainingData >= 1)
         aNewSection.maSep.dmBinFirst = *pSprmSDmBinFirst;
 
-    if (const sal_uInt8* pSprmSDmBinOther = pSep->HasSprm( pIds[9] ))
+    aRes = pSep->HasSprm(pIds[9]);
+    const sal_uInt8* pSprmSDmBinOther = aRes.pSprm;
+    if (pSprmSDmBinOther && aRes.nRemainingData >= 1)
         aNewSection.maSep.dmBinOther = *pSprmSDmBinOther;
 
     static const sal_uInt16 nTop[] = { MM_250, 1440 };
@@ -1101,8 +1116,9 @@ void wwSectionManager::CreateSep(const long nTextPos, bool /*bMustHaveBreak*/)
         aNewSection.maSep.wTextFlow = ReadUSprm(pSep, 0x5033, 0);
         aNewSection.maSep.clm = ReadUSprm( pSep, 0x5032, 0 );
         aNewSection.maSep.dyaLinePitch = ReadUSprm(pSep, 0x9031, 360);
-        if (const sal_uInt8* pS = pSep->HasSprm(0x7030))
-            aNewSection.maSep.dxtCharSpace = SVBT32ToUInt32(pS);
+        aRes = pSep->HasSprm(0x7030);
+        if (aRes.pSprm && aRes.nRemainingData >= 4)
+            aNewSection.maSep.dxtCharSpace = SVBT32ToUInt32(aRes.pSprm);
 
         //sprmSPgbProp
         sal_uInt16 pgbProp = ReadSprm( pSep, 0x522F, 0 );
@@ -1115,17 +1131,21 @@ void wwSectionManager::CreateSep(const long nTextPos, bool /*bMustHaveBreak*/)
     }
 
     // check if Line Numbering must be activated or reset
-    if (const sal_uInt8* pSprmSNLnnMod = pSep->HasSprm( pIds[4] ))
-        aNewSection.maSep.nLnnMod = *pSprmSNLnnMod;
+    SprmResult aSprmSNLnnMod = pSep->HasSprm(pIds[4]);
+    if (aSprmSNLnnMod.pSprm && aSprmSNLnnMod.nRemainingData >= 1)
+        aNewSection.maSep.nLnnMod = *aSprmSNLnnMod.pSprm;
 
-    if (const sal_uInt8* pSprmSLnc = pSep->HasSprm( pIds[5] ))
-        aNewSection.maSep.lnc = *pSprmSLnc;
+    SprmResult aSprmSLnc = pSep->HasSprm(pIds[5]);
+    if (aSprmSLnc.pSprm && aSprmSLnc.nRemainingData >= 1)
+        aNewSection.maSep.lnc = *aSprmSLnc.pSprm;
 
-    if (const sal_uInt8* pSprmSDxaLnn = pSep->HasSprm( pIds[6] ))
-        aNewSection.maSep.dxaLnn = SVBT16ToShort( pSprmSDxaLnn );
+    SprmResult aSprmSDxaLnn = pSep->HasSprm(pIds[6]);
+    if (aSprmSDxaLnn.pSprm && aSprmSDxaLnn.nRemainingData >= 2)
+        aNewSection.maSep.dxaLnn = SVBT16ToShort(aSprmSDxaLnn.pSprm);
 
-    if (const sal_uInt8* pSprmSLnnMin = pSep->HasSprm( pIds[7] ))
-        aNewSection.maSep.lnnMin = *pSprmSLnnMin;
+    SprmResult aSprmSLnnMin = pSep->HasSprm(pIds[7]);
+    if (aSprmSLnnMin.pSprm && aSprmSLnnMin.nRemainingData >= 1)
+        aNewSection.maSep.lnnMin = *aSprmSLnnMin.pSprm;
 
     if (eVer <= ww::eWW7)
         aNewSection.maSep.grpfIhdt = ReadBSprm(pSep, eVer <= ww::eWW2 ? 128 : 153, 0);
@@ -1223,16 +1243,16 @@ void SwWW8ImplReader::CopyPageDescHdFt(const SwPageDesc* pOrgPageDesc,
 // Read BoRder Control structure
 // nBrcVer should be set to the version of the BRC record being read (6, 8 or 9)
 // This will be converted to the latest format (9).
-static bool SetWW8_BRC(int nBrcVer, WW8_BRCVer9& rVar, const sal_uInt8* pS)
+static bool SetWW8_BRC(int nBrcVer, WW8_BRCVer9& rVar, const sal_uInt8* pS, size_t nLen)
 {
 
     if( pS )
     {
-        if ( nBrcVer == 9 )
+        if (nBrcVer == 9 && nLen >= sizeof(WW8_BRCVer9))
             rVar = *reinterpret_cast<const WW8_BRCVer9*>(pS);
-        else if( nBrcVer == 8 )
+        else if (nBrcVer == 8 && nLen >= sizeof(WW8_BRC))
             rVar = WW8_BRCVer9(*reinterpret_cast<const WW8_BRC*>(pS));
-        else // nBrcVer == 6
+        else if (nLen >= sizeof(WW8_BRCVer6)) // nBrcVer == 6
             rVar = WW8_BRCVer9(WW8_BRC(*reinterpret_cast<const WW8_BRCVer6*>(pS)));
     }
 
@@ -1251,24 +1271,24 @@ static sal_uInt8 lcl_ReadBorders(bool bVer67, WW8_BRCVer9* brc, WW8PLCFx_Cp_FKP*
     {
         if( !bVer67 )
         {
-            sal_uInt8* pSprm[4];
+            SprmResult aSprm[4];
 
-            if( pSep->Find4Sprms(
+            if (pSep->Find4Sprms(
                     NS_sprm::sprmSBrcTop80, NS_sprm::sprmSBrcLeft80,
                     NS_sprm::sprmSBrcBottom80, NS_sprm::sprmSBrcRight80,
-                    pSprm[0], pSprm[1], pSprm[2], pSprm[3] ) )
+                    aSprm[0], aSprm[1], aSprm[2], aSprm[3]))
             {
                 for( int i = 0; i < 4; ++i )
-                    nBorder |= int(SetWW8_BRC( 8, brc[ i ], pSprm[ i ] ))<<i;
+                    nBorder |= int(SetWW8_BRC(8, brc[i], aSprm[i].pSprm, aSprm[i].nRemainingData))<<i;
             }
             // Version 9 BRCs if present will override version 8
-            if( pSep->Find4Sprms(
+            if (pSep->Find4Sprms(
                     NS_sprm::sprmSBrcTop, NS_sprm::sprmSBrcLeft,
                     NS_sprm::sprmSBrcBottom, NS_sprm::sprmSBrcRight,
-                    pSprm[0], pSprm[1], pSprm[2], pSprm[3] ) )
+                    aSprm[0], aSprm[1], aSprm[2], aSprm[3]))
             {
                 for( int i = 0; i < 4; ++i )
-                    nBorder |= int(SetWW8_BRC( 9, brc[ i ], pSprm[ i ] ))<<i;
+                    nBorder |= int(SetWW8_BRC(9, brc[i], aSprm[i].pSprm, aSprm[i].nRemainingData))<<i;
             }
         }
     }
@@ -1288,15 +1308,24 @@ static sal_uInt8 lcl_ReadBorders(bool bVer67, WW8_BRCVer9* brc, WW8PLCFx_Cp_FKP*
             if (bVer67)
             {
                 for( int i = 0; i < 5; ++i )
-                    nBorder |= int(SetWW8_BRC( 6 , brc[ i ], pPap->HasSprm( aVer67Ids[ i ] )))<<i;
+                {
+                    SprmResult aRes(pPap->HasSprm(aVer67Ids[i]));
+                    nBorder |= int(SetWW8_BRC(6 , brc[i], aRes.pSprm, aRes.nRemainingData))<<i;
+                }
             }
             else
             {
                 for( int i = 0; i < 5; ++i )
-                    nBorder |= int(SetWW8_BRC( 8 , brc[ i ], pPap->HasSprm( aVer8Ids[ i ] )))<<i;
+                {
+                    SprmResult aRes(pPap->HasSprm(aVer8Ids[i]));
+                    nBorder |= int(SetWW8_BRC(8 , brc[i], aRes.pSprm, aRes.nRemainingData))<<i;
+                }
                 // Version 9 BRCs if present will override version 8
                 for( int i = 0; i < 5; ++i )
-                    nBorder |= int(SetWW8_BRC( 9 , brc[ i ], pPap->HasSprm( aVer9Ids[ i ] )))<<i;
+                {
+                    SprmResult aRes(pPap->HasSprm(aVer9Ids[i]));
+                    nBorder |= int(SetWW8_BRC(9 , brc[i], aRes.pSprm, aRes.nRemainingData))<<i;
+                }
             }
         }
         else if( pSty )
@@ -1304,15 +1333,24 @@ static sal_uInt8 lcl_ReadBorders(bool bVer67, WW8_BRCVer9* brc, WW8PLCFx_Cp_FKP*
             if (bVer67)
             {
                 for( int i = 0; i < 5; ++i )
-                    nBorder |= int(SetWW8_BRC( 6 , brc[ i ], pSty->HasParaSprm( aVer67Ids[ i ] )))<<i;
+                {
+                    SprmResult aRes(pSty->HasParaSprm(aVer67Ids[i]));
+                    nBorder |= int(SetWW8_BRC(6 , brc[i], aRes.pSprm, aRes.nRemainingData))<<i;
+                }
             }
             else
             {
                 for( int i = 0; i < 5; ++i )
-                    nBorder |= int(SetWW8_BRC( 8 , brc[ i ], pSty->HasParaSprm( aVer8Ids[ i ] )))<<i;
+                {
+                    SprmResult aRes(pSty->HasParaSprm(aVer8Ids[i]));
+                    nBorder |= int(SetWW8_BRC(8 , brc[i], aRes.pSprm, aRes.nRemainingData))<<i;
+                }
                 // Version 9 BRCs if present will override version 8
                 for( int i = 0; i < 5; ++i )
-                    nBorder |= int(SetWW8_BRC( 9 , brc[ i ], pSty->HasParaSprm( aVer9Ids[ i ] )))<<i;
+                {
+                    SprmResult aRes(pSty->HasParaSprm(aVer9Ids[i]));
+                    nBorder |= int(SetWW8_BRC(9 , brc[i], aRes.pSprm, aRes.nRemainingData))<<i;
+                }
             }
         }
         else {
@@ -1490,18 +1528,18 @@ static void FlySecur1(short& rSize, const bool bBorder)
 
 inline bool SetValSprm( sal_Int16* pVar, WW8PLCFx_Cp_FKP* pPap, sal_uInt16 nId )
 {
-    const sal_uInt8* pS = pPap->HasSprm( nId );
-    if( pS )
-        *pVar = (sal_Int16)SVBT16ToShort( pS );
-    return ( pS != nullptr );
+    SprmResult aS = pPap->HasSprm(nId);
+    if (aS.pSprm && aS.nRemainingData >= 2)
+        *pVar = (sal_Int16)SVBT16ToShort(aS.pSprm);
+    return aS.pSprm != nullptr;
 }
 
 inline bool SetValSprm( sal_Int16* pVar, const WW8RStyle* pStyle, sal_uInt16 nId )
 {
-    const sal_uInt8* pS = pStyle->HasParaSprm( nId );
-    if( pS )
-        *pVar = (sal_Int16)SVBT16ToShort( pS );
-    return ( pS != nullptr );
+    SprmResult aS = pStyle->HasParaSprm(nId);
+    if (aS.pSprm && aS.nRemainingData >= 2)
+        *pVar = (sal_Int16)SVBT16ToShort(aS.pSprm);
+    return aS.pSprm != nullptr;
 }
 
 /*
@@ -1560,7 +1598,6 @@ bool WW8FlyPara::operator==(const WW8FlyPara& rSrc) const
 // Read for normal text
 void WW8FlyPara::Read(sal_uInt8 nOrigSp29, WW8PLCFx_Cp_FKP* pPap)
 {
-    const sal_uInt8* pS = nullptr;
     if( bVer67 )
     {
         SetValSprm( &nSp26, pPap, 26 ); // X-position   //sprmPDxaAbs
@@ -1573,9 +1610,9 @@ void WW8FlyPara::Read(sal_uInt8 nOrigSp29, WW8PLCFx_Cp_FKP* pPap)
         SetValSprm( &nUpMgn, pPap, 48 ); // U-border    //sprmPDyaFromText
         SetValSprm( &nLoMgn, pPap, 48 ); // D-border    //sprmPDyaFromText
 
-        pS = pPap->HasSprm( 37 );                       //sprmPWr
-        if( pS )
-            nSp37 = *pS;
+        SprmResult aS = pPap->HasSprm(37);                       //sprmPWr
+        if (aS.pSprm && aS.nRemainingData >= 1)
+            nSp37 = *aS.pSprm;
     }
     else
     {
@@ -1589,9 +1626,9 @@ void WW8FlyPara::Read(sal_uInt8 nOrigSp29, WW8PLCFx_Cp_FKP* pPap)
         SetValSprm( &nUpMgn, pPap, NS_sprm::sprmPDyaFromText );    // U-border
         SetValSprm( &nLoMgn, pPap, NS_sprm::sprmPDyaFromText );    // D-border
 
-        pS = pPap->HasSprm( NS_sprm::sprmPWr );                               // wrapping
-        if( pS )
-            nSp37 = *pS;
+        SprmResult aS = pPap->HasSprm(NS_sprm::sprmPWr);                               // wrapping
+        if (aS.pSprm && aS.nRemainingData >= 1)
+            nSp37 = *aS.pSprm;
     }
 
     if( ::lcl_ReadBorders( bVer67, brc, pPap ))     // borders
@@ -1642,10 +1679,10 @@ void WW8FlyPara::ReadFull(sal_uInt8 nOrigSp29, SwWW8ImplReader* pIo)
 
             // in APO ?
             //sprmPPc
-            const sal_uInt8* pS = pPap->HasSprm( bVer67 ? 29 : 0x261B );
+            SprmResult aS = pPap->HasSprm( bVer67 ? 29 : 0x261B );
 
             // no -> graphics Apo
-            if (!pS)
+            if (!aS.pSprm || aS.nRemainingData < 1)
             {
                 bGrafApo = true;
                 break;                              // end of APO
@@ -1663,7 +1700,7 @@ void WW8FlyPara::ReadFull(sal_uInt8 nOrigSp29, SwWW8ImplReader* pIo)
 
             WW8FlyPara aF(bVer67, pNowStyleApo);
                                                 // new FlaPara for comparison
-            aF.Read( *pS, pPap );               // WWPara for new Para
+            aF.Read(*aS.pSprm, pPap);               // WWPara for new Para
             if( !( aF == *this ) )              // same APO? (or a new one?)
                 bGrafApo = true;                // no -> 1-line APO
                                                 //    -> graphics APO
@@ -1678,7 +1715,6 @@ void WW8FlyPara::ReadFull(sal_uInt8 nOrigSp29, SwWW8ImplReader* pIo)
 // read for Apo definitions in Styledefs
 void WW8FlyPara::Read(sal_uInt8 nOrigSp29, WW8RStyle* pStyle)
 {
-    const sal_uInt8* pS = nullptr;
     if (bVer67)
     {
         SetValSprm( &nSp26, pStyle, 26 );   // X-position
@@ -1691,9 +1727,9 @@ void WW8FlyPara::Read(sal_uInt8 nOrigSp29, WW8RStyle* pStyle)
         SetValSprm( &nUpMgn,    pStyle, 48 );   // U-border
         SetValSprm( &nLoMgn,    pStyle, 48 );   // D-border
 
-        pS = pStyle->HasParaSprm( 37 );             // wrapping
-        if( pS )
-            nSp37 = *pS;
+        SprmResult aS = pStyle->HasParaSprm( 37 );             // wrapping
+        if (aS.pSprm && aS.nRemainingData >= 1)
+            nSp37 = *aS.pSprm;
     }
     else
     {
@@ -1707,9 +1743,9 @@ void WW8FlyPara::Read(sal_uInt8 nOrigSp29, WW8RStyle* pStyle)
         SetValSprm( &nUpMgn, pStyle, 0x842E );  // U-border
         SetValSprm( &nLoMgn, pStyle, 0x842E );  // D-border
 
-        pS = pStyle->HasParaSprm( 0x2423 );             // wrapping
-        if( pS )
-            nSp37 = *pS;
+        SprmResult aS = pStyle->HasParaSprm( 0x2423 );             // wrapping
+        if (aS.pSprm && aS.nRemainingData >= 1)
+            nSp37 = *aS.pSprm;
     }
 
     if (::lcl_ReadBorders(bVer67, brc, nullptr, pStyle))      // border
@@ -1761,8 +1797,8 @@ WW8SwFlyPara::WW8SwFlyPara( SwPaM& rPaM,
 
     eSurround = ( rWW.nSp37 > 1 ) ? css::text::WrapTextMode_DYNAMIC : css::text::WrapTextMode_NONE;
     //#i119466 mapping "Around" wrap setting to "Parallel" for table
-    const bool bIsTable = rIo.m_pPlcxMan->HasParaSprm(0x2416);
-    if (  bIsTable && rWW.nSp37 == 2 )
+    const bool bIsTable = rIo.m_pPlcxMan->HasParaSprm(0x2416).pSprm;
+    if (bIsTable && rWW.nSp37 == 2)
         eSurround = css::text::WrapTextMode_PARALLEL;
 
     /*
@@ -2286,12 +2322,12 @@ bool SwWW8ImplReader::IsDropCap()
     WW8PLCFx_Cp_FKP *pPap = m_pPlcxMan ? m_pPlcxMan->GetPapPLCF() : nullptr;
     if (pPap)
     {
-        const sal_uInt8 *pDCS;
+        SprmResult aDCS;
         if (m_bVer67)
-            pDCS = pPap->HasSprm(46);
+            aDCS = pPap->HasSprm(46);
         else
-            pDCS = m_pPlcxMan->GetPapPLCF()->HasSprm(0x442C);
-        if(pDCS)
+            aDCS = m_pPlcxMan->GetPapPLCF()->HasSprm(0x442C);
+        if (aDCS.pSprm && aDCS.nRemainingData >= 2)
         {
             /*
               fdct   short :3   0007     drop cap type
@@ -2299,7 +2335,7 @@ bool SwWW8ImplReader::IsDropCap()
                                          1 normal drop cap
                                          2 drop cap in margin
             */
-            short nDCS = SVBT16ToShort( pDCS );
+            short nDCS = SVBT16ToShort(aDCS.pSprm);
             if (nDCS & 7)
                 return true;
         }
@@ -2871,10 +2907,10 @@ void SwWW8ImplReader::Read_BoldUsw( sal_uInt16 nId, const sal_uInt8* pData, shor
     SwWW8StyInf* pSI = GetStyle(m_nAktColl);
     if (m_pPlcxMan && eVersion > ww::eWW2)
     {
-        const sal_uInt8 *pCharIstd =
+        SprmResult aCharIstd =
             m_pPlcxMan->GetChpPLCF()->HasSprm(m_bVer67 ? 80 : 0x4A30);
-        if (pCharIstd)
-            pSI = GetStyle(SVBT16ToShort(pCharIstd));
+        if (aCharIstd.pSprm && aCharIstd.nRemainingData >= 2)
+            pSI = GetStyle(SVBT16ToShort(aCharIstd.pSprm));
     }
 
     if( m_pAktColl )                          // StyleDef -> remember flags
@@ -3038,10 +3074,10 @@ void SwWW8ImplReader::Read_BoldBiDiUsw(sal_uInt16 nId, const sal_uInt8* pData,
     SwWW8StyInf* pSI = GetStyle(m_nAktColl);
     if (m_pPlcxMan)
     {
-        const sal_uInt8 *pCharIstd =
+        SprmResult aCharIstd =
             m_pPlcxMan->GetChpPLCF()->HasSprm(m_bVer67 ? 80 : 0x4A30);
-        if (pCharIstd)
-            pSI = GetStyle(SVBT16ToShort(pCharIstd));
+        if (aCharIstd.pSprm && aCharIstd.nRemainingData >= 2)
+            pSI = GetStyle(SVBT16ToShort(aCharIstd.pSprm));
     }
 
     if (m_pAktColl && eVersion > ww::eWW2)        // StyleDef -> remember flags
@@ -3412,7 +3448,7 @@ void SwWW8ImplReader::Read_DoubleLine_Rotate( sal_uInt16, const sal_uInt8* pData
 void SwWW8ImplReader::Read_TextColor( sal_uInt16, const sal_uInt8* pData, short nLen )
 {
     //Has newer colour variant, ignore this old variant
-    if (!m_bVer67 && m_pPlcxMan && m_pPlcxMan->GetChpPLCF()->HasSprm(NS_sprm::sprmCCv))
+    if (!m_bVer67 && m_pPlcxMan && m_pPlcxMan->GetChpPLCF()->HasSprm(NS_sprm::sprmCCv).pSprm)
         return;
 
     if (nLen < 1)
@@ -3894,7 +3930,7 @@ void SwWW8ImplReader::Read_FontKern( sal_uInt16, const sal_uInt8* , short nLen )
 void SwWW8ImplReader::Read_CharShadow(  sal_uInt16, const sal_uInt8* pData, short nLen )
 {
     //Has newer colour variant, ignore this old variant
-    if (!m_bVer67 && m_pPlcxMan && m_pPlcxMan->GetChpPLCF()->HasSprm(0xCA71))
+    if (!m_bVer67 && m_pPlcxMan && m_pPlcxMan->GetChpPLCF()->HasSprm(0xCA71).pSprm)
         return;
 
     if (nLen < 2)
@@ -3981,9 +4017,9 @@ bool lcl_HasExplicitLeft(const WW8PLCFMan *pPlcxMan, bool bVer67)
     if (pPap)
     {
         if (bVer67)
-            return pPap->HasSprm(17);
+            return pPap->HasSprm(17).pSprm;
         else
-            return (pPap->HasSprm(0x840F) || pPap->HasSprm(0x845E));
+            return (pPap->HasSprm(0x840F).pSprm || pPap->HasSprm(0x845E).pSprm);
     }
     return false;
 }
@@ -4086,8 +4122,8 @@ void SwWW8ImplReader::Read_LR( sal_uInt16 nId, const sal_uInt8* pData, short nLe
             */
             if (m_pPlcxMan && m_nAktColl < m_vColl.size() && m_vColl[m_nAktColl].m_bHasBrokenWW6List)
             {
-                const sal_uInt8 *pIsZeroed = m_pPlcxMan->GetPapPLCF()->HasSprm(0x460B);
-                if (pIsZeroed && *pIsZeroed == 0)
+                SprmResult aIsZeroed = m_pPlcxMan->GetPapPLCF()->HasSprm(0x460B);
+                if (aIsZeroed.pSprm && aIsZeroed.nRemainingData >= 1 && *aIsZeroed.pSprm == 0)
                 {
                     const SvxLRSpaceItem &rLR =
                         ItemGet<SvxLRSpaceItem>(*(m_vColl[m_nAktColl].m_pFormat),
@@ -4378,10 +4414,11 @@ void SwWW8ImplReader::Read_Justify( sal_uInt16, const sal_uInt8* pData, short nL
 bool SwWW8ImplReader::IsRightToLeft()
 {
     bool bRTL = false;
-    const sal_uInt8 *pDir =
-        m_pPlcxMan ? m_pPlcxMan->GetPapPLCF()->HasSprm(0x2441) : nullptr;
-    if (pDir)
-        bRTL = *pDir != 0;
+    SprmResult aDir;
+    if (m_pPlcxMan)
+        aDir = m_pPlcxMan->GetPapPLCF()->HasSprm(0x2441);
+    if (aDir.pSprm && aDir.nRemainingData >= 1)
+        bRTL = *aDir.pSprm != 0;
     else
     {
         const SvxFrameDirectionItem* pItem=
@@ -4475,11 +4512,12 @@ void SwWW8ImplReader::Read_Emphasis( sal_uInt16, const sal_uInt8* pData, short n
         //there is use it, if there is not fall back to the currently set one.
         //Only the cjk language setting seems to matter to word, the western
         //one is ignored
-        const sal_uInt8 *pLang =
-            m_pPlcxMan ? m_pPlcxMan->GetChpPLCF()->HasSprm(0x486E) : nullptr;
+        SprmResult aLang;
+        if (m_pPlcxMan)
+            aLang = m_pPlcxMan->GetChpPLCF()->HasSprm(0x486E);
 
-        if (pLang)
-            nLang = SVBT16ToShort( pLang );
+        if (aLang.pSprm && aLang.nRemainingData >= 2)
+            nLang = SVBT16ToShort(aLang.pSprm);
         else
         {
             nLang = static_cast<const SvxLanguageItem *>(
@@ -4723,7 +4761,7 @@ void SwWW8Shade::SetShade(ColorData nFore, ColorData nBack, sal_uInt16 nIndex)
 
 void SwWW8ImplReader::Read_Shade( sal_uInt16, const sal_uInt8* pData, short nLen )
 {
-    if (!m_bVer67 && m_pPlcxMan && m_pPlcxMan->GetPapPLCF()->HasSprm(0xC64D))
+    if (!m_bVer67 && m_pPlcxMan && m_pPlcxMan->GetPapPLCF()->HasSprm(0xC64D).pSprm)
         return;
 
     if (nLen < 2)
@@ -4894,7 +4932,7 @@ void SwWW8ImplReader::Read_CharBorder(sal_uInt16 nId, const sal_uInt8* pData, sh
             WW8_BRCVer9 aBrc;
             int nBrcVer = (nId == NS_sprm::sprmCBrc) ? 9 : (m_bVer67 ? 6 : 8);
 
-            SetWW8_BRC(nBrcVer, aBrc, pData);
+            SetWW8_BRC(nBrcVer, aBrc, pData, nLen);
 
             // Border style is none -> no border, no shadow
             if( editeng::ConvertBorderStyleFromWord(aBrc.brcType()) != SvxBorderLineStyle::NONE )
@@ -5048,30 +5086,37 @@ void SwWW8ImplReader::Read_ApoPPC( sal_uInt16, const sal_uInt8* pData, short )
 bool SwWW8ImplReader::ParseTabPos(WW8_TablePos *pTabPos, WW8PLCFx_Cp_FKP* pPap)
 {
     bool bRet = false;
-    const sal_uInt8 *pRes=nullptr;
     memset(pTabPos, 0, sizeof(WW8_TablePos));
-    if (nullptr != (pRes = pPap->HasSprm(0x360D)))
+    SprmResult aRes = pPap->HasSprm(0x360D);
+    if (aRes.pSprm && aRes.nRemainingData >= 1)
     {
-        pTabPos->nSp29 = *pRes;
+        pTabPos->nSp29 = *aRes.pSprm;
         pTabPos->nSp37 = 2;     //Possible fail area, always parallel wrap
-        if (nullptr != (pRes = pPap->HasSprm(0x940E)))
-            pTabPos->nSp26 = SVBT16ToShort(pRes);
-        if (nullptr != (pRes = pPap->HasSprm(0x940F)))
-            pTabPos->nSp27 = SVBT16ToShort(pRes);
-        if (nullptr != (pRes = pPap->HasSprm(0x9410)))
-            pTabPos->nLeMgn = SVBT16ToShort(pRes);
-        if (nullptr != (pRes = pPap->HasSprm(0x941E)))
-            pTabPos->nRiMgn = SVBT16ToShort(pRes);
-        if (nullptr != (pRes = pPap->HasSprm(0x9411)))
-            pTabPos->nUpMgn = SVBT16ToShort(pRes);
-        if (nullptr != (pRes = pPap->HasSprm(0x941F)))
-            pTabPos->nLoMgn = SVBT16ToShort(pRes);
+        aRes = pPap->HasSprm(0x940E);
+        if (aRes.pSprm && aRes.nRemainingData >= 2)
+            pTabPos->nSp26 = SVBT16ToShort(aRes.pSprm);
+        aRes = pPap->HasSprm(0x940F);
+        if (aRes.pSprm && aRes.nRemainingData >= 2)
+            pTabPos->nSp27 = SVBT16ToShort(aRes.pSprm);
+        aRes = pPap->HasSprm(0x9410);
+        if (aRes.pSprm && aRes.nRemainingData >= 2)
+            pTabPos->nLeMgn = SVBT16ToShort(aRes.pSprm);
+        aRes = pPap->HasSprm(0x941E);
+        if (aRes.pSprm && aRes.nRemainingData >= 2)
+            pTabPos->nRiMgn = SVBT16ToShort(aRes.pSprm);
+        aRes = pPap->HasSprm(0x9411);
+        if (aRes.pSprm && aRes.nRemainingData >= 2)
+            pTabPos->nUpMgn = SVBT16ToShort(aRes.pSprm);
+        aRes = pPap->HasSprm(0x941F);
+        if (aRes.pSprm && aRes.nRemainingData >= 2)
+            pTabPos->nLoMgn = SVBT16ToShort(aRes.pSprm);
         bRet = true;
     }
-    if (nullptr != (pRes = pPap->HasSprm(NS_sprm::sprmTDefTable)))
+    aRes = pPap->HasSprm(NS_sprm::sprmTDefTable);
+    if (nullptr != aRes.pSprm)
     {
         WW8TabBandDesc aDesc;
-        aDesc.ReadDef(false, pRes);
+        aDesc.ReadDef(false, aRes.pSprm);
         int nTableWidth = aDesc.nCenter[aDesc.nWwCols] - aDesc.nCenter[0];
         int nTextAreaWidth = m_aSectionManager.GetTextAreaWidth();
         // If the table is wider than the text area, then don't create a fly
diff --git a/sw/source/filter/ww8/ww8scan.cxx b/sw/source/filter/ww8/ww8scan.cxx
index 66d2da14515d..f63e461b5a05 100644
--- a/sw/source/filter/ww8/ww8scan.cxx
+++ b/sw/source/filter/ww8/ww8scan.cxx
@@ -917,16 +917,20 @@ void WW8SprmIter::UpdateMyMembers()
     }
 }
 
-const sal_uInt8* WW8SprmIter::FindSprm(sal_uInt16 nId)
+SprmResult WW8SprmIter::FindSprm(sal_uInt16 nId)
 {
     while (GetSprms())
     {
         if (GetAktId() == nId)
-            return GetAktParams();              // SPRM found!
+        {
+            sal_uInt16 nFixedLen =  mrSprmParser.DistanceToData(nId);
+            sal_uInt16 nL = mrSprmParser.GetSprmSize(nId, GetSprms(), GetRemLen());
+            return SprmResult(GetAktParams(), nL - nFixedLen); // SPRM found!
+        }
         advance();
     }
 
-    return nullptr;                                   // SPRM _not_ found
+    return SprmResult();                                   // SPRM _not_ found
 }
 
 // temporary test
@@ -2723,10 +2727,10 @@ sal_uInt8* WW8PLCFx_Fc_FKP::WW8Fkp::GetLenAndIStdAndSprms(sal_Int32& rLen) const
     return maEntries[mnIdx].mpData;
 }
 
-const sal_uInt8* WW8PLCFx_Fc_FKP::WW8Fkp::HasSprm( sal_uInt16 nId )
+SprmResult WW8PLCFx_Fc_FKP::WW8Fkp::HasSprm( sal_uInt16 nId )
 {
     if (mnIdx >= mnIMax)
-        return nullptr;
+        return SprmResult();
 
     sal_Int32 nLen;
     sal_uInt8* pSprms = GetLenAndIStdAndSprms( nLen );
@@ -2736,7 +2740,7 @@ const sal_uInt8* WW8PLCFx_Fc_FKP::WW8Fkp::HasSprm( sal_uInt16 nId )
 }
 
 void WW8PLCFx_Fc_FKP::WW8Fkp::HasSprm(sal_uInt16 nId,
-    std::vector<const sal_uInt8 *> &rResult)
+    std::vector<SprmResult> &rResult)
 {
     if (mnIdx >= mnIMax)
        return;
@@ -2749,7 +2753,11 @@ void WW8PLCFx_Fc_FKP::WW8Fkp::HasSprm(sal_uInt16 nId,
     while(aIter.GetSprms())
     {
         if (aIter.GetAktId() == nId)
-            rResult.push_back(aIter.GetAktParams());
+        {
+            sal_uInt16 nFixedLen = maSprmParser.DistanceToData(nId);
+            sal_uInt16 nL = maSprmParser.GetSprmSize(nId, aIter.GetSprms(), aIter.GetRemLen());
+            rResult.push_back(SprmResult(aIter.GetAktParams(), nL - nFixedLen));
+        }
         aIter.advance();
     };
 }
@@ -3022,7 +3030,7 @@ void WW8PLCFx_Fc_FKP::GetPCDSprms( WW8PLCFxDesc& rDesc )
     }
 }
 
-const sal_uInt8* WW8PLCFx_Fc_FKP::HasSprm( sal_uInt16 nId )
+SprmResult WW8PLCFx_Fc_FKP::HasSprm(sal_uInt16 nId)
 {
     // const would be nicer, but for that, NewFkp() would need to be replaced or eliminated
     if( !pFkp )
@@ -3030,15 +3038,15 @@ const sal_uInt8* WW8PLCFx_Fc_FKP::HasSprm( sal_uInt16 nId )
         OSL_FAIL( "+Motz: HasSprm: NewFkp needed ( no const possible )" );
         // happens in BugDoc 31722
         if( !NewFkp() )
-            return nullptr;
+            return SprmResult();
     }
 
     if (!pFkp)
-        return nullptr;
+        return SprmResult();
 
-    const sal_uInt8* pRes = pFkp->HasSprm( nId );
+    SprmResult aRes = pFkp->HasSprm(nId);
 
-    if( !pRes )
+    if (!aRes.pSprm)
     {
         WW8PLCFxDesc aDesc;
         GetPCDSprms( aDesc );
@@ -3047,14 +3055,14 @@ const sal_uInt8* WW8PLCFx_Fc_FKP::HasSprm( sal_uInt16 nId )
         {
             WW8SprmIter aIter(aDesc.pMemPos, aDesc.nSprmsLen,
                 pFkp->GetSprmParser());
-            pRes = aIter.FindSprm(nId);
+            aRes = aIter.FindSprm(nId);
         }
     }
 
-    return pRes;
+    return aRes;
 }
 
-bool WW8PLCFx_Fc_FKP::HasSprm(sal_uInt16 nId, std::vector<const sal_uInt8 *> &rResult)
+bool WW8PLCFx_Fc_FKP::HasSprm(sal_uInt16 nId, std::vector<SprmResult> &rResult)
 {
     // const would be nicer, but for that, NewFkp() would need to be replaced or eliminated
     if (!pFkp)
@@ -3075,12 +3083,16 @@ bool WW8PLCFx_Fc_FKP::HasSprm(sal_uInt16 nId, std::vector<const sal_uInt8 *> &rR
 
     if (aDesc.pMemPos)
     {
-        WW8SprmIter aIter(aDesc.pMemPos, aDesc.nSprmsLen,
-            pFkp->GetSprmParser());
+        const wwSprmParser &rSprmParser = pFkp->GetSprmParser();
+        WW8SprmIter aIter(aDesc.pMemPos, aDesc.nSprmsLen, rSprmParser);
         while(aIter.GetSprms())
         {
             if (aIter.GetAktId() == nId)
-                rResult.push_back(aIter.GetAktParams());
+            {
+                sal_uInt16 nFixedLen = rSprmParser.DistanceToData(nId);
+                sal_uInt16 nL = rSprmParser.GetSprmSize(nId, aIter.GetSprms(), aIter.GetRemLen());
+                rResult.push_back(SprmResult(aIter.GetAktParams(), nL - nFixedLen));
+            }
             aIter.advance();
         };
     }
@@ -3464,34 +3476,30 @@ void WW8PLCFx_SEPX::advance()
         pPLCF->advance();
 }
 
-const sal_uInt8* WW8PLCFx_SEPX::HasSprm( sal_uInt16 nId ) const
+SprmResult WW8PLCFx_SEPX::HasSprm(sal_uInt16 nId) const
 {
-    return HasSprm( nId, pSprms, nSprmSiz);
+    return HasSprm(nId, pSprms, nSprmSiz);
 }
 
-const sal_uInt8* WW8PLCFx_SEPX::HasSprm( sal_uInt16 nId, const sal_uInt8*  pOtherSprms,
+SprmResult WW8PLCFx_SEPX::HasSprm( sal_uInt16 nId, const sal_uInt8*  pOtherSprms,
     long nOtherSprmSiz ) const
 {
-    const sal_uInt8 *pRet = nullptr;
+    SprmResult aRet;
     if (pPLCF)
     {
         WW8SprmIter aIter(pOtherSprms, nOtherSprmSiz, maSprmParser);
-        pRet = aIter.FindSprm(nId);
+        aRet = aIter.FindSprm(nId);
     }
-    return pRet;
+    return aRet;
 }
 
 bool WW8PLCFx_SEPX::Find4Sprms(sal_uInt16 nId1,sal_uInt16 nId2,sal_uInt16 nId3,sal_uInt16 nId4,
-    sal_uInt8*& p1, sal_uInt8*& p2, sal_uInt8*& p3, sal_uInt8*& p4) const
+    SprmResult& r1, SprmResult& r2, SprmResult& r3, SprmResult& r4) const
 {
     if( !pPLCF )
         return false;
 
     bool bFound = false;
-    p1 = nullptr;
-    p2 = nullptr;
-    p3 = nullptr;
-    p4 = nullptr;
 
     sal_uInt8* pSp = pSprms;
     sal_uInt16 i=0;
@@ -3499,30 +3507,42 @@ bool WW8PLCFx_SEPX::Find4Sprms(sal_uInt16 nId1,sal_uInt16 nId2,sal_uInt16 nId3,s
     {
         // Sprm found?
         const sal_uInt16 nAktId = maSprmParser.GetSprmId(pSp);
+        const sal_uInt16 x = maSprmParser.GetSprmSize(nAktId, pSp, nSprmSiz - i);
         bool bOk = true;
         if( nAktId  == nId1 )
-            p1 = pSp + maSprmParser.DistanceToData(nId1);
+        {
+            sal_uInt16 nFixedLen = maSprmParser.DistanceToData(nId1);
+            r1 = SprmResult(pSp + nFixedLen, x - nFixedLen);
+        }
         else if( nAktId  == nId2 )
-            p2 = pSp + maSprmParser.DistanceToData(nId2);
+        {
+            sal_uInt16 nFixedLen = maSprmParser.DistanceToData(nId2);
+            r2 = SprmResult(pSp + nFixedLen, x - nFixedLen);
+        }
         else if( nAktId  == nId3 )
-            p3 = pSp + maSprmParser.DistanceToData(nId3);
+        {
+            sal_uInt16 nFixedLen = maSprmParser.DistanceToData(nId3);
+            r3 = SprmResult(pSp + nFixedLen, x - nFixedLen);
+        }
         else if( nAktId  == nId4 )
-            p4 = pSp + maSprmParser.DistanceToData(nId4);
+        {
+            sal_uInt16 nFixedLen = maSprmParser.DistanceToData(nId4);
+            r4 = SprmResult(pSp + nFixedLen, x - nFixedLen);
+        }
         else
             bOk = false;
         bFound |= bOk;
         // increment pointer so that it points to next SPRM
-        const sal_uInt16 x = maSprmParser.GetSprmSize(nAktId, pSp, nSprmSiz - i);
         i += x;
         pSp += x;
     }
     return bFound;
 }
 
-const sal_uInt8* WW8PLCFx_SEPX::HasSprm( sal_uInt16 nId, sal_uInt8 n2nd ) const
+SprmResult WW8PLCFx_SEPX::HasSprm( sal_uInt16 nId, sal_uInt8 n2nd ) const
 {
-    if( !pPLCF )
-        return nullptr;
+    if (!pPLCF)
+        return SprmResult();
 
     sal_uInt8* pSp = pSprms;
 
@@ -3531,19 +3551,23 @@ const sal_uInt8* WW8PLCFx_SEPX::HasSprm( sal_uInt16 nId, sal_uInt8 n2nd ) const
     {
         // Sprm found?
         const sal_uInt16 nAktId = maSprmParser.GetSprmId(pSp);
+        const sal_uInt16 x = maSprmParser.GetSprmSize(nAktId, pSp, nSprmSiz - i);
         if (nAktId == nId)
         {
-            sal_uInt8 *pRet = pSp + maSprmParser.DistanceToData(nId);
-            if (*pRet == n2nd)
-                return pRet;
+            sal_uInt16 nFixedLen =  maSprmParser.DistanceToData(nId);
+            const sal_uInt8 *pRet = pSp + nFixedLen;
+            SprmResult aRet(pRet, x - nFixedLen);
+            if (aRet.nRemainingData >= 1 && *aRet.pSprm == n2nd)
+            {
+                return aRet;
+            }
         }
         // increment pointer so that it points to next SPRM
-        const sal_uInt16 x = maSprmParser.GetSprmSize(nAktId, pSp, nSprmSiz - i);
         i += x;
         pSp += x;
     }
 
-    return nullptr;   // Sprm not found
+    return SprmResult();   // Sprm not found
 }
 
 WW8PLCFx_SubDoc::WW8PLCFx_SubDoc(SvStream* pSt, const WW8Fib& rFib,
@@ -5219,18 +5243,18 @@ WW8PLCFx_FLD* WW8PLCFMan::GetField() const
     return static_cast<WW8PLCFx_FLD*>(m_pField->pPLCFx);
 }
 
-const sal_uInt8* WW8PLCFMan::HasParaSprm( sal_uInt16 nId ) const
+SprmResult WW8PLCFMan::HasParaSprm( sal_uInt16 nId ) const
 {
     return static_cast<WW8PLCFx_Cp_FKP*>(m_pPap->pPLCFx)->HasSprm( nId );
 }
 
-const sal_uInt8* WW8PLCFMan::HasCharSprm( sal_uInt16 nId ) const
+SprmResult WW8PLCFMan::HasCharSprm( sal_uInt16 nId ) const
 {
     return static_cast<WW8PLCFx_Cp_FKP*>(m_pChp->pPLCFx)->HasSprm( nId );
 }
 
 void WW8PLCFMan::HasCharSprm(sal_uInt16 nId,
-    std::vector<const sal_uInt8 *> &rResult) const
+    std::vector<SprmResult> &rResult) const
 {
     static_cast<WW8PLCFx_Cp_FKP*>(m_pChp->pPLCFx)->HasSprm(nId, rResult);
 }
@@ -7971,7 +7995,7 @@ sal_uInt16 wwSprmParser::DistanceToData(sal_uInt16 nId) const
     return 1 + mnDelta + SprmDataOfs(nId);
 }
 
-sal_uInt8* wwSprmParser::findSprmData(sal_uInt16 nId, sal_uInt8* pSprms,
+SprmResult wwSprmParser::findSprmData(sal_uInt16 nId, sal_uInt8* pSprms,
     sal_uInt16 nLen) const
 {
     while (nLen >= MinSprmLen())
@@ -7987,7 +8011,10 @@ sal_uInt8* wwSprmParser::findSprmData(sal_uInt16 nId, sal_uInt8* pSprms,
             nSize << " vs " << nLen << "doc or parser is wrong");
 
         if (nAktId == nId && bValid) // Sprm found
-            return pSprms + DistanceToData(nId);
+        {
+            sal_uInt16 nFixedLen = DistanceToData(nId);
+            return SprmResult(pSprms + nFixedLen, nSize - nFixedLen);
+        }
 
         //Clip to available size if wrong
         nSize = std::min(nSize, nLen);
@@ -7995,7 +8022,7 @@ sal_uInt8* wwSprmParser::findSprmData(sal_uInt16 nId, sal_uInt8* pSprms,
         nLen -= nSize;
     }
     // Sprm not found
-    return nullptr;
+    return SprmResult();
 }
 
 SEPr::SEPr() :
diff --git a/sw/source/filter/ww8/ww8scan.hxx b/sw/source/filter/ww8/ww8scan.hxx
index d2e96bb93df5..ab1fef0ee42c 100644
--- a/sw/source/filter/ww8/ww8scan.hxx
+++ b/sw/source/filter/ww8/ww8scan.hxx
@@ -97,6 +97,22 @@ private:
 
 class WW8Fib;
 
+struct SprmResult
+{
+    const sal_uInt8* pSprm;
+    sal_Int32 nRemainingData;
+    SprmResult()
+        : pSprm(nullptr)
+        , nRemainingData(0)
+    {
+    }
+    SprmResult(const sal_uInt8* pInSprm, sal_Int32 nInRemainingData)
+        : pSprm(pInSprm)
+        , nRemainingData(nInRemainingData)
+    {
+    }
+};
+
 /**
     wwSprmParser knows how to take a sequence of bytes and split it up into
     sprms and their arguments
@@ -138,8 +154,7 @@ public:
 
     /// Returns the offset to data of the first sprm of id nId, 0
     //  if not found. nLen must be the <= length of pSprms
-    sal_uInt8* findSprmData(sal_uInt16 nId, sal_uInt8* pSprms, sal_uInt16 nLen)
-        const;
+    SprmResult findSprmData(sal_uInt16 nId, sal_uInt8* pSprms, sal_uInt16 nLen) const;
 };
 
 //Read a Pascal-style, i.e. single byte string length followed
@@ -267,7 +282,7 @@ public:
     explicit WW8SprmIter(const sal_uInt8* pSprms_, sal_Int32 nLen_,
         const wwSprmParser &rSprmParser);
     void  SetSprms(const sal_uInt8* pSprms_, sal_Int32 nLen_);
-    const sal_uInt8* FindSprm(sal_uInt16 nId);
+    SprmResult FindSprm(sal_uInt16 nId);
     void  advance();
     const sal_uInt8* GetSprms() const
         { return ( pSprms && (0 < nRemLen) ) ? pSprms : nullptr; }
@@ -555,8 +570,8 @@ public:
         /*
             calls GetLenAndIStdAndSprms()...
         */
-        const sal_uInt8* HasSprm( sal_uInt16 nId );
-        void HasSprm(sal_uInt16 nId, std::vector<const sal_uInt8 *> &rResult);
+        SprmResult HasSprm(sal_uInt16 nId);
+        void HasSprm(sal_uInt16 nId, std::vector<SprmResult> &rResult);
 
         const wwSprmParser &GetSprmParser() const { return maSprmParser; }
     };
@@ -604,8 +619,8 @@ public:
     virtual void advance() override;
     virtual sal_uInt16 GetIstd() const override;
     void GetPCDSprms( WW8PLCFxDesc& rDesc );
-    const sal_uInt8* HasSprm( sal_uInt16 nId );
-    bool HasSprm(sal_uInt16 nId, std::vector<const sal_uInt8 *> &rResult);
+    SprmResult HasSprm(sal_uInt16 nId);
+    bool HasSprm(sal_uInt16 nId, std::vector<SprmResult> &rResult);
     bool HasFkp() const { return (nullptr != pFkp); }
 };
 
@@ -663,12 +678,12 @@ public:
     virtual WW8_FC Where() override;
     virtual void GetSprms( WW8PLCFxDesc* p ) override;
     virtual void advance() override;
-    const sal_uInt8* HasSprm( sal_uInt16 nId ) const;
-    const sal_uInt8* HasSprm( sal_uInt16 nId, sal_uInt8 n2nd ) const;
-    const sal_uInt8* HasSprm( sal_uInt16 nId, const sal_uInt8* pOtherSprms,
+    SprmResult HasSprm( sal_uInt16 nId ) const;
+    SprmResult HasSprm( sal_uInt16 nId, sal_uInt8 n2nd ) const;
+    SprmResult HasSprm( sal_uInt16 nId, const sal_uInt8* pOtherSprms,
         long nOtherSprmSiz ) const;
     bool Find4Sprms(sal_uInt16 nId1, sal_uInt16 nId2, sal_uInt16 nId3, sal_uInt16 nId4,
-                    sal_uInt8*& p1,   sal_uInt8*& p2,   sal_uInt8*& p3,   sal_uInt8*& p4 ) const;
+                    SprmResult& r1, SprmResult& r2, SprmResult& r3, SprmResult& r4) const;
 };
 
 /// iterator for footnotes/endnotes and comments
@@ -968,11 +983,11 @@ public:
     long GetCpOfs() const { return m_pChp->nCpOfs; }  // for Header/Footer...
 
     /* asks, if *current paragraph* has an Sprm of this type */
-    const sal_uInt8* HasParaSprm( sal_uInt16 nId ) const;
+    SprmResult HasParaSprm(sal_uInt16 nId) const;
 
     /* asks, if *current textrun* has an Sprm of this type */
-    const sal_uInt8* HasCharSprm( sal_uInt16 nId ) const;
-    void HasCharSprm(sal_uInt16 nId, std::vector<const sal_uInt8 *> &rResult) const;
+    SprmResult HasCharSprm(sal_uInt16 nId) const;
+    void HasCharSprm(sal_uInt16 nId, std::vector<SprmResult> &rResult) const;
 
     WW8PLCFx_Cp_FKP* GetChpPLCF() const
         { return static_cast<WW8PLCFx_Cp_FKP*>(m_pChp->pPLCFx); }


More information about the Libreoffice-commits mailing list