diff options
author | Laurent Godard <lgodard.libre@laposte.net> | 2015-08-17 13:28:16 +0200 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2015-08-18 09:50:53 +0000 |
commit | 0405975042e91e5cca56068ad0d16ad8ab910737 (patch) | |
tree | 5201a764abde7f8ca01b302e0ea39ee2226634a5 | |
parent | f7e493229bd949066b4d8984dce7678b8687d1ae (diff) |
tdf#75973 : User Defined Types in password encrypted macros
save/load basic script so that when executing password protected
the user defined types can be rebuilt
supports array and nested types
a unit test in sc macros-test.cxx
Change-Id: Ie127ea7ad9aea3353741048c00f1b3910c5517a4
Reviewed-on: https://gerrit.libreoffice.org/17815
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r-- | basic/source/classes/image.cxx | 161 | ||||
-rw-r--r-- | sc/qa/extras/macros-test.cxx | 33 | ||||
-rw-r--r-- | sc/qa/extras/testdocuments/testTypePassword.ods | bin | 0 -> 15201 bytes |
3 files changed, 194 insertions, 0 deletions
diff --git a/basic/source/classes/image.cxx b/basic/source/classes/image.cxx index 0fa3d1398d17..fa4feace5879 100644 --- a/basic/source/classes/image.cxx +++ b/basic/source/classes/image.cxx @@ -240,6 +240,90 @@ bool SbiImage::Load( SvStream& r, sal_uInt32& nVersion ) } break; } + case B_SBXOBJECTS: + + // User defined types + for (sal_uInt16 i = 0; i < nCount; i++) + { + OUString aTypeName = r.ReadUniOrByteString(eCharSet); + + sal_Int16 nTypeMembers; + r.ReadInt16(nTypeMembers); + + SbxObject *pType = new SbxObject(aTypeName); + SbxArray *pTypeMembers = pType->GetProperties(); + + for (sal_uInt16 j = 0; j < nTypeMembers; j++) + { + OUString aMemberName = r.ReadUniOrByteString(eCharSet); + + sal_Int16 aIntMemberType; + r.ReadInt16(aIntMemberType); + SbxDataType aMemberType = static_cast< SbxDataType > ( aIntMemberType ); + + SbxProperty *pTypeElem = new SbxProperty( aMemberName, aMemberType ); + + sal_uInt32 aIntFlag; + r.ReadUInt32(aIntFlag); + SbxFlagBits nElemFlags = static_cast< SbxFlagBits > ( aIntFlag ); + + pTypeElem->SetFlags(nElemFlags); + + sal_Int16 hasObject; + r.ReadInt16(hasObject); + + if (hasObject == 1) + { + if(aMemberType == SbxOBJECT) + { + // nested user defined types + // declared before use, so it is ok to reference it by name on load + // nested types not structuraly compatible with arrays at the moment + OUString aNestedTypeName = r.ReadUniOrByteString(eCharSet); + SbxObject* pNestedTypeObj = static_cast< SbxObject* >( rTypes->Find( aNestedTypeName, SbxCLASS_OBJECT ) ); + if (pNestedTypeObj) + { + SbxObject* pCloneObj = cloneTypeObjectImpl( *pNestedTypeObj ); + pTypeElem->PutObject( pCloneObj ); + } + } + else + { + // an array + // not compatible with nested user defined types at the moment + SbxDimArray* pArray = new SbxDimArray(); + + sal_Int16 isFixedSize; + r.ReadInt16(isFixedSize); + if (isFixedSize == 1) + pArray->setHasFixedSize( true ); + + sal_Int32 nDims; + r.ReadInt32(nDims); + for (sal_Int32 d = 0; d < nDims; d++) + { + sal_Int32 lBound; + sal_Int32 uBound; + r.ReadInt32(lBound).ReadInt32(uBound); + pArray->unoAddDim32(lBound, uBound); + } + + pTypeElem->PutObject( pArray ); + } + } + + pTypeMembers->Insert( pTypeElem, pTypeMembers->Count() ); + + } + + pType->Remove( OUString("Name"), SbxCLASS_DONTCARE ); + pType->Remove( OUString("Parent"), SbxCLASS_DONTCARE ); + + AddType(pType); + } + + break; + case B_MODEND: goto done; default: @@ -360,6 +444,83 @@ bool SbiImage::Save( SvStream& r, sal_uInt32 nVer ) pByteStrings.reset(); SbiCloseRecord( r, nPos ); } + // User defined types + sal_uInt16 nTypes = rTypes->Count(); + if (nTypes > 0 ) + { + nPos = SbiOpenRecord( r, B_SBXOBJECTS, nTypes ); + + for (sal_uInt16 i = 0; i < nTypes; i++) + { + SbxObject* pType = static_cast< SbxObject* > ( rTypes->Get(i) ); + OUString aTypeName = pType->GetClassName(); + + r.WriteUniOrByteString( aTypeName, eCharSet ); + + SbxArray *pTypeMembers = pType->GetProperties(); + sal_uInt16 nTypeMembers = pTypeMembers->Count(); + + r.WriteInt16(nTypeMembers); + + for (sal_uInt16 j = 0; j < nTypeMembers; j++) + { + + SbxProperty* pTypeElem = static_cast< SbxProperty* > ( pTypeMembers->Get(j) ); + + OUString aElemName = pTypeElem->GetName(); + r.WriteUniOrByteString( aElemName, eCharSet ); + + SbxDataType dataType = pTypeElem->GetType(); + r.WriteInt16(dataType); + + SbxFlagBits nElemFlags = pTypeElem->GetFlags(); + r.WriteUInt32(static_cast< sal_uInt32 > (nElemFlags) ); + + SbxBase* pElemObject = pTypeElem->GetObject(); + + if (pElemObject) + { + r.WriteInt16(1); // has elem Object + + if( dataType == SbxOBJECT ) + { + // nested user defined types + // declared before use, so it is ok to reference it by name on load + // not compatible with arrays at the moment + SbxObject* pNestedType = static_cast< SbxObject* > ( pElemObject ); + r.WriteUniOrByteString( pNestedType->GetClassName(), eCharSet ); + } + else + { + // an array + // not compatible with nested user defined types at the moment + SbxDimArray* pArray = static_cast< SbxDimArray* > ( pElemObject ); + + bool bFixedSize = pArray->hasFixedSize(); + if (bFixedSize) + r.WriteInt16(1); + else + r.WriteInt16(0); + + sal_Int32 nDims = pArray->GetDims(); + r.WriteInt32(nDims); + + for (sal_Int32 d = 0; d < nDims; d++) + { + sal_Int32 lBound; + sal_Int32 uBound; + pArray->GetDim32(d, lBound, uBound); + r.WriteInt32(lBound).WriteInt32(uBound); + } + } + } + else + r.WriteInt16(0); // no elem Object + + } + } + SbiCloseRecord( r, nPos ); + } // Set overall length SbiCloseRecord( r, nStart ); if( !SbiGood( r ) ) diff --git a/sc/qa/extras/macros-test.cxx b/sc/qa/extras/macros-test.cxx index d769ff4b74a6..520b31f4144d 100644 --- a/sc/qa/extras/macros-test.cxx +++ b/sc/qa/extras/macros-test.cxx @@ -40,6 +40,7 @@ public: void testStarBasic(); void testVba(); void testMSP(); + void testPasswordProtectedStarBasic(); #endif CPPUNIT_TEST_SUITE(ScMacrosTest); #if !defined(MACOSX) @@ -48,6 +49,7 @@ public: CPPUNIT_TEST(testStarBasic); CPPUNIT_TEST(testMSP); CPPUNIT_TEST(testVba); + CPPUNIT_TEST(testPasswordProtectedStarBasic); #endif CPPUNIT_TEST_SUITE_END(); @@ -96,6 +98,37 @@ void ScMacrosTest::testMSP() xDocSh->DoClose(); } +void ScMacrosTest::testPasswordProtectedStarBasic() +{ + const OUString aFileNameBase("testTypePassword.ods"); + OUString aFileName; + createFileURL(aFileNameBase, aFileName); + uno::Reference< com::sun::star::lang::XComponent > xComponent = loadFromDesktop(aFileName, "com.sun.star.sheet.SpreadsheetDocument"); + + CPPUNIT_ASSERT_MESSAGE("Failed to load testTypePassword.ods", xComponent.is()); + + Any aRet; + Sequence< sal_Int16 > aOutParamIndex; + Sequence< Any > aOutParam; + Sequence< uno::Any > aParams; + + SfxObjectShell* pFoundShell = SfxObjectShell::GetShellFromComponent(xComponent); + + CPPUNIT_ASSERT_MESSAGE("Failed to access document shell", pFoundShell); + ScDocShell* xDocSh = static_cast<ScDocShell*>(pFoundShell); + ScDocument& rDoc = xDocSh->GetDocument(); + + SfxObjectShell::CallXScript( + xComponent, + "vnd.sun.Star.script:MyLibrary.Module1.Main?language=Basic&location=document", + aParams, aRet, aOutParamIndex, aOutParam); + + OUString aValue = rDoc.GetString(0,0,0); + CPPUNIT_ASSERT_MESSAGE("script did not change the value of Sheet1.A1", aValue == "success"); + + xDocSh->DoClose(); +} + void ScMacrosTest::testStarBasic() { const OUString aFileNameBase("StarBasic.ods"); diff --git a/sc/qa/extras/testdocuments/testTypePassword.ods b/sc/qa/extras/testdocuments/testTypePassword.ods Binary files differnew file mode 100644 index 000000000000..ff8b27b4811c --- /dev/null +++ b/sc/qa/extras/testdocuments/testTypePassword.ods |