editeng/qa/unit/core-test.cxx | 39 +++++++++++++++++++++++++++++++ editeng/source/editeng/editdoc.cxx | 46 +++++++++++++++++++++++-------------- editeng/source/editeng/editdoc.hxx | 5 +--- editeng/source/editeng/editobj.cxx | 5 ++++ xmloff/source/style/impastpl.cxx | 14 +++++++++++ 5 files changed, 89 insertions(+), 20 deletions(-)
New commits: commit 17fd1d8848df8fa97818b024a510bec98d8fc9d5 Author: Michael Stahl <mst...@redhat.com> Date: Mon Dec 1 19:26:09 2014 +0100 editeng: don't hide the DbgCheckAttribs() behind OSL_DEBUG_LEVEL > 2 ... and add a check for fdo#85496 too. Change-Id: I235057362bcac23fa64e79f1b47311328e01a81a diff --git a/editeng/source/editeng/editdoc.cxx b/editeng/source/editeng/editdoc.cxx index 54cdb90..15be683 100644 --- a/editeng/source/editeng/editdoc.cxx +++ b/editeng/source/editeng/editdoc.cxx @@ -1559,9 +1559,7 @@ void ContentNode::AppendAttribs( ContentNode* pNextNode ) sal_Int32 nNewStart = maString.getLength(); -#if OSL_DEBUG_LEVEL > 2 - OSL_ENSURE( aCharAttribList.DbgCheckAttribs(), "Attribute before AppendAttribs broken" ); -#endif + OSL_ENSURE( CharAttribList::DbgCheckAttribs(aCharAttribList), "Attribute before AppendAttribs broken" ); sal_Int32 nAttr = 0; CharAttribList::AttribsType& rNextAttribs = pNextNode->GetCharAttribs().GetAttribs(); @@ -1615,9 +1613,7 @@ void ContentNode::AppendAttribs( ContentNode* pNextNode ) // For the Attributes that just moved over: rNextAttribs.clear(); -#if OSL_DEBUG_LEVEL > 2 - OSL_ENSURE( aCharAttribList.DbgCheckAttribs(), "Attribute after AppendAttribs broken" ); -#endif + OSL_ENSURE( CharAttribList::DbgCheckAttribs(aCharAttribList), "Attribute after AppendAttribs broken" ); } void ContentNode::CreateDefFont() @@ -2987,11 +2983,13 @@ void CharAttribList::DeleteEmptyAttribs( SfxItemPool& rItemPool ) bHasEmptyAttribs = false; } -#if OSL_DEBUG_LEVEL > 2 -bool CharAttribList::DbgCheckAttribs() const +#if OSL_DEBUG_LEVEL > 0 +bool CharAttribList::DbgCheckAttribs(CharAttribList const& rAttribs) { bool bOK = true; - AttribsType::const_iterator it = aAttribs.begin(), itEnd = aAttribs.end(); + AttribsType::const_iterator it = rAttribs.aAttribs.begin(); + AttribsType::const_iterator itEnd = rAttribs.aAttribs.end(); + std::set<std::pair<sal_Int32, sal_uInt16>> zero_set; for (; it != itEnd; ++it) { const EditCharAttrib& rAttr = *it; @@ -3000,11 +2998,16 @@ bool CharAttribList::DbgCheckAttribs() const bOK = false; OSL_FAIL( "Attribute is distorted" ); } - else if (rAttr.IsFeature() && rAttr.GetLen() != 1) + if (rAttr.IsFeature() && rAttr.GetLen() != 1) { bOK = false; OSL_FAIL( "Feature, Len != 1" ); } + if (0 == rAttr.GetLen()) + { + // not sure if 0-length attributes allowed at all in non-empty para? + assert(zero_set.insert(std::make_pair(rAttr.GetStart(), rAttr.Which())).second && "duplicate 0-length attribute detected"); + } } return bOK; } diff --git a/editeng/source/editeng/editdoc.hxx b/editeng/source/editeng/editdoc.hxx index 612786f..7cbbd43 100644 --- a/editeng/source/editeng/editdoc.hxx +++ b/editeng/source/editeng/editdoc.hxx @@ -229,9 +229,8 @@ public: void Remove(sal_Int32 nPos); void Release(const EditCharAttrib* p); -#if OSL_DEBUG_LEVEL > 2 - // Debug: - bool DbgCheckAttribs() const; +#if OSL_DEBUG_LEVEL > 0 + static bool DbgCheckAttribs(CharAttribList const& rAttribs); #endif }; commit 7a242b463132d67a4a2d6e69319e0da367145cc0 Author: Michael Stahl <mst...@redhat.com> Date: Mon Dec 1 19:25:13 2014 +0100 fdo#85496: add some asserts to detect this sort of problem Change-Id: Iff787c8d2a71bc3082192cc98e3d916badee65dd diff --git a/editeng/source/editeng/editobj.cxx b/editeng/source/editeng/editobj.cxx index 11e1b22..bf316c7 100644 --- a/editeng/source/editeng/editobj.cxx +++ b/editeng/source/editeng/editobj.cxx @@ -992,6 +992,11 @@ void EditTextObjectImpl::GetAllSections( std::vector<editeng::Section>& rAttrs ) for (; itCurAttr != aAttrs.end() && itCurAttr->mnParagraph == nPara && itCurAttr->mnEnd <= nEnd; ++itCurAttr) { editeng::Section& rSecAttr = *itCurAttr; + // serious bug: will cause duplicate attributes to be exported + assert(rSecAttr.maAttributes.end() == std::find_if( + rSecAttr.maAttributes.begin(), rSecAttr.maAttributes.end(), + [&pItem](SfxPoolItem const*const pIt) + { return pIt->Which() == pItem->Which(); })); rSecAttr.maAttributes.push_back(pItem); } } diff --git a/xmloff/source/style/impastpl.cxx b/xmloff/source/style/impastpl.cxx index 1888407..365fd5e 100644 --- a/xmloff/source/style/impastpl.cxx +++ b/xmloff/source/style/impastpl.cxx @@ -247,6 +247,20 @@ XMLAutoStylePoolProperties::XMLAutoStylePoolProperties( XMLAutoStyleFamily& rFam } while (rFamilyData.maNameSet.find(msName) != rFamilyData.maNameSet.end()); } + +#if OSL_DEBUG_LEVEL > 0 + std::set<sal_Int32> DebugProperties; + for (size_t i = 0; i < maProperties.size(); ++i) + { + sal_Int32 const property(maProperties[i].mnIndex); + // serious bug: will cause duplicate attributes to be exported + assert(DebugProperties.find(property) == DebugProperties.end()); + if (-1 != property) + { + DebugProperties.insert(property); + } + } +#endif } bool operator<( const XMLAutoStyleFamily& r1, const XMLAutoStyleFamily& r2) commit 846b56b6b99e334dfa44f1a24640aa3158509854 Author: Michael Stahl <mst...@redhat.com> Date: Mon Dec 1 19:21:49 2014 +0100 fdo#85496: editeng: do not add multiple 0-length attributes... ... at the same position. Since commit 0d57434180db6c8eda8c5b9b704f8a1c18b371df these will be exported by the ODF filter as duplicate attributes. Change-Id: I8befe55f61c59ab968409fa03359540c300f9198 diff --git a/editeng/qa/unit/core-test.cxx b/editeng/qa/unit/core-test.cxx index 4090db4..ae4a946 100644 --- a/editeng/qa/unit/core-test.cxx +++ b/editeng/qa/unit/core-test.cxx @@ -573,6 +573,45 @@ void Test::testSectionAttributes() CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnEnd); CPPUNIT_ASSERT_MESSAGE("Attribute array should be empty.", pSecAttr->maAttributes.empty()); } + + + { + aEngine.Clear(); + aEngine.SetText("one\ntwo"); + CPPUNIT_ASSERT_EQUAL(2, aEngine.GetParagraphCount()); + + // embolden 2nd paragraph + pSet.reset(new SfxItemSet(aEngine.GetEmptyItemSet())); + pSet->Put(aBold); + aEngine.QuickSetAttribs(*pSet, ESelection(1,0,1,3)); + // disboldify 1st paragraph + SvxWeightItem aNotSoBold(WEIGHT_NORMAL, EE_CHAR_WEIGHT); + pSet->Put(aNotSoBold); + aEngine.QuickSetAttribs(*pSet, ESelection(0,0,0,3)); + + // now delete & join the paragraphs - this is fdo#85496 scenario + aEngine.QuickDelete(ESelection(0,0,1,3)); + CPPUNIT_ASSERT_EQUAL(1, aEngine.GetParagraphCount()); + + boost::scoped_ptr<EditTextObject> pEditText(aEngine.CreateTextObject()); + CPPUNIT_ASSERT_MESSAGE("Failed to create text object.", pEditText.get()); + std::vector<editeng::Section> aAttrs; + pEditText->GetAllSections(aAttrs); + + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aAttrs.size()); + + const editeng::Section* pSecAttr = &aAttrs[0]; + CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnParagraph); + CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnStart); + CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnEnd); + std::set<sal_uInt16> whiches; + for (size_t i = 0; i < pSecAttr->maAttributes.size(); ++i) + { + sal_uInt16 const nWhich(pSecAttr->maAttributes[i]->Which()); + CPPUNIT_ASSERT_MESSAGE("duplicate item in text portion attributes", + whiches.insert(nWhich).second); + } + } } CPPUNIT_TEST_SUITE_REGISTRATION(Test); diff --git a/editeng/source/editeng/editdoc.cxx b/editeng/source/editeng/editdoc.cxx index e293425..54cdb90 100644 --- a/editeng/source/editeng/editdoc.cxx +++ b/editeng/source/editeng/editdoc.cxx @@ -1579,14 +1579,23 @@ void ContentNode::AppendAttribs( ContentNode* pNextNode ) { if ( pTmpAttrib->GetEnd() == nNewStart ) { - if ( ( pTmpAttrib->Which() == pAttrib->Which() ) && - ( *(pTmpAttrib->GetItem()) == *(pAttrib->GetItem() ) ) ) + if (pTmpAttrib->Which() == pAttrib->Which()) { - pTmpAttrib->GetEnd() = - pTmpAttrib->GetEnd() + pAttrib->GetLen(); - rNextAttribs.erase(rNextAttribs.begin()+nAttr); - // Unsubscribe from the pool?! - bMelted = true; + // prevent adding 2 0-length attributes at same position + if ((*(pTmpAttrib->GetItem()) == *(pAttrib->GetItem())) + || (0 == pAttrib->GetLen())) + { + pTmpAttrib->GetEnd() = + pTmpAttrib->GetEnd() + pAttrib->GetLen(); + rNextAttribs.erase(rNextAttribs.begin()+nAttr); + // Unsubscribe from the pool?! + bMelted = true; + } + else if (0 == pTmpAttrib->GetLen()) + { + aCharAttribList.Remove(nTmpAttr); + --nTmpAttr; // to cancel later increment... + } } } ++nTmpAttr; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits