diff options
-rw-r--r-- | basic/source/classes/image.cxx | 171 | ||||
-rw-r--r-- | basic/source/classes/sbxmod.cxx | 5 | ||||
-rw-r--r-- | basic/source/inc/filefmt.hxx | 30 | ||||
-rw-r--r-- | basic/source/uno/scriptcont.cxx | 5 | ||||
-rw-r--r-- | include/basic/sbmod.hxx | 1 | ||||
-rw-r--r-- | sc/qa/extras/macros-test.cxx | 33 | ||||
-rw-r--r-- | sc/qa/extras/testdocuments/testTypePassword.ods | bin | 0 -> 14623 bytes |
7 files changed, 236 insertions, 9 deletions
diff --git a/basic/source/classes/image.cxx b/basic/source/classes/image.cxx index d99259b0082c..6726da140c6a 100644 --- a/basic/source/classes/image.cxx +++ b/basic/source/classes/image.cxx @@ -240,6 +240,99 @@ bool SbiImage::Load( SvStream& r, sal_uInt32& nVersion ) } break; } + case B_USERTYPES: + { + //assuming an empty string with just the lead 32bit/16bit len indicator + const size_t nMinStringSize = (eCharSet == RTL_TEXTENCODING_UNICODE) ? 4 : 2; + const size_t nMinRecordSize = nMinStringSize + sizeof(sal_Int16); + const size_t nMaxRecords = r.remainingSize() / nMinRecordSize; + if (nCount > nMaxRecords) + { + SAL_WARN("basic", "Parsing error: " << nMaxRecords << + " max possible entries, but " << nCount << " claimed, truncating"); + nCount = nMaxRecords; + } + + // 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 + 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 + 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 +453,84 @@ bool SbiImage::Save( SvStream& r, sal_uInt32 nVer ) pByteStrings.reset(); SbiCloseRecord( r, nPos ); } + // User defined types + if (rTypes) + { + sal_uInt16 nTypes = rTypes->Count(); + if (nTypes > 0 ) + { + nPos = SbiOpenRecord( r, B_USERTYPES, 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 + SbxObject* pNestedType = static_cast< SbxObject* > ( pElemObject ); + r.WriteUniOrByteString( pNestedType->GetClassName(), eCharSet ); + } + else + { + // an array + 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/basic/source/classes/sbxmod.cxx b/basic/source/classes/sbxmod.cxx index e6375e272905..aaa9db9b6aed 100644 --- a/basic/source/classes/sbxmod.cxx +++ b/basic/source/classes/sbxmod.cxx @@ -1806,11 +1806,6 @@ bool SbModule::HasExeCode() } // Store only image, no source -bool SbModule::StoreBinaryData( SvStream& rStrm ) -{ - return StoreBinaryData( rStrm, 0 ); -} - bool SbModule::StoreBinaryData( SvStream& rStrm, sal_uInt16 nVer ) { bool bRet = Compile(); diff --git a/basic/source/inc/filefmt.hxx b/basic/source/inc/filefmt.hxx index 9b294a8c2028..db0b1f6e919f 100644 --- a/basic/source/inc/filefmt.hxx +++ b/basic/source/inc/filefmt.hxx @@ -38,10 +38,13 @@ class SvStream; // Version F: #57844 introduction of SvNumberformat::StringToDouble // Version 10: #29955 generate for-loop-level in Statement-PCodes // Version 11: #29955 force anew compilation because of build-inconsistences +// Version 12: aoo#64377 increase code size that basic can handle +// tdf#75973 support user defined types B_USERTYPES in password protected macros +// #define B_LEGACYVERSION 0x00000011L -#define B_CURVERSION 0x00000012L #define B_EXT_IMG_VERSION 0x00000012L +#define B_CURVERSION 0x00000012L // The file contains either a module- or a library-record. // Those records contain further records. Every record's got @@ -69,6 +72,9 @@ class SvStream; #define B_SBXOBJECTS 0x5853 // SX SBX objects #define B_EXTSOURCE 0x5345 // ES extended source +#define B_USERTYPES 0x4369 // UT user defined types + + // A library record contains only module records // sal_uInt16 identifier BL // sal_uInt32 the record's length @@ -153,6 +159,28 @@ class SvStream; // sal_uInt16 number of objects // .... object data +// user defined types B_USERTYPES : +// sal_uInt16 identifier UT +// sal_uInt32 the record's length +// sal_uInt16 number of types +// Data for every user defined type: +// string instance type name +// sal_Int16 number of type members +// Data for every type member: +// string name +// sal_Int16 type +// sal_uInt32 flags +// sal_Int16 hasObjects (0/1) +// If hasObjects +// If member type is nested type +// string nested type name +// Else (array declaration) +// sal_Int16 isFixedSize (0/1) +// sal_Int32 number of dimensions +// Data for every dimension: +// sal_Int32 lower bound +// sal_Int32 upper bound + #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/basic/source/uno/scriptcont.cxx b/basic/source/uno/scriptcont.cxx index ae1b9bf4e78e..bbf1fa6b2117 100644 --- a/basic/source/uno/scriptcont.cxx +++ b/basic/source/uno/scriptcont.cxx @@ -18,6 +18,7 @@ */ #include "scriptcont.hxx" +#include <filefmt.hxx> #include <com/sun/star/container/XNameContainer.hpp> #include <com/sun/star/xml/sax/Parser.hpp> #include <com/sun/star/xml/sax/InputSource.hpp> @@ -652,7 +653,7 @@ bool SfxScriptLibraryContainer::implStorePasswordLibrary( SfxLibrary* pLib, cons throw uno::RuntimeException(); } SvMemoryStream aMemStream; - /*sal_Bool bStore = */pMod->StoreBinaryData( aMemStream ); + /*sal_Bool bStore = */pMod->StoreBinaryData( aMemStream, B_CURVERSION ); sal_Size nSize = aMemStream.Tell(); Sequence< sal_Int8 > aBinSeq( nSize ); @@ -795,7 +796,7 @@ bool SfxScriptLibraryContainer::implStorePasswordLibrary( SfxLibrary* pLib, cons embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ); SvMemoryStream aMemStream; - /*sal_Bool bStore = */pMod->StoreBinaryData( aMemStream ); + /*sal_Bool bStore = */pMod->StoreBinaryData( aMemStream, B_CURVERSION ); sal_Size nSize = aMemStream.Tell(); Sequence< sal_Int8 > aBinSeq( nSize ); diff --git a/include/basic/sbmod.hxx b/include/basic/sbmod.hxx index c5a9e16480fb..cddfffb86b4b 100644 --- a/include/basic/sbmod.hxx +++ b/include/basic/sbmod.hxx @@ -119,7 +119,6 @@ public: void ClearAllBP(); // Store only image, no source (needed for new password protection) - bool StoreBinaryData( SvStream& ); bool StoreBinaryData( SvStream&, sal_uInt16 nVer ); bool LoadBinaryData( SvStream&, sal_uInt16 nVer ); bool LoadBinaryData( SvStream& ); diff --git a/sc/qa/extras/macros-test.cxx b/sc/qa/extras/macros-test.cxx index 3bc3a94d4b68..745de8673d51 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..80a0006d58c5 --- /dev/null +++ b/sc/qa/extras/testdocuments/testTypePassword.ods |