consistently track amount of buffers remaining

Change-Id: Ib9746a045edf2146b8cc3bd69124ab74462df094
Reviewed-on: https://gerrit.libreoffice.org/36405
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index 831082c..93bcea4 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 95481dc..9c3d471 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 f9252ad..6e488a1 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 3e9b6db..f2c9807 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 b033133..bb1287f 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 a34427f..b090f15 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 493c18b..3c254f9 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 339350f..ae0b67c 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 66d2da1..f63e461 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 d2e96bb..ab1fef0 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); }