Kaydet (Commit) f7bcaa98 authored tarafından Yogesh Bharate's avatar Yogesh Bharate Kaydeden (comit) Miklos Vajna

fdo#78957 Corruption - <wp:extent> "cy" height exceed the limit in header.xml

Problem Description:

1. On 19th  May windows daily build
[Build ID: dd0f8447, TinderBox: Win-x86@42, Branch:master],
if we RT document, RT get corrupted due to the exceeding the limit of extend height & width.
2. As per ECMA standard, extend height & width is of type long, but MSO only
support int32.Hence added code changes to check the same.
3. On 20th May windows daily build
[Build ID: f3a46244, TinderBox: Win-x86@42, Branch:master],
if we RT document, it get corrupted due to exceeding value of posOffset.
4. Added code changes to make sure posOffset value is within the allowed range.

Reviewed on:
	https://gerrit.libreoffice.org/9424

Change-Id: Ib0b55314f54c51f39a492485992356f71eb062e3
üst e93f4d9e
......@@ -3498,6 +3498,21 @@ DECLARE_OOXMLEXPORT_TEST(testFdo78910, "fdo78910.docx")
assertXPath ( pXmlDoc, "//w:hyperlink[2]/w:r[5]/w:fldChar", "fldCharType", "end" );
}
DECLARE_OOXMLEXPORT_TEST(testFdo78957, "fdo78957.docx")
{
xmlDocPtr pXmlHeader = parseExport("word/header2.xml");
if(!pXmlHeader)
return;
const sal_Int64 IntMax = 2147483647;
sal_Int64 cx = 0, cy = 0;
cx = getXPath(pXmlHeader,"/w:hdr[1]/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/wp:extent[1]","cx").toInt64();
cy = getXPath(pXmlHeader,"/w:hdr[1]/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/wp:extent[1]","cy").toInt64();
// Here we check the values of extent width & height
CPPUNIT_ASSERT(cx <= IntMax );
CPPUNIT_ASSERT(cy >= 0 );
}
#endif
CPPUNIT_PLUGIN_IMPLEMENT();
......
......@@ -44,7 +44,6 @@
#include <writerhelper.hxx>
#include <comphelper/seqstream.hxx>
#include <climits>
using namespace com::sun::star;
using namespace oox;
......@@ -426,6 +425,13 @@ void DocxSdrExport::startDMLAnchorInline(const SwFrmFmt* pFrmFmt, const Size& rS
break;
}
m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_positionH, XML_relativeFrom, relativeFromH, FSEND);
/**
* Sizes of integral types
* climits header defines constants with the limits of integral types for the specific system and compiler implemetation used.
* Use of this might cause platform dependent problem like posOffset exceed the limit.
**/
const sal_Int64 MAX_INTEGER_VALUE = 2147483647;
const sal_Int64 MIN_INTEGER_VALUE = -2147483648;
if (alignH != NULL)
{
m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_align, FSEND);
......@@ -447,13 +453,14 @@ void DocxSdrExport::startDMLAnchorInline(const SwFrmFmt* pFrmFmt, const Size& rS
*
* Please refer : http://www.schemacentral.com/sc/xsd/t-xsd_int.html
*/
if (nTwipstoEMU > INT_MAX)
if (nTwipstoEMU > MAX_INTEGER_VALUE)
{
nTwipstoEMU = INT_MAX;
nTwipstoEMU = MAX_INTEGER_VALUE;
}
else if (nTwipstoEMU < INT_MIN)
else if (nTwipstoEMU < MIN_INTEGER_VALUE)
{
nTwipstoEMU = INT_MIN;
nTwipstoEMU = MIN_INTEGER_VALUE;
}
m_pImpl->m_pSerializer->write(nTwipstoEMU);
m_pImpl->m_pSerializer->endElementNS(XML_wp, XML_posOffset);
......@@ -470,13 +477,13 @@ void DocxSdrExport::startDMLAnchorInline(const SwFrmFmt* pFrmFmt, const Size& rS
{
m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_posOffset, FSEND);
sal_Int64 nTwipstoEMU = TwipsToEMU(aPos.Y);
if (nTwipstoEMU > INT_MAX)
if (nTwipstoEMU > MAX_INTEGER_VALUE)
{
nTwipstoEMU = INT_MAX;
nTwipstoEMU = MAX_INTEGER_VALUE;
}
else if (nTwipstoEMU < INT_MIN)
else if (nTwipstoEMU < MIN_INTEGER_VALUE)
{
nTwipstoEMU = INT_MIN;
nTwipstoEMU = MIN_INTEGER_VALUE;
}
m_pImpl->m_pSerializer->write(nTwipstoEMU);
m_pImpl->m_pSerializer->endElementNS(XML_wp, XML_posOffset);
......@@ -502,11 +509,49 @@ void DocxSdrExport::startDMLAnchorInline(const SwFrmFmt* pFrmFmt, const Size& rS
// now the common parts
// extent of the image
OString aWidth(OString::number(TwipsToEMU(rSize.Width())));
OString aHeight(OString::number(TwipsToEMU(rSize.Height())));
/**
* Extent width is of type long ( i.e cx & cy ) as
*
* per ECMA-376, Second Edition, Part 1 - Fundamentals And Markup Language Reference
* [ 20.4.2.7 extent (Drawing Object Size)]
*
* cy is of type a:ST_PositiveCoordinate.
* Minimum inclusive: 0
* Maximum inclusive: 27273042316900
*
* reference : http://www.schemacentral.com/sc/ooxml/e-wp_extent-1.html
*
* Though ECMA mentions the max value as aforementioned. It appears that MSO does not
* handle for the same, infact it acutally can handles a max value of int32 i.e
* 2147483647( MAX_INTEGER_VALUE ).
* Therefore changing the following accordingly so that LO sync's up with MSO.
**/
sal_uInt64 cx = 0 ;
sal_uInt64 cy = 0 ;
const sal_Int64 MAX_INTEGER_VALUE = 2147483647;
if (rSize.Width() > MAX_INTEGER_VALUE)
cx = MAX_INTEGER_VALUE ;
else if (0 > rSize.Width())
cx = 0 ;
else
cx = rSize.Width();
if (rSize.Height() > MAX_INTEGER_VALUE)
cy = MAX_INTEGER_VALUE ;
else if (0 > rSize.Height())
cy = 0 ;
else
cy = rSize.Height();
OString aWidth(OString::number(TwipsToEMU(cx)));
//we explicitly check the converted EMU value for the range as mentioned in above comment.
aWidth = (aWidth.toInt64() > 0 ? (aWidth.toInt64() > MAX_INTEGER_VALUE ? I64S(MAX_INTEGER_VALUE) : aWidth.getStr()): "0");
OString aHeight(OString::number(TwipsToEMU(cy)));
aHeight = (aHeight.toInt64() > 0 ? (aHeight.toInt64() > MAX_INTEGER_VALUE ? I64S(MAX_INTEGER_VALUE) : aHeight.getStr()): "0");
m_pImpl->m_pSerializer->singleElementNS(XML_wp, XML_extent,
XML_cx, (rSize.Width() > 0 ? aWidth.getStr() : "0"),
XML_cy, (rSize.Height() > 0 ? aHeight.getStr() : "0"),
XML_cx, aWidth,
XML_cy, aHeight,
FSEND);
// effectExtent, extent including the effect (shadow only for now)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment