Kaydet (Commit) b8a4abdd authored tarafından sushil_shinde's avatar sushil_shinde Kaydeden (comit) Miklos Vajna

[docx] activeX reference files (.bin) saved in InteropGrabBag and exported.

  The XInputStream for activeX.bin files is stored as the PropertyValue
  "OOXActiveXBin" into the "InteropGraBag"

  Added mxActiveXBinList object which holds XInputStreams for each
  activeX.bin from activeX folder.

  Added .bin files entry to respective acivex.xml's .rels file.

  Added Unit Test to test all .bin files are stores properly.

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

Change-Id: I3a0e9462a6cc53d8cbb9c7d59ed24631d77d4d30
üst 9fbdb2b8
...@@ -1617,6 +1617,34 @@ DECLARE_OOXML_TEST(testActiveXGrabBag, "activex.docx") ...@@ -1617,6 +1617,34 @@ DECLARE_OOXML_TEST(testActiveXGrabBag, "activex.docx")
CPPUNIT_ASSERT(bActiveX); // Grab Bag has all the expected elements CPPUNIT_ASSERT(bActiveX); // Grab Bag has all the expected elements
} }
DECLARE_OOXML_TEST(testActiveXBinGrabBag, "activexbin.docx")
{
// The problem was that activeX.bin files were missing from docx file after saving file.
// This test case tests whether activex bin files grabbagged properly in correct object.
uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
uno::Reference<beans::XPropertySet> xTextDocumentPropertySet(xTextDocument, uno::UNO_QUERY);
uno::Sequence<beans::PropertyValue> aGrabBag(0);
xTextDocumentPropertySet->getPropertyValue(OUString("InteropGrabBag")) >>= aGrabBag;
CPPUNIT_ASSERT(aGrabBag.hasElements()); // Grab Bag not empty
bool bActiveX = sal_False;
for(int i = 0; i < aGrabBag.getLength(); ++i)
{
if (aGrabBag[i].Name == "OOXActiveXBin")
{
bActiveX = sal_True;
uno::Reference<io::XInputStream> aActiveXBin;
uno::Sequence<uno::Reference<io::XInputStream> > aActiveXBinList;
CPPUNIT_ASSERT(aGrabBag[i].Value >>= aActiveXBinList); // PropertyValue of proper type
sal_Int32 length = aActiveXBinList.getLength();
CPPUNIT_ASSERT_EQUAL(sal_Int32(5), length);
aActiveXBin = aActiveXBinList[0];
CPPUNIT_ASSERT(aActiveXBin.get()); // Reference not empty
}
}
CPPUNIT_ASSERT(bActiveX); // Grab Bag has all the expected elements
}
DECLARE_OOXML_TEST(testFdo69644, "fdo69644.docx") DECLARE_OOXML_TEST(testFdo69644, "fdo69644.docx")
{ {
// The problem was that the exporter exported the table definition // The problem was that the exporter exported the table definition
......
...@@ -867,6 +867,7 @@ void DocxExport::WriteActiveX() ...@@ -867,6 +867,7 @@ void DocxExport::WriteActiveX()
return; return;
uno::Sequence<uno::Reference<xml::dom::XDocument> > activeXDomlist; uno::Sequence<uno::Reference<xml::dom::XDocument> > activeXDomlist;
uno::Sequence<uno::Reference<io::XInputStream> > activeXBinList;
uno::Sequence< beans::PropertyValue > propList; uno::Sequence< beans::PropertyValue > propList;
xPropSet->getPropertyValue( pName ) >>= propList; xPropSet->getPropertyValue( pName ) >>= propList;
for ( sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp ) for ( sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp )
...@@ -879,9 +880,20 @@ void DocxExport::WriteActiveX() ...@@ -879,9 +880,20 @@ void DocxExport::WriteActiveX()
} }
} }
for ( sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp )
{
OUString propName = propList[nProp].Name;
if ( propName == "OOXActiveXBin" )
{
propList[nProp].Value >>= activeXBinList;
break;
}
}
for (sal_Int32 j = 0; j < activeXDomlist.getLength(); j++) for (sal_Int32 j = 0; j < activeXDomlist.getLength(); j++)
{ {
uno::Reference<xml::dom::XDocument> activeXDom = activeXDomlist[j]; uno::Reference<xml::dom::XDocument> activeXDom = activeXDomlist[j];
uno::Reference<io::XInputStream> activeXBin = activeXBinList[j];
if ( activeXDom.is() ) if ( activeXDom.is() )
{ {
...@@ -895,7 +907,47 @@ void DocxExport::WriteActiveX() ...@@ -895,7 +907,47 @@ void DocxExport::WriteActiveX()
"application/vnd.ms-office.activeX+xml" ) ); "application/vnd.ms-office.activeX+xml" ) );
serializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( writer, uno::UNO_QUERY_THROW ), serializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( writer, uno::UNO_QUERY_THROW ),
uno::Sequence< beans::StringPair >() ); uno::Sequence< beans::StringPair >() );
} }
if ( activeXBin.is() )
{
uno::Reference< io::XOutputStream > xOutStream = GetFilter().openFragmentStream("word/activeX/activeX"+OUString::number((j+1))+".bin",
"application/vnd.ms-office.activeX");
try
{
sal_Int32 nBufferSize = 512;
uno::Sequence< sal_Int8 > aDataBuffer(nBufferSize);
sal_Int32 nRead;
do
{
nRead = activeXBin->readBytes( aDataBuffer, nBufferSize );
if( nRead )
{
if( nRead < nBufferSize )
{
nBufferSize = nRead;
aDataBuffer.realloc(nRead);
}
xOutStream->writeBytes( aDataBuffer );
}
}
while( nRead );
xOutStream->flush();
}
catch(const uno::Exception&)
{
SAL_WARN("sw.ww8", "WriteActiveX() ::Failed to copy Inputstream to outputstream exception catched!");
}
xOutStream->closeOutput();
// Adding itemprops's relationship entry to item.xml.rels file
m_pFilter->addRelation( GetFilter().openFragmentStream( "/word/activeX/activeX"+OUString::number((j+1))+".xml",
"application/vnd.ms-office.activeX+xml" ) ,
"http://schemas.microsoft.com/office/2006/relationships/activeXControlBinary",
"activeX"+OUString::number((j+1))+".bin" );
}
} }
} }
......
...@@ -76,7 +76,7 @@ class WRITERFILTER_OOXML_DLLPUBLIC OOXMLStream ...@@ -76,7 +76,7 @@ class WRITERFILTER_OOXML_DLLPUBLIC OOXMLStream
{ {
public: public:
enum StreamType_t { UNKNOWN, DOCUMENT, STYLES, FONTTABLE, NUMBERING, enum StreamType_t { UNKNOWN, DOCUMENT, STYLES, FONTTABLE, NUMBERING,
FOOTNOTES, ENDNOTES, COMMENTS, THEME, CUSTOMXML, CUSTOMXMLPROPS, ACTIVEX, SETTINGS, VBAPROJECT }; FOOTNOTES, ENDNOTES, COMMENTS, THEME, CUSTOMXML, CUSTOMXMLPROPS, ACTIVEX, ACTIVEXBIN, SETTINGS, VBAPROJECT };
typedef boost::shared_ptr<OOXMLStream> Pointer_t; typedef boost::shared_ptr<OOXMLStream> Pointer_t;
virtual ~OOXMLStream() {} virtual ~OOXMLStream() {}
...@@ -245,6 +245,7 @@ public: ...@@ -245,6 +245,7 @@ public:
virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getCustomXmlDomList( ) = 0; virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getCustomXmlDomList( ) = 0;
virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getCustomXmlDomPropsList( ) = 0; virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getCustomXmlDomPropsList( ) = 0;
virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getActiveXDomList( ) = 0; virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getActiveXDomList( ) = 0;
virtual uno::Sequence<uno::Reference<io::XInputStream> > getActiveXBinList() = 0;
}; };
......
...@@ -203,11 +203,15 @@ sal_Bool WriterFilter::filter( const uno::Sequence< beans::PropertyValue >& aDes ...@@ -203,11 +203,15 @@ sal_Bool WriterFilter::filter( const uno::Sequence< beans::PropertyValue >& aDes
// We want to keep the previous items // We want to keep the previous items
xDocProps->getPropertyValue( aGrabBagPropName ) >>= aGrabBag; xDocProps->getPropertyValue( aGrabBagPropName ) >>= aGrabBag;
sal_Int32 length = aGrabBag.getLength(); sal_Int32 length = aGrabBag.getLength();
aGrabBag.realloc(length+1); aGrabBag.realloc(length+2);
beans::PropertyValue* pValue = aGrabBag.getArray(); beans::PropertyValue* pValue = aGrabBag.getArray();
pValue[length].Name = "OOXActiveX"; pValue[length].Name = "OOXActiveX";
pValue[length].Value = uno::makeAny( pDocument->getActiveXDomList() ); pValue[length].Value = uno::makeAny( pDocument->getActiveXDomList() );
pValue[length+1].Name = "OOXActiveXBin";
pValue[length+1].Value = uno::makeAny( pDocument->getActiveXBinList() );
xDocProps->setPropertyValue( aGrabBagPropName, uno::Any( aGrabBag ) ); xDocProps->setPropertyValue( aGrabBagPropName, uno::Any( aGrabBag ) );
} }
} }
......
...@@ -153,6 +153,10 @@ uno::Reference<xml::dom::XDocument> OOXMLDocumentImpl::importSubStream(OOXMLStre ...@@ -153,6 +153,10 @@ uno::Reference<xml::dom::XDocument> OOXMLDocumentImpl::importSubStream(OOXMLStre
{ {
importSubStreamRelations(pStream, OOXMLStream::CUSTOMXMLPROPS); importSubStreamRelations(pStream, OOXMLStream::CUSTOMXMLPROPS);
} }
if(OOXMLStream::ACTIVEX == nType)
{
importSubStreamRelations(pStream, OOXMLStream::ACTIVEXBIN);
}
return xRet; return xRet;
} }
...@@ -160,46 +164,52 @@ uno::Reference<xml::dom::XDocument> OOXMLDocumentImpl::importSubStream(OOXMLStre ...@@ -160,46 +164,52 @@ uno::Reference<xml::dom::XDocument> OOXMLDocumentImpl::importSubStream(OOXMLStre
void OOXMLDocumentImpl::importSubStreamRelations(OOXMLStream::Pointer_t pStream, OOXMLStream::StreamType_t nType) void OOXMLDocumentImpl::importSubStreamRelations(OOXMLStream::Pointer_t pStream, OOXMLStream::StreamType_t nType)
{ {
// imporing itemprops files for item.xml from customXml. uno::Reference<xml::dom::XDocument> xRelation;
if(OOXMLStream::CUSTOMXMLPROPS == nType) OOXMLStream::Pointer_t cStream;
try
{ {
uno::Reference<xml::dom::XDocument> xCustomProps; cStream = OOXMLDocumentFactory::createStream(pStream, nType);
OOXMLStream::Pointer_t cStream; }
try catch (uno::Exception const& e)
{ {
cStream = OOXMLDocumentFactory::createStream(pStream, OOXMLStream::CUSTOMXMLPROPS); SAL_WARN("writerfilter", "importSubStreamRelations: exception while "
} "importing stream " << nType << " : " << e.Message);
catch (uno::Exception const& e) }
{
SAL_WARN("writerfilter", "importSubStreamRelations: exception while "
"importing stream " << nType << " : " << e.Message);
mxCustomXmlProsDom = xCustomProps;
}
uno::Reference<io::XInputStream> xcpInputStream = uno::Reference<io::XInputStream> xcpInputStream =
cStream->getDocumentStream(); cStream->getDocumentStream();
if (xcpInputStream.is()) if (xcpInputStream.is())
{
// imporing itemprops files for item.xml from customXml.
if(OOXMLStream::CUSTOMXMLPROPS == nType)
{ {
try try
{ {
uno::Reference<uno::XComponentContext> xcpContext(pStream->getContext()); uno::Reference<uno::XComponentContext> xcpContext(pStream->getContext());
uno::Reference<xml::dom::XDocumentBuilder> xDomBuilder(xml::dom::DocumentBuilder::create(xcpContext)); uno::Reference<xml::dom::XDocumentBuilder> xDomBuilder(xml::dom::DocumentBuilder::create(xcpContext));
xCustomProps = xDomBuilder->parse(xcpInputStream); xRelation = xDomBuilder->parse(xcpInputStream);
} }
catch (uno::Exception const& e) catch (uno::Exception const& e)
{ {
SAL_WARN("writerfilter", "importSubStream: exception while " SAL_WARN("writerfilter", "importSubStream: exception while "
"parsing stream " << nType << " : " << e.Message); "parsing stream " << nType << " : " << e.Message);
mxCustomXmlProsDom = xCustomProps; mxCustomXmlProsDom = xRelation;
} }
}
if(xCustomProps.is()) if(xRelation.is())
{
mxCustomXmlProsDom = xRelation;
}
}
else if(OOXMLStream::ACTIVEXBIN == nType)
{ {
mxCustomXmlProsDom = xCustomProps; // imporing activex.bin files for activex.xml from activeX folder.
mxActiveXBin = xcpInputStream;
} }
} }
} }
void OOXMLDocumentImpl::setXNoteId(const sal_Int32 nId) void OOXMLDocumentImpl::setXNoteId(const sal_Int32 nId)
...@@ -527,6 +537,7 @@ void OOXMLDocumentImpl::resolveActiveXStream(Stream & rStream) ...@@ -527,6 +537,7 @@ void OOXMLDocumentImpl::resolveActiveXStream(Stream & rStream)
uno::Sequence< uno::Sequence< beans::StringPair > >aSeqs = uno::Sequence< uno::Sequence< beans::StringPair > >aSeqs =
mxRelationshipAccess->getAllRelationships(); mxRelationshipAccess->getAllRelationships();
uno::Sequence<uno::Reference<xml::dom::XDocument> > mxActiveXDomListTemp(aSeqs.getLength()); uno::Sequence<uno::Reference<xml::dom::XDocument> > mxActiveXDomListTemp(aSeqs.getLength());
uno::Sequence<uno::Reference<io::XInputStream> > mxActiveXBinListTemp(aSeqs.getLength());
for (sal_Int32 j = 0; j < aSeqs.getLength(); j++) for (sal_Int32 j = 0; j < aSeqs.getLength(); j++)
{ {
uno::Sequence< beans::StringPair > aSeq = aSeqs[j]; uno::Sequence< beans::StringPair > aSeq = aSeqs[j];
...@@ -551,6 +562,10 @@ void OOXMLDocumentImpl::resolveActiveXStream(Stream & rStream) ...@@ -551,6 +562,10 @@ void OOXMLDocumentImpl::resolveActiveXStream(Stream & rStream)
if(activeXTemp.is()) if(activeXTemp.is())
{ {
mxActiveXDomListTemp[counter] = activeXTemp; mxActiveXDomListTemp[counter] = activeXTemp;
if(mxActiveXBin.is())
{
mxActiveXBinListTemp[counter] = mxActiveXBin;
}
counter++; counter++;
resolveFastSubStream(rStream, OOXMLStream::ACTIVEX); resolveFastSubStream(rStream, OOXMLStream::ACTIVEX);
} }
...@@ -558,7 +573,9 @@ void OOXMLDocumentImpl::resolveActiveXStream(Stream & rStream) ...@@ -558,7 +573,9 @@ void OOXMLDocumentImpl::resolveActiveXStream(Stream & rStream)
} }
} }
mxActiveXDomListTemp.realloc(counter); mxActiveXDomListTemp.realloc(counter);
mxActiveXBinListTemp.realloc(counter);
mxActiveXDomList = mxActiveXDomListTemp; mxActiveXDomList = mxActiveXDomListTemp;
mxActiveXBinList = mxActiveXBinListTemp;
} }
} }
...@@ -639,6 +656,11 @@ uno::Sequence<uno::Reference<xml::dom::XDocument> > OOXMLDocumentImpl::getActive ...@@ -639,6 +656,11 @@ uno::Sequence<uno::Reference<xml::dom::XDocument> > OOXMLDocumentImpl::getActive
return mxActiveXDomList; return mxActiveXDomList;
} }
uno::Sequence<uno::Reference<io::XInputStream> > OOXMLDocumentImpl::getActiveXBinList( )
{
return mxActiveXBinList;
}
OOXMLDocument * OOXMLDocument *
OOXMLDocumentFactory::createDocument OOXMLDocumentFactory::createDocument
(OOXMLStream::Pointer_t pStream) (OOXMLStream::Pointer_t pStream)
......
...@@ -46,6 +46,8 @@ class OOXMLDocumentImpl : public OOXMLDocument ...@@ -46,6 +46,8 @@ class OOXMLDocumentImpl : public OOXMLDocument
uno::Sequence<uno::Reference<xml::dom::XDocument> > mxCustomXmlDomPropsList; uno::Sequence<uno::Reference<xml::dom::XDocument> > mxCustomXmlDomPropsList;
uno::Reference<xml::dom::XDocument> mxCustomXmlProsDom; uno::Reference<xml::dom::XDocument> mxCustomXmlProsDom;
uno::Sequence<uno::Reference<xml::dom::XDocument> > mxActiveXDomList; uno::Sequence<uno::Reference<xml::dom::XDocument> > mxActiveXDomList;
uno::Sequence<uno::Reference<io::XInputStream> > mxActiveXBinList;
uno::Reference<io::XInputStream> mxActiveXBin;
bool mbIsSubstream; bool mbIsSubstream;
protected: protected:
...@@ -120,6 +122,7 @@ public: ...@@ -120,6 +122,7 @@ public:
virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getCustomXmlDomList(); virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getCustomXmlDomList();
virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getCustomXmlDomPropsList(); virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getCustomXmlDomPropsList();
virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getActiveXDomList(); virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getActiveXDomList();
virtual uno::Sequence<uno::Reference<io::XInputStream> > getActiveXBinList();
}; };
}} }}
#endif // OOXML_DOCUMENT_IMPL_HXX #endif // OOXML_DOCUMENT_IMPL_HXX
......
...@@ -113,6 +113,7 @@ bool OOXMLStreamImpl::lcl_getTarget(uno::Reference<embed::XRelationshipAccess> ...@@ -113,6 +113,7 @@ bool OOXMLStreamImpl::lcl_getTarget(uno::Reference<embed::XRelationshipAccess>
static OUString sCustomType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml"); static OUString sCustomType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml");
static OUString sCustomPropsType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXmlProps"); static OUString sCustomPropsType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXmlProps");
static OUString sActiveXType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/control"); static OUString sActiveXType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/control");
static OUString sActiveXBinType("http://schemas.microsoft.com/office/2006/relationships/activeXControlBinary");
static OUString sSettingsType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings"); static OUString sSettingsType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings");
static OUString sTarget("Target"); static OUString sTarget("Target");
static OUString sTargetMode("TargetMode"); static OUString sTargetMode("TargetMode");
...@@ -159,6 +160,9 @@ bool OOXMLStreamImpl::lcl_getTarget(uno::Reference<embed::XRelationshipAccess> ...@@ -159,6 +160,9 @@ bool OOXMLStreamImpl::lcl_getTarget(uno::Reference<embed::XRelationshipAccess>
case ACTIVEX: case ACTIVEX:
sStreamType = sActiveXType; sStreamType = sActiveXType;
break; break;
case ACTIVEXBIN:
sStreamType = sActiveXBinType;
break;
case SETTINGS: case SETTINGS:
sStreamType = sSettingsType; sStreamType = sSettingsType;
break; break;
...@@ -189,7 +193,7 @@ bool OOXMLStreamImpl::lcl_getTarget(uno::Reference<embed::XRelationshipAccess> ...@@ -189,7 +193,7 @@ bool OOXMLStreamImpl::lcl_getTarget(uno::Reference<embed::XRelationshipAccess>
bFound = true; bFound = true;
else if (aPair.First.compareTo(sTarget) == 0) else if (aPair.First.compareTo(sTarget) == 0)
{ {
// checking item[n].xml is not visited already. // checking item[n].xml or activex[n].xml is not visited already.
if(customTarget != aPair.Second && (sStreamType == sCustomType || sStreamType == sActiveXType)) if(customTarget != aPair.Second && (sStreamType == sCustomType || sStreamType == sActiveXType))
{ {
bFound = false; bFound = false;
......
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