summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--basic/source/classes/image.cxx171
-rw-r--r--basic/source/classes/sbxmod.cxx5
-rw-r--r--basic/source/inc/filefmt.hxx30
-rw-r--r--basic/source/uno/scriptcont.cxx5
-rw-r--r--include/basic/sbmod.hxx1
-rw-r--r--sc/qa/extras/macros-test.cxx33
-rw-r--r--sc/qa/extras/testdocuments/testTypePassword.odsbin0 -> 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
new file mode 100644
index 000000000000..80a0006d58c5
--- /dev/null
+++ b/sc/qa/extras/testdocuments/testTypePassword.ods
Binary files differ