tdf#163064: pic element is required here, after all

In commit cf15306ccf (ERROR: Invalid
content was found starting with element 'p:pic'., 2014-12-22), the
pic element inside the oleObj element was only alloswed for the old
revision of ECMA-736 export, because that was considered invalid by
officeotron. However, as of ECMA-376-1:2016,  this element is
mandatory; CT_OleObject definition in Annex A has:

 <xsd:element name="pic" type="CT_Picture" minOccurs="1" maxOccurs="1"/>

and Annex L (Primer) has L.7.2.5 "Embeddings in a PresentationML
Document" saying:

 The oleObj element shall have a pic child element that (optionally)
 contains the image data to be used in place of loading the actual
 object data.

The omission of this in the export is the reason of tdf#163064. So
here I filter out the error from the validation results, which is
not ideal (I have no way to know if the found pic is really in the
oleObj, or somewhere else), but a lesser evil, compared to required
exclusion of all tests that export OLE objects.

Change-Id: Ia73a49da7347e8ff22c626e211b55ba1e0625070
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173761
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Tested-by: Jenkins
Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173809
This commit is contained in:
Mike Kaganski 2024-09-21 18:41:17 +05:00 committed by Xisco Fauli
parent 3c353fd997
commit 47a10b6dba
3 changed files with 63 additions and 11 deletions

View file

@ -2828,15 +2828,12 @@ ShapeExport& ShapeExport::WriteOLE2Shape( const Reference< XShape >& xShape )
// pic element
SdrObject* pSdrOLE2(SdrObject::getSdrObjectFromXShape(xShape));
// The spec doesn't allow <p:pic> here, but PowerPoint requires it.
bool const bEcma = mpFB->getVersion() == oox::core::ECMA_376_1ST_EDITION;
if (bEcma)
if (auto pOle2Obj = dynamic_cast<SdrOle2Obj*>(pSdrOLE2))
{
const Graphic* pGraphic = pOle2Obj->GetGraphic();
if (pGraphic)
WriteGraphicObjectShapePart( xShape, pGraphic );
}
if (auto pOle2Obj = dynamic_cast<SdrOle2Obj*>(pSdrOLE2))
{
const Graphic* pGraphic = pOle2Obj->GetGraphic();
if (pGraphic)
WriteGraphicObjectShapePart(xShape, pGraphic);
}
mpFS->endElementNS( mnXmlNamespace, XML_oleObj );

View file

@ -726,6 +726,7 @@ CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest4, testTdf143222_embeddedWorksheet)
pGraphic = pOleObj->GetGraphic();
CPPUNIT_ASSERT_MESSAGE("no graphic after the export", pGraphic != nullptr);
CPPUNIT_ASSERT_MESSAGE("no graphic after the export", !pGraphic->IsNone());
}
CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest4, testTdf143315)

View file

@ -140,6 +140,59 @@ OString loadFile(const OUString& rURL)
return aContent;
}
constexpr std::u16string_view grand_total = u"Grand total of errors in submitted package: ";
OUString filterOut(const OUString& s, std::u16string_view excludedSubstr)
{
OUString result = s;
for (;;)
{
sal_Int32 pos = result.indexOf(excludedSubstr);
if (pos < 0)
break;
sal_Int32 start = result.lastIndexOf('\n', pos);
if (!result.match("ERROR", start + 1))
return s; // unexpected string format
sal_Int32 end = result.indexOf('\n', pos);
result = result.replaceAt(start, end - start, u"");
pos = result.lastIndexOf(grand_total);
if (pos < 0)
return s; // unexpected string format
start = end = pos + grand_total.size();
while (end < result.getLength() && rtl::isAsciiDigit(result[end]))
++end;
std::u16string_view aNumber = result.subView(start, end - start);
sal_Int32 nErrors = o3tl::toInt32(aNumber) - 1;
result = result.replaceAt(start, end - start, OUString::number(nErrors));
}
return result;
}
OUString filterValidationResults(const OUString& s)
{
OUString result = s;
// In ECMA-376-1 Second Edition, 2008, there is the following restriction for oleObj:
//
// <xsd:choice minOccurs="1" maxOccurs="1">
// <xsd:element name="embed" type="CT_OleObjectEmbed"/>
// <xsd:element name="link" type="CT_OleObjectLink"/>
// <xsd:element name="pic" type="CT_Picture"/>
// </xsd:choice>
//
// This makes simultaneous use of embed (or link) and pic impossible. This was obviously a
// mistake; and the following editions of standard fixed it: e.g., in ECMA-376-1:2016, that
// rule is
//
// <xsd:choice minOccurs="1" maxOccurs="1">
// <xsd:element name="embed" type="CT_OleObjectEmbed"/>
// <xsd:element name="link" type="CT_OleObjectLink"/>
// </xsd:choice>
// <xsd:element name="pic" type="CT_Picture" minOccurs="1" maxOccurs="1"/>
//
// But officeotron only knows the old version...
result = filterOut(result, u"Invalid content was found starting with element 'p:pic'. No child element is expected at this point.");
return result;
}
}
#endif
@ -215,15 +268,16 @@ void test::BootstrapFixture::validate(const OUString& rPath, test::ValidationFor
if( eFormat == test::OOXML && !aContentOUString.isEmpty() )
{
aContentOUString = filterValidationResults(aContentOUString);
// check for validation errors here
sal_Int32 nIndex = aContentOUString.lastIndexOf("Grand total of errors in submitted package: ");
sal_Int32 nIndex = aContentOUString.lastIndexOf(grand_total);
if(nIndex == -1)
{
SAL_WARN("test", "no summary line");
}
else
{
sal_Int32 nStartOfNumber = nIndex + std::strlen("Grand total of errors in submitted package: ");
sal_Int32 nStartOfNumber = nIndex + grand_total.size();
std::u16string_view aNumber = aContentOUString.subView(nStartOfNumber);
sal_Int32 nErrors = o3tl::toInt32(aNumber);
OString aMsg = "validation error in OOXML export: Errors: " + OString::number(nErrors);