Kaydet (Commit) b9bc4570 authored tarafından Armin Le Grand's avatar Armin Le Grand

Make EscherPropertyContainer::CreatePolygonProperties safer

Additionally adapted EscherPropertyContainer's AddOpt
methods to be more safe and flexible. Added support for
SvMemoryStream. Changed Data handling in EscherPropSortStruct
to use std::vector<sal_uInt8>, adapted all usages and
converions throgh all modules. This makes memorty handling
for these parts much safer (no more local new-ops, no
longer delete[] there).
Currently there are quite some usages of nProp.size() and
&nProp[0] to access the data. but the base for further
changes to work more on std::vector is done.

Change-Id: I982225c5bfc06fdd9e195d18cd3c550d15f1d48d
Reviewed-on: https://gerrit.libreoffice.org/57061
Tested-by: Jenkins
Reviewed-by: 's avatarArmin Le Grand <Armin.Le.Grand@cib.de>
üst 3bc3ddc1
......@@ -243,10 +243,7 @@ sal_uInt32 ImplEESdrWriter::ImplWriteShape( ImplEESdrObject& rObj,
const std::unique_ptr< SvMemoryStream >& pMemStrm = pInteraction->getHyperlinkRecord();
if ( pMemStrm.get() )
{
pMemStrm->ObjectOwnsMemory( false );
sal_uInt8 const * pBuf = static_cast<sal_uInt8 const *>(pMemStrm->GetData());
sal_uInt32 nSize = pMemStrm->Seek( STREAM_SEEK_TO_END );
aPropOpt.AddOpt( ESCHER_Prop_pihlShape, false, nSize, const_cast<sal_uInt8 *>(pBuf), nSize );
aPropOpt.AddOpt(ESCHER_Prop_pihlShape, false, 0, *pMemStrm.get());
}
aPropOpt.AddOpt( ESCHER_Prop_fPrint, 0x00080008 );
}
......
......@@ -656,8 +656,7 @@ class SdrObjCustomShape;
struct EscherPropSortStruct
{
sal_uInt8* pBuf;
sal_uInt32 nPropSize;
std::vector<sal_uInt8> nProp;
sal_uInt32 nPropValue;
sal_uInt16 nPropId;
};
......@@ -703,21 +702,26 @@ public:
// GraphicObjects are saved to PowerPoint
~EscherPropertyContainer();
void AddOpt( sal_uInt16 nPropertyID, const OUString& rString );
void AddOpt(
sal_uInt16 nPropertyID,
sal_uInt32 nPropValue,
bool bBlib = false
);
void AddOpt(
sal_uInt16 nPropertyID,
bool bBlib,
sal_uInt32 nPropValue,
sal_uInt8* pProp,
sal_uInt32 nPropSize
);
void AddOpt(
sal_uInt16 nPropID,
bool bBlib,
sal_uInt32 nSizeReduction,
SvMemoryStream& rStream);
void AddOpt(
sal_uInt16 nPropertyID,
const OUString& rString);
void AddOpt(
sal_uInt16 nPropertyID,
sal_uInt32 nPropValue,
bool bBlib = false);
void AddOpt(
sal_uInt16 nPropertyID,
bool bBlib,
sal_uInt32 nPropValue,
const std::vector<sal_uInt8>& rProp);
bool GetOpt( sal_uInt16 nPropertyID, sal_uInt32& rPropValue ) const;
......
......@@ -494,11 +494,11 @@ void VMLExport::Commit( EscherPropertyContainer& rProps, const tools::Rectangle&
if ( rProps.GetOpt( ESCHER_Prop_pVertices, aVertices ) &&
rProps.GetOpt( ESCHER_Prop_pSegmentInfo, aSegments ) )
{
const sal_uInt8 *pVerticesIt = aVertices.pBuf + 6;
const sal_uInt8 *pSegmentIt = aSegments.pBuf;
const sal_uInt8 *pVerticesIt = &aVertices.nProp[0] + 6;
const sal_uInt8 *pSegmentIt = &aSegments.nProp[0];
OStringBuffer aPath( 512 );
sal_uInt16 nPointSize = aVertices.pBuf[4] + ( aVertices.pBuf[5] << 8 );
sal_uInt16 nPointSize = aVertices.nProp[4] + ( aVertices.nProp[5] << 8 );
// number of segments
sal_uInt16 nSegments = impl_GetUInt16( pSegmentIt );
......@@ -685,8 +685,8 @@ void VMLExport::Commit( EscherPropertyContainer& rProps, const tools::Rectangle&
SvMemoryStream aStream;
// The first bytes are WW8-specific, we're only interested in the PNG
int nHeaderSize = 25;
aStream.WriteBytes(aStruct.pBuf + nHeaderSize,
aStruct.nPropSize - nHeaderSize);
aStream.WriteBytes(&aStruct.nProp[0] + nHeaderSize,
aStruct.nProp.size() - nHeaderSize);
aStream.Seek(0);
Graphic aGraphic;
GraphicConverter::Import(aStream, aGraphic);
......@@ -895,9 +895,14 @@ void VMLExport::Commit( EscherPropertyContainer& rProps, const tools::Rectangle&
if (rProps.GetOpt(ESCHER_Prop_gtextUNICODE, aUnicode))
{
SvMemoryStream aStream;
aStream.WriteBytes(opt.pBuf, opt.nPropSize);
if(!opt.nProp.empty())
{
aStream.WriteBytes(&opt.nProp[0], opt.nProp.size());
}
aStream.Seek(0);
OUString aTextPathString = SvxMSDffManager::MSDFFReadZString(aStream, opt.nPropSize, true);
OUString aTextPathString = SvxMSDffManager::MSDFFReadZString(aStream, opt.nProp.size(), true);
aStream.Seek(0);
m_pSerializer->singleElementNS( XML_v, XML_path,
......@@ -912,9 +917,9 @@ void VMLExport::Commit( EscherPropertyContainer& rProps, const tools::Rectangle&
OUString aStyle;
if (rProps.GetOpt(ESCHER_Prop_gtextFont, aFont))
{
aStream.WriteBytes(aFont.pBuf, aFont.nPropSize);
aStream.WriteBytes(&aFont.nProp[0], aFont.nProp.size());
aStream.Seek(0);
OUString aTextPathFont = SvxMSDffManager::MSDFFReadZString(aStream, aFont.nPropSize, true);
OUString aTextPathFont = SvxMSDffManager::MSDFFReadZString(aStream, aFont.nProp.size(), true);
aStyle += "font-family:\"" + aTextPathFont + "\"";
}
sal_uInt32 nSize;
......@@ -953,9 +958,14 @@ void VMLExport::Commit( EscherPropertyContainer& rProps, const tools::Rectangle&
case ESCHER_Prop_wzName:
{
SvMemoryStream aStream;
aStream.WriteBytes(opt.pBuf, opt.nPropSize);
if(!opt.nProp.empty())
{
aStream.WriteBytes(&opt.nProp[0], opt.nProp.size());
}
aStream.Seek(0);
OUString idStr = SvxMSDffManager::MSDFFReadZString(aStream, opt.nPropSize, true);
OUString idStr = SvxMSDffManager::MSDFFReadZString(aStream, opt.nProp.size(), true);
aStream.Seek(0);
if (!IsWaterMarkShape(m_pSdrObject->GetName()) && !m_bSkipwzName)
m_pShapeAttrList->add(XML_ID, OUStringToOString(idStr, RTL_TEXTENCODING_UTF8).getStr());
......@@ -965,13 +975,18 @@ void VMLExport::Commit( EscherPropertyContainer& rProps, const tools::Rectangle&
break;
default:
#if OSL_DEBUG_LEVEL > 0
const size_t opt_nProp_size(opt.nProp.size());
const sal_uInt8 opt_nProp_empty(0);
fprintf( stderr, "TODO VMLExport::Commit(), unimplemented id: %d, value: %" SAL_PRIuUINT32 ", data: [%" SAL_PRIuUINT32 ", %p]\n",
nId, opt.nPropValue, opt.nPropSize, opt.pBuf );
if ( opt.nPropSize )
nId,
opt.nPropValue,
static_cast<unsigned int>(opt_nProp_size),
0 == opt_nProp_size ? &opt_nProp_empty : &opt.nProp[0]);
if ( opt.nProp.size() )
{
const sal_uInt8 *pIt = opt.pBuf;
const sal_uInt8 *pIt = &opt.nProp[0];
fprintf( stderr, " ( " );
for ( int nCount = opt.nPropSize; nCount; --nCount )
for ( int nCount = opt.nProp.size(); nCount; --nCount )
{
fprintf( stderr, "%02x ", *pIt );
++pIt;
......
......@@ -2054,19 +2054,7 @@ void PPTWriter::ImplWritePage( const PHLayout& rLayout, EscherSolverContainer& a
if ( !aControlName.isEmpty() )
{
sal_uInt16 nBufSize;
nBufSize = ( aControlName.getLength() + 1 ) << 1;
sal_uInt8* pBuf = new sal_uInt8[ nBufSize ];
sal_uInt8* pTmp = pBuf;
for ( sal_Int32 i = 0; i < aControlName.getLength(); i++ )
{
sal_Unicode nUnicode = aControlName[i];
*pTmp++ = static_cast<sal_uInt8>(nUnicode);
*pTmp++ = static_cast<sal_uInt8>( nUnicode >> 8 );
}
*pTmp++ = 0;
*pTmp = 0;
aPropOpt.AddOpt( ESCHER_Prop_wzName, true, nBufSize, pBuf, nBufSize );
aPropOpt.AddOpt(ESCHER_Prop_wzName, aControlName);
}
}
else if ( mType == "drawing.Connector" )
......@@ -3140,7 +3128,6 @@ void PPTWriter::ImplCreateTable( uno::Reference< drawing::XShape > const & rXSha
EscherPropertyContainer aPropOpt2;
SvMemoryStream aMemStrm;
aMemStrm.ObjectOwnsMemory( false );
aMemStrm.WriteUInt16( nRowCount )
.WriteUInt16( nRowCount )
.WriteUInt16( 4 );
......@@ -3151,7 +3138,7 @@ void PPTWriter::ImplCreateTable( uno::Reference< drawing::XShape > const & rXSha
aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x1000100 );
aPropOpt2.AddOpt( ESCHER_Prop_tableProperties, 1 );
aPropOpt2.AddOpt( ESCHER_Prop_tableRowProperties, true, aMemStrm.Tell(), static_cast< sal_uInt8* >( const_cast< void* >( aMemStrm.GetData() ) ), aMemStrm.Tell() );
aPropOpt2.AddOpt(ESCHER_Prop_tableRowProperties, true, 0, aMemStrm);
aPropOpt.CreateShapeProperties( rXShape );
aPropOpt.Commit( *mpStrm );
aPropOpt2.Commit( *mpStrm, 3, ESCHER_UDefProp );
......
......@@ -270,16 +270,16 @@ void RtfSdrExport::Commit(EscherPropertyContainer& rProps, const tools::Rectangl
if (rProps.GetOpt(ESCHER_Prop_pVertices, aVertices)
&& rProps.GetOpt(ESCHER_Prop_pSegmentInfo, aSegments)
&& aVertices.nPropSize >= 6 && aSegments.nPropSize >= 6)
&& aVertices.nProp.size() >= 6 && aSegments.nProp.size() >= 6)
{
const sal_uInt8* pVerticesIt = aVertices.pBuf + 6;
const sal_uInt8* pVerticesIt = &aVertices.nProp[0] + 6;
std::size_t nVerticesPos = 6;
const sal_uInt8* pSegmentIt = aSegments.pBuf;
const sal_uInt8* pSegmentIt = &aSegments.nProp[0];
OStringBuffer aSegmentInfo(512);
OStringBuffer aVerticies(512);
sal_uInt16 nPointSize = aVertices.pBuf[4] + (aVertices.pBuf[5] << 8);
sal_uInt16 nPointSize = aVertices.nProp[4] + (aVertices.nProp[5] << 8);
// number of segments
sal_uInt16 nSegments = impl_GetUInt16(pSegmentIt);
......@@ -432,8 +432,8 @@ void RtfSdrExport::Commit(EscherPropertyContainer& rProps, const tools::Rectangl
.append(SAL_NEWLINE_STRING);
int nHeaderSize
= 25; // The first bytes are WW8-specific, we're only interested in the PNG
aBuf.append(msfilter::rtfutil::WriteHex(rOpt.pBuf + nHeaderSize,
rOpt.nPropSize - nHeaderSize));
aBuf.append(msfilter::rtfutil::WriteHex(&rOpt.nProp[0] + nHeaderSize,
rOpt.nProp.size() - nHeaderSize));
aBuf.append('}');
m_aShapeProps.insert(
std::pair<OString, OString>("fillBlip", aBuf.makeStringAndClear()));
......
......@@ -291,11 +291,9 @@ void SwBasicEscherEx::PreWriteHyperlinkWithinFly(const SwFrameFormat& rFormat,Es
const SwFormatURL *pINetFormat = dynamic_cast<const SwFormatURL*>(pItem);
if (pINetFormat && !pINetFormat->GetURL().isEmpty())
{
SvMemoryStream *rStrm = new SvMemoryStream ;
WriteHyperlinkWithinFly( *rStrm, pINetFormat );
sal_uInt8 const * pBuf = static_cast<sal_uInt8 const *>(rStrm->GetData());
sal_uInt32 nSize = rStrm->Seek( STREAM_SEEK_TO_END );
rPropOpt.AddOpt( ESCHER_Prop_pihlShape, true, nSize, const_cast<sal_uInt8 *>(pBuf), nSize );
SvMemoryStream aStrm;
WriteHyperlinkWithinFly( aStrm, pINetFormat );
rPropOpt.AddOpt(ESCHER_Prop_pihlShape, true, 0, aStrm);
sal_uInt32 nValue;
OUString aNamestr = pINetFormat->GetName();
if (!aNamestr.isEmpty())
......@@ -1634,11 +1632,7 @@ sal_Int32 SwBasicEscherEx::WriteGrfFlyFrame(const SwFrameFormat& rFormat, sal_uI
SwWW8Writer::InsAsString16( aBuf, sURL );
SwWW8Writer::InsUInt16( aBuf, 0 );
sal_uInt16 nArrLen = aBuf.size();
sal_uInt8* pArr = new sal_uInt8[ nArrLen ];
std::copy( aBuf.begin(), aBuf.end(), pArr);
aPropOpt.AddOpt(ESCHER_Prop_pibName, true, nArrLen, pArr, nArrLen);
aPropOpt.AddOpt(ESCHER_Prop_pibName, true, aBuf.size(), aBuf);
nFlags = ESCHER_BlipFlagLinkToFile | ESCHER_BlipFlagURL |
ESCHER_BlipFlagDoNotSave;
}
......@@ -2145,12 +2139,7 @@ sal_Int32 SwEscherEx::WriteFlyFrameAttr(const SwFrameFormat& rFormat, MSO_SPT eS
aPolyDump.WriteUInt32( aPoly[nI].Y() );
}
sal_uInt16 nArrLen = msword_cast<sal_uInt16>(aPolyDump.Tell());
void *pArr = const_cast<void *>(aPolyDump.GetData());
//PropOpt wants to own the buffer
aPolyDump.ObjectOwnsMemory(false);
rPropOpt.AddOpt(DFF_Prop_pWrapPolygonVertices, false,
nArrLen, static_cast<sal_uInt8 *>(pArr), nArrLen);
rPropOpt.AddOpt(DFF_Prop_pWrapPolygonVertices, false, 0, aPolyDump);
}
}
}
......
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