diff options
54 files changed, 1615 insertions, 633 deletions
diff --git a/filter/inc/filter/msfilter/mscodec.hxx b/filter/inc/filter/msfilter/mscodec.hxx index 7bad8af6b788..60e3adf1d5ba 100644 --- a/filter/inc/filter/msfilter/mscodec.hxx +++ b/filter/inc/filter/msfilter/mscodec.hxx @@ -28,8 +28,11 @@ #ifndef SVX_MSCODEC_HXX #define SVX_MSCODEC_HXX -#include "rtl/cipher.h" -#include "rtl/digest.h" +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/beans/NamedValue.hpp> + +#include <rtl/cipher.h> +#include <rtl/digest.h> #include "filter/msfilter/msfilterdllapi.h" namespace msfilter { @@ -52,6 +55,23 @@ public: */ void InitKey( const sal_uInt8 pnPassData[ 16 ] ); + /** Initializes the algorithm with the encryption data. + + @param aData + The sequence contains the necessary data to initialize + the codec. + */ + sal_Bool InitCodec( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aData ); + + /** Retrieves the encryption data + + @return + The sequence contains the necessary data to initialize + the codec. + */ + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > GetEncryptionData(); + + /** Verifies the validity of the password using the passed key and hash. @precond @@ -105,16 +125,6 @@ public: */ void Skip( sal_Size nBytes ); - // static ----------------------------------------------------------------- - - /** Calculates the 16-bit hash value for the given password. - - The password data may be longer than 16 bytes. The array does not need - to be terminated with a NULL byte (but it can without invalidating the - result). - */ - static sal_uInt16 GetHash( const sal_uInt8* pnPassData, sal_Size nSize ); - protected: sal_uInt8 mpnKey[ 16 ]; /// Encryption key. sal_Size mnOffset; /// Key offset. @@ -185,17 +195,34 @@ public: explicit MSCodec_Std97(); ~MSCodec_Std97(); + /** Initializes the algorithm with the encryption data. + + @param aData + The sequence contains the necessary data to initialize + the codec. + */ + sal_Bool InitCodec( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aData ); + + /** Retrieves the encryption data + + @return + The sequence contains the necessary data to initialize + the codec. + */ + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > GetEncryptionData(); + + /** Initializes the algorithm with the specified password and document ID. @param pPassData Wide character array containing the password. Must be zero terminated, which results in a maximum length of 15 characters. - @param pUnique + @param pDocId Unique document identifier read from or written to the file. */ void InitKey( const sal_uInt16 pPassData[ 16 ], - const sal_uInt8 pUnique[ 16 ] ); + const sal_uInt8 pDocId[ 16 ] ); /** Verifies the validity of the password using the passed salt data. @@ -320,16 +347,26 @@ public: sal_uInt8 pSaltData[16], sal_uInt8 pSaltDigest[16]); -private: + /* allows to get the unique document id from the codec + */ + void GetDocId( sal_uInt8 pDocId[16] ); + void GetDigestFromSalt( const sal_uInt8 pSaltData[16], sal_uInt8 pDigest[16] ); private: + void InitKeyImpl( + const sal_uInt8 pKeyData[64], + const sal_uInt8 pDocId[16] ); + + +private: MSFILTER_DLLPRIVATE MSCodec_Std97( const MSCodec_Std97& ); MSFILTER_DLLPRIVATE MSCodec_Std97& operator=( const MSCodec_Std97& ); rtlCipher m_hCipher; rtlDigest m_hDigest; sal_uInt8 m_pDigestValue[ RTL_DIGEST_LENGTH_MD5 ]; + sal_uInt8 m_pDocId[16]; }; // ============================================================================ diff --git a/filter/source/config/cache/lateinitthread.cxx b/filter/source/config/cache/lateinitthread.cxx index 13432c30ad0f..1cae15996876 100644 --- a/filter/source/config/cache/lateinitthread.cxx +++ b/filter/source/config/cache/lateinitthread.cxx @@ -76,5 +76,10 @@ void SAL_CALL LateInitThread::run() rCache->load(FilterCache::E_CONTAINS_ALL, sal_True); } +void SAL_CALL LateInitThread::onTerminated() +{ + delete this; +} + } // namespace config } // namespace filter diff --git a/filter/source/config/cache/lateinitthread.hxx b/filter/source/config/cache/lateinitthread.hxx index c330394d434d..b37d0525dd4b 100644 --- a/filter/source/config/cache/lateinitthread.hxx +++ b/filter/source/config/cache/lateinitthread.hxx @@ -81,6 +81,8 @@ class LateInitThread : public ::osl::Thread /** @short thread function. */ virtual void SAL_CALL run(); + + virtual void SAL_CALL onTerminated(); }; } // namespace config diff --git a/filter/source/config/cache/typedetection.cxx b/filter/source/config/cache/typedetection.cxx index 4fe9a1df64e6..418c95f0f819 100644 --- a/filter/source/config/cache/typedetection.cxx +++ b/filter/source/config/cache/typedetection.cxx @@ -1103,12 +1103,11 @@ void TypeDetection::impl_seekStreamToZero(comphelper::MediaDescriptor& rDescript try { // create a new request to ask user for it's decision about the usable filter - ::framework::RequestFilterSelect* pRequest = new ::framework::RequestFilterSelect(sURL); - css::uno::Reference< css::task::XInteractionRequest > xRequest(static_cast< css::task::XInteractionRequest* >(pRequest), css::uno::UNO_QUERY_THROW); - xInteraction->handle(xRequest); + ::framework::RequestFilterSelect aRequest(sURL); + xInteraction->handle(aRequest.GetRequest()); // "Cancel" pressed? => return with error - if (pRequest->isAbort()) + if (aRequest.isAbort()) return ::rtl::OUString(); // "OK" pressed => verify the selected filter, get it's coressponding @@ -1117,7 +1116,7 @@ void TypeDetection::impl_seekStreamToZero(comphelper::MediaDescriptor& rDescript // a type here only. But we must be shure, that the selected filter is used // too and no ambigous filter registration disturb us .-) - ::rtl::OUString sFilter = pRequest->getFilter(); + ::rtl::OUString sFilter = aRequest.getFilter(); if (!impl_validateAndSetFilterOnDescriptor(rDescriptor, sFilter)) return ::rtl::OUString(); diff --git a/filter/source/config/fragments/filters/MS_PowerPoint_97.xcu b/filter/source/config/fragments/filters/MS_PowerPoint_97.xcu index 7c61f7c14084..20c55429e465 100644 --- a/filter/source/config/fragments/filters/MS_PowerPoint_97.xcu +++ b/filter/source/config/fragments/filters/MS_PowerPoint_97.xcu @@ -1,5 +1,5 @@ <node oor:name="MS PowerPoint 97" oor:op="replace"> - <prop oor:name="Flags"><value>IMPORT EXPORT ALIEN ENCRYPTION PASSWORDTOMODIFY</value></prop> + <prop oor:name="Flags"><value>IMPORT EXPORT ALIEN</value></prop> <prop oor:name="UIComponent"/> <prop oor:name="FilterService"/> <prop oor:name="UserData"><value>sdfilt</value></prop> diff --git a/filter/source/config/fragments/filters/MS_PowerPoint_97_Vorlage.xcu b/filter/source/config/fragments/filters/MS_PowerPoint_97_Vorlage.xcu index 505084d4d39f..b0776fda9500 100644 --- a/filter/source/config/fragments/filters/MS_PowerPoint_97_Vorlage.xcu +++ b/filter/source/config/fragments/filters/MS_PowerPoint_97_Vorlage.xcu @@ -1,5 +1,5 @@ <node oor:name="MS PowerPoint 97 Vorlage" oor:op="replace"> - <prop oor:name="Flags"><value>IMPORT EXPORT TEMPLATE TEMPLATEPATH ALIEN ENCRYPTION PASSWORDTOMODIFY</value></prop> + <prop oor:name="Flags"><value>IMPORT EXPORT TEMPLATE TEMPLATEPATH ALIEN</value></prop> <prop oor:name="UIComponent"/> <prop oor:name="FilterService"/> <prop oor:name="UserData"><value>sdfilt</value></prop> diff --git a/filter/source/config/fragments/filters/Rich_Text_Format.xcu b/filter/source/config/fragments/filters/Rich_Text_Format.xcu index dc8b07e45536..d8fb18c96d06 100644 --- a/filter/source/config/fragments/filters/Rich_Text_Format.xcu +++ b/filter/source/config/fragments/filters/Rich_Text_Format.xcu @@ -1,7 +1,7 @@ <node oor:name="Rich Text Format" oor:op="replace"> - <prop oor:name="Flags"><value>IMPORT EXPORT ALIEN PREFERRED</value></prop> + <prop oor:name="Flags"><value>IMPORT EXPORT ALIEN 3RDPARTYFILTER PREFERRED</value></prop> <prop oor:name="UIComponent"/> - <prop oor:name="FilterService"/> + <prop oor:name="FilterService"><value>com.sun.star.comp.Writer.RtfFilter</value></prop> <prop oor:name="UserData"><value>RTF</value></prop> <prop oor:name="UIName"> <value xml:lang="x-default">Rich Text Format</value> diff --git a/filter/source/graphicfilter/itiff/itiff.cxx b/filter/source/graphicfilter/itiff/itiff.cxx index f10b8a15f3ef..6f356b042d28 100644 --- a/filter/source/graphicfilter/itiff/itiff.cxx +++ b/filter/source/graphicfilter/itiff/itiff.cxx @@ -764,245 +764,259 @@ BOOL TIFFReader::ConvertScanline( ULONG nY ) } else if ( nPhotometricInterpretation == 2 && nSamplesPerPixel >= 3 ) { - ULONG nMinMax = nMinSampleValue * 255 / ( nMaxSampleValue - nMinSampleValue ); - for ( nx = 0; nx < nImageWidth; nx++ ) + if ( nMaxSampleValue > nMinSampleValue ) { - if ( nPlanes < 3 ) - { - nRed = GetBits( pMap[ 0 ], ( nx * nSamplesPerPixel + 0 ) * nBitsPerSample, nBitsPerSample ); - nGreen = GetBits( pMap[ 1 ], ( nx * nSamplesPerPixel + 1 ) * nBitsPerSample, nBitsPerSample ); - nBlue = GetBits( pMap[ 2 ], ( nx * nSamplesPerPixel + 2 ) * nBitsPerSample, nBitsPerSample ); - } - else + ULONG nMinMax = nMinSampleValue * 255 / ( nMaxSampleValue - nMinSampleValue ); + for ( nx = 0; nx < nImageWidth; nx++ ) { - nRed = GetBits( pMap[ 0 ], nx * nBitsPerSample, nBitsPerSample ); - nGreen = GetBits( pMap[ 1 ], nx * nBitsPerSample, nBitsPerSample ); - nBlue = GetBits( pMap[ 2 ], nx * nBitsPerSample, nBitsPerSample ); + if ( nPlanes < 3 ) + { + nRed = GetBits( pMap[ 0 ], ( nx * nSamplesPerPixel + 0 ) * nBitsPerSample, nBitsPerSample ); + nGreen = GetBits( pMap[ 1 ], ( nx * nSamplesPerPixel + 1 ) * nBitsPerSample, nBitsPerSample ); + nBlue = GetBits( pMap[ 2 ], ( nx * nSamplesPerPixel + 2 ) * nBitsPerSample, nBitsPerSample ); + } + else + { + nRed = GetBits( pMap[ 0 ], nx * nBitsPerSample, nBitsPerSample ); + nGreen = GetBits( pMap[ 1 ], nx * nBitsPerSample, nBitsPerSample ); + nBlue = GetBits( pMap[ 2 ], nx * nBitsPerSample, nBitsPerSample ); + } + pAcc->SetPixel( nY, nx, Color( (BYTE)( nRed - nMinMax ), (BYTE)( nGreen - nMinMax ), (BYTE)(nBlue - nMinMax) ) ); } - pAcc->SetPixel( nY, nx, Color( (BYTE)( nRed - nMinMax ), (BYTE)( nGreen - nMinMax ), (BYTE)(nBlue - nMinMax) ) ); } } else if ( nPhotometricInterpretation == 5 && nSamplesPerPixel == 3 ) { - ULONG nMinMax = nMinSampleValue * 255 / ( nMaxSampleValue - nMinSampleValue ); - for ( nx = 0; nx < nImageWidth; nx++ ) + if ( nMaxSampleValue > nMinSampleValue ) { - if ( nPlanes < 3 ) - { - nRed = GetBits( pMap[ 0 ],( nx * nSamplesPerPixel + 0 ) * nBitsPerSample, nBitsPerSample ); - nGreen = GetBits( pMap[ 0 ],( nx * nSamplesPerPixel + 1 ) * nBitsPerSample, nBitsPerSample ); - nBlue = GetBits( pMap[ 0 ],( nx * nSamplesPerPixel + 2 ) * nBitsPerSample, nBitsPerSample ); - } - else + ULONG nMinMax = nMinSampleValue * 255 / ( nMaxSampleValue - nMinSampleValue ); + for ( nx = 0; nx < nImageWidth; nx++ ) { - nRed = GetBits( pMap[ 0 ], nx * nBitsPerSample, nBitsPerSample ); - nGreen = GetBits( pMap[ 1 ], nx * nBitsPerSample, nBitsPerSample ); - nBlue = GetBits( pMap[ 2 ], nx * nBitsPerSample, nBitsPerSample ); + if ( nPlanes < 3 ) + { + nRed = GetBits( pMap[ 0 ],( nx * nSamplesPerPixel + 0 ) * nBitsPerSample, nBitsPerSample ); + nGreen = GetBits( pMap[ 0 ],( nx * nSamplesPerPixel + 1 ) * nBitsPerSample, nBitsPerSample ); + nBlue = GetBits( pMap[ 0 ],( nx * nSamplesPerPixel + 2 ) * nBitsPerSample, nBitsPerSample ); + } + else + { + nRed = GetBits( pMap[ 0 ], nx * nBitsPerSample, nBitsPerSample ); + nGreen = GetBits( pMap[ 1 ], nx * nBitsPerSample, nBitsPerSample ); + nBlue = GetBits( pMap[ 2 ], nx * nBitsPerSample, nBitsPerSample ); + } + nRed = 255 - (BYTE)( nRed - nMinMax ); + nGreen = 255 - (BYTE)( nGreen - nMinMax ); + nBlue = 255 - (BYTE)( nBlue - nMinMax ); + pAcc->SetPixel( nY, nx, Color( (BYTE) nRed, (BYTE) nGreen, (BYTE) nBlue ) ); } - nRed = 255 - (BYTE)( nRed - nMinMax ); - nGreen = 255 - (BYTE)( nGreen - nMinMax ); - nBlue = 255 - (BYTE)( nBlue - nMinMax ); - pAcc->SetPixel( nY, nx, Color( (BYTE) nRed, (BYTE) nGreen, (BYTE) nBlue ) ); } } else if( nPhotometricInterpretation == 5 && nSamplesPerPixel == 4 ) { - BYTE nSamp[ 4 ]; - BYTE nSampLast[ 4 ] = { 0, 0, 0, 0 }; - long nBlack; - - for( nx = 0; nx < nImageWidth; nx++ ) + if ( nMaxSampleValue > nMinSampleValue ) { - // sind die Werte als Differenz abgelegt? - if( 2 == nPredictor ) + BYTE nSamp[ 4 ]; + BYTE nSampLast[ 4 ] = { 0, 0, 0, 0 }; + long nBlack; + + for( nx = 0; nx < nImageWidth; nx++ ) { - for( ns = 0; ns < 4; ns++ ) + // sind die Werte als Differenz abgelegt? + if( 2 == nPredictor ) { - if( nPlanes < 3 ) - nSampLast[ ns ] = nSampLast[ ns ] + (BYTE) GetBits( pMap[ 0 ], ( nx * nSamplesPerPixel + ns ) * nBitsPerSample, nBitsPerSample ); - else - nSampLast[ ns ] = nSampLast[ ns ] + (BYTE) GetBits( pMap[ ns ], nx * nBitsPerSample, nBitsPerSample ); - nSamp[ ns ] = nSampLast[ ns ]; + for( ns = 0; ns < 4; ns++ ) + { + if( nPlanes < 3 ) + nSampLast[ ns ] = nSampLast[ ns ] + (BYTE) GetBits( pMap[ 0 ], ( nx * nSamplesPerPixel + ns ) * nBitsPerSample, nBitsPerSample ); + else + nSampLast[ ns ] = nSampLast[ ns ] + (BYTE) GetBits( pMap[ ns ], nx * nBitsPerSample, nBitsPerSample ); + nSamp[ ns ] = nSampLast[ ns ]; + } } - } - else - { - for( ns = 0; ns < 4; ns++ ) + else { - if( nPlanes < 3 ) - nSamp[ ns ] = (BYTE) GetBits( pMap[ 0 ], ( nx * nSamplesPerPixel + ns ) * nBitsPerSample, nBitsPerSample ); - else - nSamp[ ns ]= (BYTE) GetBits( pMap[ ns ], nx * nBitsPerSample, nBitsPerSample ); + for( ns = 0; ns < 4; ns++ ) + { + if( nPlanes < 3 ) + nSamp[ ns ] = (BYTE) GetBits( pMap[ 0 ], ( nx * nSamplesPerPixel + ns ) * nBitsPerSample, nBitsPerSample ); + else + nSamp[ ns ]= (BYTE) GetBits( pMap[ ns ], nx * nBitsPerSample, nBitsPerSample ); + } } + nBlack = nSamp[ 3 ]; + nRed = (BYTE) Max( 0L, 255L - ( ( (long) nSamp[ 0 ] + nBlack - ( ( (long) nMinSampleValue ) << 1 ) ) * + 255L/(long)(nMaxSampleValue-nMinSampleValue) ) ); + nGreen = (BYTE) Max( 0L, 255L - ( ( (long) nSamp[ 1 ] + nBlack - ( ( (long) nMinSampleValue ) << 1 ) ) * + 255L/(long)(nMaxSampleValue-nMinSampleValue) ) ); + nBlue = (BYTE) Max( 0L, 255L - ( ( (long) nSamp[ 2 ] + nBlack - ( ( (long) nMinSampleValue ) << 1 ) ) * + 255L/(long)(nMaxSampleValue-nMinSampleValue) ) ); + pAcc->SetPixel( nY, nx, Color ( (BYTE)nRed, (BYTE)nGreen, (BYTE)nBlue ) ); } - nBlack = nSamp[ 3 ]; - nRed = (BYTE) Max( 0L, 255L - ( ( (long) nSamp[ 0 ] + nBlack - ( ( (long) nMinSampleValue ) << 1 ) ) * - 255L/(long)(nMaxSampleValue-nMinSampleValue) ) ); - nGreen = (BYTE) Max( 0L, 255L - ( ( (long) nSamp[ 1 ] + nBlack - ( ( (long) nMinSampleValue ) << 1 ) ) * - 255L/(long)(nMaxSampleValue-nMinSampleValue) ) ); - nBlue = (BYTE) Max( 0L, 255L - ( ( (long) nSamp[ 2 ] + nBlack - ( ( (long) nMinSampleValue ) << 1 ) ) * - 255L/(long)(nMaxSampleValue-nMinSampleValue) ) ); - pAcc->SetPixel( nY, nx, Color ( (BYTE)nRed, (BYTE)nGreen, (BYTE)nBlue ) ); - } } } else if ( nSamplesPerPixel == 1 && ( nPhotometricInterpretation <= 1 || nPhotometricInterpretation == 3 ) ) { - ULONG nMinMax = ( ( 1 << nDstBitsPerPixel ) - 1 ) / ( nMaxSampleValue - nMinSampleValue ); - BYTE* pt = pMap[ 0 ]; - BYTE nShift; - - switch ( nDstBitsPerPixel ) + if ( nMaxSampleValue > nMinSampleValue ) { - case 8 : + ULONG nMinMax = ( ( 1 << nDstBitsPerPixel ) - 1 ) / ( nMaxSampleValue - nMinSampleValue ); + BYTE* pt = pMap[ 0 ]; + BYTE nShift; + + switch ( nDstBitsPerPixel ) { - BYTE nLast; - if ( bByteSwap ) + case 8 : { - if ( nPredictor == 2 ) + BYTE nLast; + if ( bByteSwap ) { - nLast = BYTESWAP( (BYTE)*pt++ ); - for ( nx = 0; nx < nImageWidth; nx++ ) + if ( nPredictor == 2 ) { - pAcc->SetPixel( nY, nx, nLast ); - nLast = nLast + *pt++; + nLast = BYTESWAP( (BYTE)*pt++ ); + for ( nx = 0; nx < nImageWidth; nx++ ) + { + pAcc->SetPixel( nY, nx, nLast ); + nLast = nLast + *pt++; + } } - } - else - { - for ( nx = 0; nx < nImageWidth; nx++ ) + else { - nLast = *pt++; - pAcc->SetPixel( nY, nx, (BYTE)( ( (BYTESWAP((ULONG)nLast ) - nMinSampleValue ) * nMinMax ) ) ); + for ( nx = 0; nx < nImageWidth; nx++ ) + { + nLast = *pt++; + pAcc->SetPixel( nY, nx, (BYTE)( ( (BYTESWAP((ULONG)nLast ) - nMinSampleValue ) * nMinMax ) ) ); + } } } - } - else - { - if ( nPredictor == 2 ) + else { - nLast = *pt++; - for ( nx = 0; nx < nImageWidth; nx++ ) + if ( nPredictor == 2 ) { - pAcc->SetPixel( nY, nx, nLast ); - nLast = nLast + *pt++; + nLast = *pt++; + for ( nx = 0; nx < nImageWidth; nx++ ) + { + pAcc->SetPixel( nY, nx, nLast ); + nLast = nLast + *pt++; + } } - } - else - { - for ( nx = 0; nx < nImageWidth; nx++ ) + else { - pAcc->SetPixel( nY, nx, (BYTE)( ( (ULONG)*pt++ - nMinSampleValue ) * nMinMax ) ); + for ( nx = 0; nx < nImageWidth; nx++ ) + { + pAcc->SetPixel( nY, nx, (BYTE)( ( (ULONG)*pt++ - nMinSampleValue ) * nMinMax ) ); + } } } } - } - break; + break; - case 7 : - case 6 : - case 5 : - case 4 : - case 3 : - case 2 : - { - for ( nx = 0; nx < nImageWidth; nx++ ) + case 7 : + case 6 : + case 5 : + case 4 : + case 3 : + case 2 : { - nVal = ( GetBits( pt, nx * nBitsPerSample, nBitsPerSample ) - nMinSampleValue ) * nMinMax; - pAcc->SetPixel( nY, nx, (BYTE)nVal ); + for ( nx = 0; nx < nImageWidth; nx++ ) + { + nVal = ( GetBits( pt, nx * nBitsPerSample, nBitsPerSample ) - nMinSampleValue ) * nMinMax; + pAcc->SetPixel( nY, nx, (BYTE)nVal ); + } } - } - break; + break; - case 1 : - { - if ( bByteSwap ) + case 1 : { - nx = 0; - nByteCount = ( nImageWidth >> 3 ) + 1; - while ( --nByteCount ) + if ( bByteSwap ) { - nByteVal = *pt++; - pAcc->SetPixel( nY, nx++, nByteVal & 1 ); - nByteVal >>= 1; - pAcc->SetPixel( nY, nx++, nByteVal & 1 ); - nByteVal >>= 1; - pAcc->SetPixel( nY, nx++, nByteVal & 1 ); - nByteVal >>= 1; - pAcc->SetPixel( nY, nx++, nByteVal & 1 ); - nByteVal >>= 1; - pAcc->SetPixel( nY, nx++, nByteVal & 1 ); - nByteVal >>= 1; - pAcc->SetPixel( nY, nx++, nByteVal & 1 ); - nByteVal >>= 1; - pAcc->SetPixel( nY, nx++, nByteVal & 1 ); - nByteVal >>= 1; - pAcc->SetPixel( nY, nx++, nByteVal ); - } - if ( nImageWidth & 7 ) - { - nByteVal = *pt++; - while ( nx < nImageWidth ) + nx = 0; + nByteCount = ( nImageWidth >> 3 ) + 1; + while ( --nByteCount ) { + nByteVal = *pt++; + pAcc->SetPixel( nY, nx++, nByteVal & 1 ); + nByteVal >>= 1; + pAcc->SetPixel( nY, nx++, nByteVal & 1 ); + nByteVal >>= 1; + pAcc->SetPixel( nY, nx++, nByteVal & 1 ); + nByteVal >>= 1; + pAcc->SetPixel( nY, nx++, nByteVal & 1 ); + nByteVal >>= 1; + pAcc->SetPixel( nY, nx++, nByteVal & 1 ); + nByteVal >>= 1; + pAcc->SetPixel( nY, nx++, nByteVal & 1 ); + nByteVal >>= 1; pAcc->SetPixel( nY, nx++, nByteVal & 1 ); nByteVal >>= 1; + pAcc->SetPixel( nY, nx++, nByteVal ); + } + if ( nImageWidth & 7 ) + { + nByteVal = *pt++; + while ( nx < nImageWidth ) + { + pAcc->SetPixel( nY, nx++, nByteVal & 1 ); + nByteVal >>= 1; + } } } - } - else - { - nx = 7; - nByteCount = ( nImageWidth >> 3 ) + 1; - while ( --nByteCount ) - { - nByteVal = *pt++; - pAcc->SetPixel( nY, nx, nByteVal & 1 ); - nByteVal >>= 1; - pAcc->SetPixel( nY, --nx, nByteVal & 1 ); - nByteVal >>= 1; - pAcc->SetPixel( nY, --nx, nByteVal & 1 ); - nByteVal >>= 1; - pAcc->SetPixel( nY, --nx, nByteVal & 1 ); - nByteVal >>= 1; - pAcc->SetPixel( nY, --nx, nByteVal & 1 ); - nByteVal >>= 1; - pAcc->SetPixel( nY, --nx, nByteVal & 1 ); - nByteVal >>= 1; - pAcc->SetPixel( nY, --nx, nByteVal & 1 ); - nByteVal >>= 1; - pAcc->SetPixel( nY, --nx, nByteVal ); - nx += 15; - } - if ( nImageWidth & 7 ) + else { - nx -= 7; - nByteVal = *pt++; - nShift = 7; - while ( nx < nImageWidth ) + nx = 7; + nByteCount = ( nImageWidth >> 3 ) + 1; + while ( --nByteCount ) { - pAcc->SetPixel( nY, nx++, ( nByteVal >> nShift ) & 1); + nByteVal = *pt++; + pAcc->SetPixel( nY, nx, nByteVal & 1 ); + nByteVal >>= 1; + pAcc->SetPixel( nY, --nx, nByteVal & 1 ); + nByteVal >>= 1; + pAcc->SetPixel( nY, --nx, nByteVal & 1 ); + nByteVal >>= 1; + pAcc->SetPixel( nY, --nx, nByteVal & 1 ); + nByteVal >>= 1; + pAcc->SetPixel( nY, --nx, nByteVal & 1 ); + nByteVal >>= 1; + pAcc->SetPixel( nY, --nx, nByteVal & 1 ); + nByteVal >>= 1; + pAcc->SetPixel( nY, --nx, nByteVal & 1 ); + nByteVal >>= 1; + pAcc->SetPixel( nY, --nx, nByteVal ); + nx += 15; + } + if ( nImageWidth & 7 ) + { + nx -= 7; + nByteVal = *pt++; + nShift = 7; + while ( nx < nImageWidth ) + { + pAcc->SetPixel( nY, nx++, ( nByteVal >> nShift ) & 1); + } } } } - } - break; + break; - default : - return FALSE; + default : + return FALSE; + } } } else if ( ( nSamplesPerPixel == 2 ) && ( nBitsPerSample == 8 ) && ( nPlanarConfiguration == 1 ) && ( pColorMap == 0 ) ) // grayscale { - ULONG nMinMax = ( ( 1 << 8 /*nDstBitsPerPixel*/ ) - 1 ) / ( nMaxSampleValue - nMinSampleValue ); - BYTE* pt = pMap[ 0 ]; - if ( nByte1 == 'I' ) - pt++; - for ( nx = 0; nx < nImageWidth; nx++, pt += 2 ) + if ( nMaxSampleValue > nMinSampleValue ) { - pAcc->SetPixel( nY, nx, (BYTE)( ( (ULONG)*pt - nMinSampleValue ) * nMinMax ) ); + ULONG nMinMax = ( ( 1 << 8 /*nDstBitsPerPixel*/ ) - 1 ) / ( nMaxSampleValue - nMinSampleValue ); + BYTE* pt = pMap[ 0 ]; + if ( nByte1 == 'I' ) + pt++; + for ( nx = 0; nx < nImageWidth; nx++, pt += 2 ) + { + pAcc->SetPixel( nY, nx, (BYTE)( ( (ULONG)*pt - nMinSampleValue ) * nMinMax ) ); + } } } else @@ -1207,11 +1221,17 @@ BOOL TIFFReader::ReadTIFF(SvStream & rTIFF, Graphic & rGraphic ) if ( pTIFF->IsEof() ) nNextIfd = 0; } + if ( !nBitsPerSample || ( nBitsPerSample > 32 ) ) + bStatus = FALSE; if ( bStatus ) { if ( nMaxSampleValue == 0 ) - nMaxSampleValue = ( 1 << nBitsPerSample ) - 1; - + { + if ( nBitsPerSample == 32 ) // sj: i93300, compiler bug, 1 << 32 gives 1 one 32bit windows platforms, + nMaxSampleValue = 0xffffffff; // (up from 80286 only the lower 5 bits are used when shifting a 32bit register) + else + nMaxSampleValue = ( 1 << nBitsPerSample ) - 1; + } if ( nPhotometricInterpretation == 2 || nPhotometricInterpretation == 5 || nPhotometricInterpretation == 6 ) nDstBitsPerPixel = 24; else if ( nBitsPerSample*nSamplesPerPixel <= 1 ) diff --git a/filter/source/msfilter/mscodec.cxx b/filter/source/msfilter/mscodec.cxx index de17da6bde59..c6feb4fb57dd 100644 --- a/filter/source/msfilter/mscodec.cxx +++ b/filter/source/msfilter/mscodec.cxx @@ -34,12 +34,16 @@ #include <string.h> #include <tools/solar.h> +#include <comphelper/sequenceashashmap.hxx> +#include <comphelper/docpasswordhelper.hxx> + #define DEBUG_MSO_ENCRYPTION_STD97 0 #if DEBUG_MSO_ENCRYPTION_STD97 #include <stdio.h> #endif +using namespace ::com::sun::star; namespace msfilter { @@ -169,6 +173,37 @@ void MSCodec_Xor95::InitKey( const sal_uInt8 pnPassData[ 16 ] ) } } +sal_Bool MSCodec_Xor95::InitCodec( const uno::Sequence< beans::NamedValue >& aData ) +{ + sal_Bool bResult = sal_False; + + ::comphelper::SequenceAsHashMap aHashData( aData ); + uno::Sequence< sal_Int8 > aKey = aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95EncryptionKey" ) ), uno::Sequence< sal_Int8 >() ); + + if ( aKey.getLength() == 16 ) + { + (void)memcpy( mpnKey, aKey.getConstArray(), 16 ); + bResult = sal_True; + + mnKey = (sal_uInt16)aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95BaseKey" ) ), (sal_Int16)0 ); + mnHash = (sal_uInt16)aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95PasswordHash" ) ), (sal_Int16)0 ); + } + else + OSL_ENSURE( sal_False, "Unexpected key size!\n" ); + + return bResult; +} + +uno::Sequence< beans::NamedValue > MSCodec_Xor95::GetEncryptionData() +{ + ::comphelper::SequenceAsHashMap aHashData; + aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95EncryptionKey" ) ) ] <<= uno::Sequence<sal_Int8>( (sal_Int8*)mpnKey, 16 ); + aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95BaseKey" ) ) ] <<= (sal_Int16)mnKey; + aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95PasswordHash" ) ) ] <<= (sal_Int16)mnHash; + + return aHashData.getAsConstNamedValueList(); +} + bool MSCodec_Xor95::VerifyKey( sal_uInt16 nKey, sal_uInt16 nHash ) const { return (nKey == mnKey) && (nHash == mnHash); @@ -218,11 +253,6 @@ void MSCodec_Xor95::Skip( sal_Size nBytes ) mnOffset = (mnOffset + nBytes) & 0x0F; } -sal_uInt16 MSCodec_Xor95::GetHash( const sal_uInt8* pnPassData, sal_Size nSize ) -{ - return lclGetHash( pnPassData, nSize ); -} - // ============================================================================ MSCodec_Std97::MSCodec_Std97 () @@ -236,15 +266,18 @@ MSCodec_Std97::MSCodec_Std97 () OSL_ASSERT(m_hDigest != 0); (void)memset (m_pDigestValue, 0, sizeof(m_pDigestValue)); + (void)memset (m_pDocId, 0, sizeof(m_pDocId)); } MSCodec_Std97::~MSCodec_Std97 () { (void)memset (m_pDigestValue, 0, sizeof(m_pDigestValue)); + (void)memset (m_pDocId, 0, sizeof(m_pDocId)); rtl_digest_destroy (m_hDigest); rtl_cipher_destroy (m_hCipher); } +#if 0 #if DEBUG_MSO_ENCRYPTION_STD97 static void lcl_PrintKeyData(const sal_uInt8* pKeyData, const char* msg) { @@ -261,6 +294,7 @@ static void lcl_PrintKeyData(const sal_uInt8* /*pKeyData*/, const char* /*msg*/) { } #endif +#endif #if DEBUG_MSO_ENCRYPTION_STD97 static void lcl_PrintDigest(const sal_uInt8* pDigest, const char* msg) @@ -276,65 +310,65 @@ static void lcl_PrintDigest(const sal_uInt8* /*pDigest*/, const char* /*msg*/) } #endif -void MSCodec_Std97::InitKey ( - const sal_uInt16 pPassData[16], - const sal_uInt8 pUnique[16]) +sal_Bool MSCodec_Std97::InitCodec( const uno::Sequence< beans::NamedValue >& aData ) { #if DEBUG_MSO_ENCRYPTION_STD97 - fprintf(stdout, "MSCodec_Std97::InitKey: --begin\n");fflush(stdout); + fprintf(stdout, "MSCodec_Std97::InitCodec: --begin\n");fflush(stdout); #endif - sal_uInt8 pKeyData[64]; - int i, n; + sal_Bool bResult = sal_False; - // Fill PassData into KeyData. - (void)memset (pKeyData, 0, sizeof(pKeyData)); - lcl_PrintKeyData(pKeyData, "initial"); - for (i = 0, n = 16; (i < n) && pPassData[i]; i++) - { - pKeyData[2*i ] = sal::static_int_cast< sal_uInt8 >( - (pPassData[i] >> 0) & 0xff); - pKeyData[2*i + 1] = sal::static_int_cast< sal_uInt8 >( - (pPassData[i] >> 8) & 0xff); - } - pKeyData[2*i] = 0x80; - pKeyData[ 56] = sal::static_int_cast< sal_uInt8 >(i << 4); + ::comphelper::SequenceAsHashMap aHashData( aData ); + uno::Sequence< sal_Int8 > aKey = aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97EncryptionKey" ) ), uno::Sequence< sal_Int8 >() ); - lcl_PrintKeyData(pKeyData, "password data"); - - // Fill raw digest of KeyData into KeyData. - (void)rtl_digest_updateMD5 ( - m_hDigest, pKeyData, sizeof(pKeyData)); - (void)rtl_digest_rawMD5 ( - m_hDigest, pKeyData, RTL_DIGEST_LENGTH_MD5); - - lcl_PrintKeyData(pKeyData, "raw digest of key data"); - - // Update digest with KeyData and Unique. - for (i = 0; i < 16; i++) + if ( aKey.getLength() == RTL_DIGEST_LENGTH_MD5 ) { - rtl_digest_updateMD5 (m_hDigest, pKeyData, 5); - rtl_digest_updateMD5 (m_hDigest, pUnique, 16); + (void)memcpy( m_pDigestValue, aKey.getConstArray(), RTL_DIGEST_LENGTH_MD5 ); + uno::Sequence< sal_Int8 > aUniqueID = aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97UniqueID" ) ), uno::Sequence< sal_Int8 >() ); + if ( aUniqueID.getLength() == 16 ) + { + (void)memcpy( m_pDocId, aUniqueID.getConstArray(), 16 ); + bResult = sal_True; + lcl_PrintDigest(m_pDigestValue, "digest value"); + lcl_PrintDigest(m_pDocId, "DocId value"); + } + else + OSL_ENSURE( sal_False, "Unexpected document ID!\n" ); } + else + OSL_ENSURE( sal_False, "Unexpected key size!\n" ); - // Update digest with padding. - pKeyData[16] = 0x80; - (void)memset (pKeyData + 17, 0, sizeof(pKeyData) - 17); - pKeyData[56] = 0x80; - pKeyData[57] = 0x0a; + return bResult; +} - lcl_PrintKeyData(pKeyData, "update digest with padding"); +uno::Sequence< beans::NamedValue > MSCodec_Std97::GetEncryptionData() +{ + ::comphelper::SequenceAsHashMap aHashData; + aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97EncryptionKey" ) ) ] <<= uno::Sequence< sal_Int8 >( (sal_Int8*)m_pDigestValue, RTL_DIGEST_LENGTH_MD5 ); + aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97UniqueID" ) ) ] <<= uno::Sequence< sal_Int8 >( (sal_Int8*)m_pDocId, 16 ); - rtl_digest_updateMD5 ( - m_hDigest, &(pKeyData[16]), sizeof(pKeyData) - 16); + return aHashData.getAsConstNamedValueList(); +} +void MSCodec_Std97::InitKey ( + const sal_uInt16 pPassData[16], + const sal_uInt8 pDocId[16]) +{ +#if DEBUG_MSO_ENCRYPTION_STD97 + fprintf(stdout, "MSCodec_Std97::InitKey: --begin\n");fflush(stdout); +#endif + uno::Sequence< sal_Int8 > aKey = ::comphelper::DocPasswordHelper::GenerateStd97Key( pPassData, uno::Sequence< sal_Int8 >( (sal_Int8*)pDocId, 16 ) ); // Fill raw digest of above updates into DigestValue. - rtl_digest_rawMD5 ( - m_hDigest, m_pDigestValue, sizeof(m_pDigestValue)); + + if ( aKey.getLength() == sizeof(m_pDigestValue) ) + (void)memcpy ( m_pDigestValue, aKey.getConstArray(), sizeof(m_pDigestValue) ); + else + memset( m_pDigestValue, 0, sizeof(m_pDigestValue) ); lcl_PrintDigest(m_pDigestValue, "digest value"); - // Erase KeyData array and leave. - (void)memset (pKeyData, 0, sizeof(pKeyData)); + (void)memcpy (m_pDocId, pDocId, 16); + + lcl_PrintDigest(m_pDocId, "DocId value"); } bool MSCodec_Std97::VerifyKey ( @@ -411,7 +445,7 @@ bool MSCodec_Std97::InitCipher (sal_uInt32 nCounter) bool MSCodec_Std97::CreateSaltDigest( const sal_uInt8 nSaltData[16], sal_uInt8 nSaltDigest[16] ) { #if DEBUG_MSO_ENCRYPTION_STD97 - lcl_PrintDigest(pSaltData, "salt data"); + lcl_PrintDigest(nSaltData, "salt data"); #endif bool result = false; @@ -528,6 +562,12 @@ void MSCodec_Std97::GetEncryptKey ( } } +void MSCodec_Std97::GetDocId( sal_uInt8 pDocId[16] ) +{ + if ( sizeof( m_pDocId ) == 16 ) + (void)memcpy( pDocId, m_pDocId, 16 ); +} + // ============================================================================ } // namespace svx diff --git a/filter/source/msfilter/msvbahelper.cxx b/filter/source/msfilter/msvbahelper.cxx index 44db464ee06d..3bbcf7b4727d 100644 --- a/filter/source/msfilter/msvbahelper.cxx +++ b/filter/source/msfilter/msvbahelper.cxx @@ -104,6 +104,24 @@ SfxObjectShell* findShellForUrl( const rtl::OUString& sMacroURLOrPath ) , rtl::OUStringToOString( xModel->getURL(), RTL_TEXTENCODING_UTF8 ).getStr() , rtl::OUStringToOString( aURL, RTL_TEXTENCODING_UTF8 ).getStr() ); + ::rtl::OUString aName = xModel->getURL() ; + if (0 == aName.getLength()) + { + + const static rtl::OUString sTitle( RTL_CONSTASCII_USTRINGPARAM("Title" ) ); + uno::Reference< frame::XFrame > xFrame( xModel->getCurrentController()->getFrame(), uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xProps( xFrame, uno::UNO_QUERY_THROW ); + xProps->getPropertyValue(sTitle) >>= aName; + sal_Int32 pos = 0; + aName = aName.getToken(0,'-',pos); + aName = aName.trim(); + if( sMacroURLOrPath.lastIndexOf( aName ) >= 0 ) + { + pFoundShell = pShell; + break; + } + } + if ( sMacroURLOrPath.endsWithIgnoreAsciiCaseAsciiL( ".dot", 4 ) ) { uno::Reference< document::XDocumentInfoSupplier > xDocInfoSupp( xModel, uno::UNO_QUERY ); @@ -264,10 +282,13 @@ MacroResolvedInfo resolveVBAMacro( SfxObjectShell* pShell, const rtl::OUString& // macro format = Container.Module.Procedure String sContainer, sModule, sProcedure; parseMacro( aMacroName, sContainer, sModule, sProcedure ); - uno::Reference< lang::XMultiServiceFactory> xSF( pShell->GetModel(), uno::UNO_QUERY); uno::Reference< container::XNameContainer > xPrjNameCache; - if ( xSF.is() ) - xPrjNameCache.set( xSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAProjectNameProvider" ) ) ), uno::UNO_QUERY ); + + // As long as service VBAProjectNameProvider isn't supported in the model, disable the createInstance call + // (the ServiceNotRegisteredException is wrongly caught in ScModelObj::createInstance) + //uno::Reference< lang::XMultiServiceFactory> xSF( pShell->GetModel(), uno::UNO_QUERY); + //if ( xSF.is() ) + // xPrjNameCache.set( xSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAProjectNameProvider" ) ) ), uno::UNO_QUERY ); std::vector< rtl::OUString > sSearchList; @@ -404,6 +425,7 @@ sal_Bool executeMacro( SfxObjectShell* pShell, const String& sMacroName, uno::Se } return bRes; } + // ============================================================================ uno::Sequence< ::rtl::OUString > VBAMacroResolver_getSupportedServiceNames() diff --git a/filter/source/msfilter/svdfppt.cxx b/filter/source/msfilter/svdfppt.cxx index f334c86bbc5f..05f99aa36813 100644 --- a/filter/source/msfilter/svdfppt.cxx +++ b/filter/source/msfilter/svdfppt.cxx @@ -1468,12 +1468,16 @@ SdrPowerPointImport::SdrPowerPointImport( PowerPointImportParam& rParam, const S if ( bOk ) { - // PersistPtrs lesen (alle) - nPersistPtrAnz = aUserEditAtom.nMaxPersistWritten + 1; // 1 mehr, damit ich immer direkt indizieren kann - pPersistPtr = new UINT32[ nPersistPtrAnz ]; // (die fangen naemlich eigentlich bei 1 an) + nPersistPtrAnz = aUserEditAtom.nMaxPersistWritten + 1; + if ( ( nPersistPtrAnz >> 2 ) > nStreamLen ) // sj: at least nPersistPtrAnz is not allowed to be greater than filesize + bOk = FALSE; // (it should not be greater than the PPT_PST_PersistPtrIncrementalBlock, but + // we are reading this block later, so we do not have access yet) + + if ( bOk && ( nPersistPtrAnz < ( SAL_MAX_UINT32 / sizeof( UINT32 ) ) ) ) + pPersistPtr = new (std::nothrow) UINT32[ nPersistPtrAnz ]; if ( !pPersistPtr ) bOk = FALSE; - else + if ( bOk ) { memset( pPersistPtr, 0x00, nPersistPtrAnz * 4 ); @@ -5087,8 +5091,8 @@ void PPTStyleTextPropReader::ReadParaProps( SvStream& rIn, SdrPowerPointImport& rIn >> nCharCount >> aParaPropSet.pParaSet->mnDepth; // Einruecktiefe - aParaPropSet.pParaSet->mnDepth = - std::min(sal_uInt16(9), + aParaPropSet.pParaSet->mnDepth = // taking care of about using not more than 9 outliner levels + std::min(sal_uInt16(8), aParaPropSet.pParaSet->mnDepth); nCharCount--; diff --git a/filter/source/msfilter/svxmsbas.cxx b/filter/source/msfilter/svxmsbas.cxx index 5214b2d022c3..d17af3b2681b 100644 --- a/filter/source/msfilter/svxmsbas.cxx +++ b/filter/source/msfilter/svxmsbas.cxx @@ -252,14 +252,12 @@ BOOL SvxImportMSVBasic::ImportCode_Impl( const String& rStorageName, Reference<XLibraryContainer> xLibContainer = rDocSh.GetBasicContainer(); DBG_ASSERT( xLibContainer.is(), "No BasicContainer!" ); + /* Set library container to VBA compatibility mode. This will create + the VBA Globals object and store it in the Basic manager of the + document. */ if( !bAsComment ) try { - Reference< vba::XVBACompatibility > xVBACompat( xLibContainer, UNO_QUERY_THROW ); - xVBACompat->setVBACompatibilityMode( sal_True ); - /* Force creation of the VBAGlobals object, each application will - create the right one and store it at the Basic manager. */ - Reference< XMultiServiceFactory > xFactory( rDocSh.GetModel(), UNO_QUERY_THROW ); - xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAGlobals" ) ) ); + Reference< vba::XVBACompatibility >( xLibContainer, UNO_QUERY_THROW )->setVBACompatibilityMode( sal_True ); } catch( Exception& ) { diff --git a/filter/source/pdf/impdialog.cxx b/filter/source/pdf/impdialog.cxx index bb125bd37a47..1adbbc63619c 100644 --- a/filter/source/pdf/impdialog.cxx +++ b/filter/source/pdf/impdialog.cxx @@ -33,7 +33,9 @@ #include "vcl/svapp.hxx" #include "vcl/msgbox.hxx" #include "sfx2/passwd.hxx" -#include "com/sun/star/uno/Sequence.hxx" + +#include "comphelper/storagehelper.hxx" + #include "com/sun/star/text/XTextRange.hpp" #include "com/sun/star/drawing/XShapes.hpp" #include "com/sun/star/container/XIndexAccess.hpp" @@ -382,8 +384,8 @@ Sequence< PropertyValue > ImpPDFTabDialog::GetFilterData() nElementAdded--; // add the open password - aRet[ aRet.getLength() - nElementAdded ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentOpenPassword" ) ); - aRet[ aRet.getLength() - nElementAdded ].Value <<= OUString( msUserPassword ); + aRet[ aRet.getLength() - nElementAdded ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "PreparedPasswords" ) ); + aRet[ aRet.getLength() - nElementAdded ].Value <<= mxPreparedPasswords; nElementAdded--; //the restrict permission flag (needed to have the scripting consistent with the dialog) @@ -392,8 +394,8 @@ Sequence< PropertyValue > ImpPDFTabDialog::GetFilterData() nElementAdded--; //add the permission password - aRet[ aRet.getLength() - nElementAdded ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "PermissionPassword" ) ); - aRet[ aRet.getLength() - nElementAdded ].Value <<= OUString( msOwnerPassword ); + aRet[ aRet.getLength() - nElementAdded ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "PreparedPermissionPassword" ) ); + aRet[ aRet.getLength() - nElementAdded ].Value <<= maPreparedOwnerPassword; nElementAdded--; // this should be the last added... @@ -1017,12 +1019,12 @@ void ImpPDFTabViewerPage::SetFilterConfigItem( const ImpPDFTabDialog* paParent ImpPDFTabSecurityPage::ImpPDFTabSecurityPage( Window* i_pParent, const SfxItemSet& i_rCoreSet ) : SfxTabPage( i_pParent, PDFFilterResId( RID_PDF_TAB_SECURITY ), i_rCoreSet ), - maPbUserPwd( this, PDFFilterResId( BTN_USER_PWD ) ), + maFlGroup( this, PDFFilterResId( FL_PWD_GROUP ) ), + maPbSetPwd( this, PDFFilterResId( BTN_SET_PWD ) ), maFtUserPwd( this, PDFFilterResId( FT_USER_PWD ) ), maUserPwdSet( PDFFilterResId( STR_USER_PWD_SET ) ), maUserPwdUnset( PDFFilterResId( STR_USER_PWD_UNSET ) ), - - maPbOwnerPwd( this, PDFFilterResId( BTN_OWNER_PWD ) ), + maStrSetPwd( PDFFilterResId( STR_SET_PWD ) ), maFtOwnerPwd( this, PDFFilterResId( FT_OWNER_PWD ) ), maOwnerPwdSet( PDFFilterResId( STR_OWNER_PWD_SET ) ), maOwnerPwdUnset( PDFFilterResId( STR_OWNER_PWD_UNSET ) ), @@ -1043,6 +1045,8 @@ ImpPDFTabSecurityPage::ImpPDFTabSecurityPage( Window* i_pParent, maCbEnableAccessibility( this, PDFFilterResId( CB_ENAB_ACCESS ) ), msUserPwdTitle( PDFFilterResId( STR_PDF_EXPORT_UDPWD ) ), + mbHaveOwnerPassword( false ), + mbHaveUserPassword( false ), msOwnerPwdTitle( PDFFilterResId( STR_PDF_EXPORT_ODPWD ) ) { @@ -1081,6 +1085,8 @@ ImpPDFTabSecurityPage::ImpPDFTabSecurityPage( Window* i_pParent, (*pCurrent++)->SetPosPixel( aNewPos ); } } + + maPbSetPwd.SetClickHdl( LINK( this, ImpPDFTabSecurityPage, ClickmaPbSetPwdHdl ) ); } // ----------------------------------------------------------------------------- @@ -1100,13 +1106,11 @@ void ImpPDFTabSecurityPage::GetFilterConfigItem( ImpPDFTabDialog* paParent ) { // please note that in PDF/A-1a mode even if this are copied back, // the security settings are forced disabled in PDFExport::Export - paParent->mbEncrypt = (msUserPassword.Len() > 0); - if( paParent->mbEncrypt ) - paParent->msUserPassword = msUserPassword; + paParent->mbEncrypt = mbHaveUserPassword; + paParent->mxPreparedPasswords = mxPreparedPasswords; - paParent->mbRestrictPermissions = (msOwnerPassword.Len() > 0); - if( msOwnerPassword.Len() > 0 ) - paParent->msOwnerPassword = msOwnerPassword; + paParent->mbRestrictPermissions = mbHaveOwnerPassword; + paParent->maPreparedOwnerPassword = maPreparedOwnerPassword; //verify print status paParent->mnPrint = 0; @@ -1135,10 +1139,6 @@ void ImpPDFTabSecurityPage::GetFilterConfigItem( ImpPDFTabDialog* paParent ) // ----------------------------------------------------------------------------- void ImpPDFTabSecurityPage::SetFilterConfigItem( const ImpPDFTabDialog* paParent ) { - maPbUserPwd.SetClickHdl( LINK( this, ImpPDFTabSecurityPage, ClickmaPbUserPwdHdl ) ); - - maPbOwnerPwd.SetClickHdl( LINK( this, ImpPDFTabSecurityPage, ClickmaPbOwnerPwdHdl ) ); - switch( paParent->mnPrint ) { default: @@ -1184,39 +1184,44 @@ void ImpPDFTabSecurityPage::SetFilterConfigItem( const ImpPDFTabDialog* paParen !( ( ImpPDFTabGeneralPage* )paParent->GetTabPage( RID_PDF_TAB_GENER ) )->IsPdfaSelected() ); } -//method common to both the password entry procedures -void ImpPDFTabSecurityPage::ImplPwdPushButton( const String & i_rDlgTitle, String & io_rDestPassword ) +IMPL_LINK( ImpPDFTabSecurityPage, ClickmaPbSetPwdHdl, void*, EMPTYARG ) { -// string needed: dialog title, message box text, depending on the button clicked - SfxPasswordDialog aPwdDialog( this ); + SfxPasswordDialog aPwdDialog( this, &msUserPwdTitle ); aPwdDialog.SetMinLen( 0 ); - aPwdDialog.ShowExtras( SHOWEXTRAS_CONFIRM ); - aPwdDialog.SetText( i_rDlgTitle ); + aPwdDialog.ShowExtras( SHOWEXTRAS_CONFIRM | SHOWEXTRAS_PASSWORD2 | SHOWEXTRAS_CONFIRM2 ); + aPwdDialog.SetText( maStrSetPwd ); + aPwdDialog.SetGroup2Text( msOwnerPwdTitle ); aPwdDialog.AllowAsciiOnly(); if( aPwdDialog.Execute() == RET_OK ) //OK issued get password and set it - io_rDestPassword = aPwdDialog.GetPassword(); - enablePermissionControls(); -} + { + rtl::OUString aUserPW( aPwdDialog.GetPassword() ); + rtl::OUString aOwnerPW( aPwdDialog.GetPassword2() ); -IMPL_LINK( ImpPDFTabSecurityPage, ClickmaPbUserPwdHdl, void*, EMPTYARG ) -{ - ImplPwdPushButton(msUserPwdTitle, msUserPassword ); - return 0; -} + mbHaveUserPassword = (aUserPW.getLength() != 0); + mbHaveOwnerPassword = (aOwnerPW.getLength() != 0); -IMPL_LINK( ImpPDFTabSecurityPage, ClickmaPbOwnerPwdHdl, void*, EMPTYARG ) -{ - ImplPwdPushButton( msOwnerPwdTitle, msOwnerPassword ); + mxPreparedPasswords = vcl::PDFWriter::InitEncryption( aOwnerPW, aUserPW, true ); + + if( mbHaveOwnerPassword ) + { + maPreparedOwnerPassword = comphelper::OStorageHelper::CreatePackageEncryptionData( aOwnerPW ); + } + else + maPreparedOwnerPassword = Sequence< NamedValue >(); + // trash clear text passwords string memory + rtl_zeroMemory( (void*)aUserPW.getStr(), aUserPW.getLength() ); + rtl_zeroMemory( (void*)aOwnerPW.getStr(), aOwnerPW.getLength() ); + } + enablePermissionControls(); return 0; } void ImpPDFTabSecurityPage::enablePermissionControls() { - maFtUserPwd.SetText( (msUserPassword.Len() > 0 && IsEnabled()) ? maUserPwdSet : maUserPwdUnset ); - - sal_Bool bLocalEnable = (msOwnerPassword.Len() > 0) && IsEnabled(); + maFtUserPwd.SetText( (mbHaveUserPassword && IsEnabled()) ? maUserPwdSet : maUserPwdUnset ); + sal_Bool bLocalEnable = mbHaveOwnerPassword && IsEnabled(); maFtOwnerPwd.SetText( bLocalEnable ? maOwnerPwdSet : maOwnerPwdUnset ); maFlPrintPermissions.Enable( bLocalEnable ); diff --git a/filter/source/pdf/impdialog.hrc b/filter/source/pdf/impdialog.hrc index cc438255650f..dccdc2cad11b 100644 --- a/filter/source/pdf/impdialog.hrc +++ b/filter/source/pdf/impdialog.hrc @@ -144,14 +144,15 @@ #define NUM_BOOKMARKLEVELS 114 //controls for security preferences tab page -#define BTN_USER_PWD 120 +#define FL_PWD_GROUP 119 +#define BTN_SET_PWD 120 #define FT_USER_PWD 121 #define STR_USER_PWD_SET 122 #define STR_USER_PWD_ENC 123 #define STR_USER_PWD_UNSET 124 #define STR_USER_PWD_UNENC 125 +#define STR_SET_PWD 126 -#define BTN_OWNER_PWD 127 #define FT_OWNER_PWD 128 #define STR_OWNER_PWD_SET 129 #define STR_OWNER_PWD_REST 130 diff --git a/filter/source/pdf/impdialog.hxx b/filter/source/pdf/impdialog.hxx index 38da273c2fbd..3fd98c775e0d 100644 --- a/filter/source/pdf/impdialog.hxx +++ b/filter/source/pdf/impdialog.hxx @@ -44,6 +44,8 @@ #include "sfx2/tabdlg.hxx" +#include "com/sun/star/beans/NamedValue.hpp" + // ---------------- // - ImpPDFDialog - // ---------------- @@ -126,14 +128,14 @@ protected: sal_Bool mbFirstPageLeft; sal_Bool mbEncrypt; - String msUserPassword; sal_Bool mbRestrictPermissions; - String msOwnerPassword; + com::sun::star::uno::Sequence< com::sun::star::beans::NamedValue > maPreparedOwnerPassword; sal_Int32 mnPrint; sal_Int32 mnChangesAllowed; sal_Bool mbCanCopyOrExtract; sal_Bool mbCanExtractForAccessibility; + com::sun::star::uno::Reference< com::sun::star::beans::XMaterialHolder > mxPreparedPasswords; sal_Bool mbIsRangeChecked; String msPageRange; @@ -314,12 +316,13 @@ public: //class security tab page class ImpPDFTabSecurityPage : public SfxTabPage { - PushButton maPbUserPwd; + FixedLine maFlGroup; + PushButton maPbSetPwd; FixedText maFtUserPwd; String maUserPwdSet; String maUserPwdUnset; + String maStrSetPwd; - PushButton maPbOwnerPwd; FixedText maFtOwnerPwd; String maOwnerPwdSet; String maOwnerPwdUnset; @@ -339,16 +342,18 @@ class ImpPDFTabSecurityPage : public SfxTabPage CheckBox maCbEnableCopy; CheckBox maCbEnableAccessibility; - String msUserPassword; String msUserPwdTitle; - String msOwnerPassword; + bool mbHaveOwnerPassword; + bool mbHaveUserPassword; + com::sun::star::uno::Sequence< com::sun::star::beans::NamedValue > maPreparedOwnerPassword; String msOwnerPwdTitle; + com::sun::star::uno::Reference< com::sun::star::beans::XMaterialHolder > mxPreparedPasswords; + long nWidth; - DECL_LINK( ClickmaPbUserPwdHdl, void* ); - DECL_LINK( ClickmaPbOwnerPwdHdl, void* ); + DECL_LINK( ClickmaPbSetPwdHdl, void* ); void enablePermissionControls(); diff --git a/filter/source/pdf/impdialog.src b/filter/source/pdf/impdialog.src index 248d7d8491f7..1c941d6a9972 100644 --- a/filter/source/pdf/impdialog.src +++ b/filter/source/pdf/impdialog.src @@ -39,13 +39,13 @@ String STR_PDF_EXPORT //password dialog title String STR_PDF_EXPORT_UDPWD { - Text[ en-US ] = "Set Open Password"; + Text[ en-US ] = "Set open password"; }; //password dialog title String STR_PDF_EXPORT_ODPWD { - Text[ en-US ] = "Set Permission Password"; + Text[ en-US ] = "Set permission password"; }; ////////////////////////////////////////////////////////////// @@ -561,20 +561,29 @@ TabPage RID_PDF_TAB_SECURITY TAB_PDF_SIZE; Hide = TRUE; -////////////////////////////////////// - PushButton BTN_USER_PWD + FixedLine FL_PWD_GROUP + { + Pos = MAP_APPFONT( 5, 5 ); + Size = MAP_APPFONT( 125, 10 ); + Text[ en-US ] = "File encryption and permission"; + }; + PushButton BTN_SET_PWD { - HelpID = "filter:PushButton:RID_PDF_TAB_SECURITY:BTN_USER_PWD"; + HelpID = "filter:PushButton:RID_PDF_TAB_SECURITY:BTN_PWD"; TabStop = TRUE ; Disable = TRUE ; - Pos = MAP_APPFONT ( 12, 5 ) ; + Pos = MAP_APPFONT ( 12, 20 ) ; Size = MAP_APPFONT ( 120 , 13 ) ; - Text[ en-US ] = "Set ~open password..."; + Text[ en-US ] = "Set ~passwords..."; + }; + String STR_SET_PWD + { + Text[ en-US ] = "Set passwords"; }; FixedText FT_USER_PWD { - Pos = MAP_APPFONT(12 , 25 ); + Pos = MAP_APPFONT(12 , 40 ); Size = MAP_APPFONT( 160, 20 ); }; @@ -598,16 +607,6 @@ TabPage RID_PDF_TAB_SECURITY Text [ en-US ] = "PDF document will not be encrypted"; }; - PushButton BTN_OWNER_PWD - { - HelpID = "filter:PushButton:RID_PDF_TAB_SECURITY:BTN_OWNER_PWD"; - TabStop = TRUE ; - Disable = TRUE ; - Pos = MAP_APPFONT ( 12, 45 ) ; - Size = MAP_APPFONT ( 120 , 13 ) ; - Text[ en-US ] = "Set ~permission password..."; - }; - FixedText FT_OWNER_PWD { Pos = MAP_APPFONT( 12 , 65 ); diff --git a/filter/source/pdf/makefile.mk b/filter/source/pdf/makefile.mk index 776729ac0d97..65028c7d5d8d 100644 --- a/filter/source/pdf/makefile.mk +++ b/filter/source/pdf/makefile.mk @@ -47,6 +47,7 @@ SLOFILES= $(SLO)$/pdfuno.obj \ $(SLO)$/pdfdialog.obj \ $(SLO)$/impdialog.obj \ $(SLO)$/pdffilter.obj \ + $(SLO)$/pdfinteract.obj \ $(SLO)$/pdfexport.obj # --- Library ----------------------------------- diff --git a/filter/source/pdf/pdfexport.cxx b/filter/source/pdf/pdfexport.cxx index a8d4e1d0d14c..382dd12eeb83 100644 --- a/filter/source/pdf/pdfexport.cxx +++ b/filter/source/pdf/pdfexport.cxx @@ -32,49 +32,58 @@ #include "impdialog.hxx" #include "pdf.hrc" -#include <tools/urlobj.hxx> -#include <tools/fract.hxx> -#include <tools/poly.hxx> -#include <vcl/mapmod.hxx> -#include <vcl/virdev.hxx> -#include <vcl/metaact.hxx> -#include <vcl/gdimtf.hxx> -#include <vcl/jobset.hxx> -#include <vcl/salbtype.hxx> -#include <vcl/bmpacc.hxx> +#include "tools/urlobj.hxx" +#include "tools/fract.hxx" +#include "tools/poly.hxx" +#include "vcl/mapmod.hxx" +#include "vcl/virdev.hxx" +#include "vcl/metaact.hxx" +#include "vcl/gdimtf.hxx" +#include "vcl/jobset.hxx" +#include "vcl/salbtype.hxx" +#include "vcl/bmpacc.hxx" #include "vcl/svapp.hxx" -#include <toolkit/awt/vclxdevice.hxx> -#include <unotools/localfilehelper.hxx> -#include <unotools/processfactory.hxx> -#include <svtools/FilterConfigItem.hxx> -#include <svtools/filter.hxx> -#include <svl/solar.hrc> -#include <comphelper/string.hxx> -#include <unotools/streamwrap.hxx> -#include <com/sun/star/io/XSeekable.hpp> +#include "toolkit/awt/vclxdevice.hxx" +#include "unotools/localfilehelper.hxx" +#include "unotools/processfactory.hxx" +#include "svtools/FilterConfigItem.hxx" +#include "svtools/filter.hxx" +#include "svl/solar.hrc" +#include "comphelper/string.hxx" +#include "comphelper/storagehelper.hxx" +#include "unotools/streamwrap.hxx" +#include "com/sun/star/io/XSeekable.hpp" + #include "basegfx/polygon/b2dpolygon.hxx" #include "basegfx/polygon/b2dpolypolygon.hxx" #include "basegfx/polygon/b2dpolygontools.hxx" -#include <unotools/saveopt.hxx> // only for testing of relative saving options in PDF - -#include <vcl/graphictools.hxx> -#include <com/sun/star/beans/XPropertySet.hpp> -#include <com/sun/star/awt/Rectangle.hpp> -#include <com/sun/star/awt/XDevice.hpp> -#include <com/sun/star/util/MeasureUnit.hpp> -#include <com/sun/star/frame/XModel.hpp> -#include <com/sun/star/frame/XModuleManager.hpp> -#include <com/sun/star/frame/XStorable.hpp> -#include <com/sun/star/frame/XController.hpp> -#include <com/sun/star/document/XDocumentProperties.hpp> -#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> -#include <com/sun/star/container/XNameAccess.hpp> -#include <com/sun/star/view/XViewSettingsSupplier.hpp> -#include <unotools/configmgr.hxx> -#include <com/sun/star/lang/XServiceInfo.hpp> -#include <com/sun/star/drawing/XShapes.hpp> -#include <com/sun/star/graphic/XGraphicProvider.hpp> +#include "unotools/saveopt.hxx" // only for testing of relative saving options in PDF + +#include "vcl/graphictools.hxx" +#include "com/sun/star/beans/XPropertySet.hpp" +#include "com/sun/star/awt/Rectangle.hpp" +#include "com/sun/star/awt/XDevice.hpp" +#include "com/sun/star/util/MeasureUnit.hpp" +#include "com/sun/star/frame/XModel.hpp" +#include "com/sun/star/frame/XModuleManager.hpp" +#include "com/sun/star/frame/XStorable.hpp" +#include "com/sun/star/frame/XController.hpp" +#include "com/sun/star/document/XDocumentProperties.hpp" +#include "com/sun/star/document/XDocumentPropertiesSupplier.hpp" +#include "com/sun/star/container/XNameAccess.hpp" +#include "com/sun/star/view/XViewSettingsSupplier.hpp" +#include "com/sun/star/task/XInteractionRequest.hpp" +#include "com/sun/star/task/PDFExportException.hpp" + +#include "unotools/configmgr.hxx" +#include "cppuhelper/exc_hlp.hxx" +#include "cppuhelper/compbase1.hxx" +#include "cppuhelper/basemutex.hxx" + +#include "com/sun/star/lang/XServiceInfo.hpp" +#include "com/sun/star/drawing/XShapes.hpp" +#include "com/sun/star/graphic/XGraphicProvider.hpp" using namespace ::rtl; using namespace ::vcl; @@ -89,10 +98,14 @@ using namespace ::com::sun::star::graphic; // - PDFExport - // ------------- -PDFExport::PDFExport( const Reference< XComponent >& rxSrcDoc, Reference< task::XStatusIndicator >& rxStatusIndicator, const Reference< lang::XMultiServiceFactory >& xFactory ) : +PDFExport::PDFExport( const Reference< XComponent >& rxSrcDoc, + const Reference< task::XStatusIndicator >& rxStatusIndicator, + const Reference< task::XInteractionHandler >& rxIH, + const Reference< lang::XMultiServiceFactory >& xFactory ) : mxSrcDoc ( rxSrcDoc ), mxMSF ( xFactory ), mxStatusIndicator ( rxStatusIndicator ), + mxIH ( rxIH ), mbUseTaggedPDF ( sal_False ), mnPDFTypeSelection ( 0 ), mbExportNotes ( sal_True ), @@ -130,9 +143,7 @@ PDFExport::PDFExport( const Reference< XComponent >& rxSrcDoc, Reference< task:: mbFirstPageLeft ( sal_False ), mbEncrypt ( sal_False ), - msOpenPassword (), mbRestrictPermissions ( sal_False ), - msPermissionPassword (), mnPrintAllowed ( 2 ), mnChangesAllowed ( 4 ), mbCanCopyOrExtract ( sal_True ), @@ -250,12 +261,12 @@ sal_Bool PDFExport::ExportSelection( vcl::PDFWriter& rPDFWriter, Reference< com: class PDFExportStreamDoc : public vcl::PDFOutputStream { - Reference< XComponent > m_xSrcDoc; - rtl::OUString m_aPassWd; + Reference< XComponent > m_xSrcDoc; + Sequence< beans::NamedValue > m_aPreparedPassword; public: - PDFExportStreamDoc( const Reference< XComponent >& xDoc, const rtl::OUString& rPwd ) + PDFExportStreamDoc( const Reference< XComponent >& xDoc, const Sequence<beans::NamedValue>& rPwd ) : m_xSrcDoc( xDoc ), - m_aPassWd( rPwd ) + m_aPreparedPassword( rPwd ) {} virtual ~PDFExportStreamDoc(); @@ -271,15 +282,16 @@ void PDFExportStreamDoc::write( const Reference< XOutputStream >& xStream ) Reference< com::sun::star::frame::XStorable > xStore( m_xSrcDoc, UNO_QUERY ); if( xStore.is() ) { - Sequence< beans::PropertyValue > aArgs( m_aPassWd.getLength() ? 3 : 2 ); + Sequence< beans::PropertyValue > aArgs( 2 + ((m_aPreparedPassword.getLength() > 0) ? 1 : 0) ); aArgs.getArray()[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) ); aArgs.getArray()[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "OutputStream" ) ); aArgs.getArray()[1].Value <<= xStream; - if( m_aPassWd.getLength() ) + if( m_aPreparedPassword.getLength() ) { - aArgs.getArray()[2].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "Password" ) ); - aArgs.getArray()[2].Value <<= m_aPassWd; + aArgs.getArray()[2].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "EncryptionData" ) ); + aArgs.getArray()[2].Value <<= m_aPreparedPassword; } + try { xStore->storeToURL( OUString( RTL_CONSTASCII_USTRINGPARAM( "private:stream" ) ), @@ -390,6 +402,11 @@ sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue VCLXDevice* pXDevice = new VCLXDevice; OUString aPageRange; Any aSelection; + PDFWriter::PDFWriterContext aContext; + rtl::OUString aOpenPassword, aPermissionPassword; + Reference< beans::XMaterialHolder > xEnc; + Sequence< beans::NamedValue > aPreparedPermissionPassword; + // getting the string for the creator String aCreator; @@ -408,7 +425,34 @@ sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue aCreator.AppendAscii( "Math" ); } - PDFWriter::PDFWriterContext aContext; + Reference< document::XDocumentPropertiesSupplier > xDocumentPropsSupplier( mxSrcDoc, UNO_QUERY ); + if ( xDocumentPropsSupplier.is() ) + { + Reference< document::XDocumentProperties > xDocumentProps( xDocumentPropsSupplier->getDocumentProperties() ); + if ( xDocumentProps.is() ) + { + aContext.DocumentInfo.Title = xDocumentProps->getTitle(); + aContext.DocumentInfo.Author = xDocumentProps->getAuthor(); + aContext.DocumentInfo.Subject = xDocumentProps->getSubject(); + aContext.DocumentInfo.Keywords = ::comphelper::string::convertCommaSeparated(xDocumentProps->getKeywords()); + } + } + // getting the string for the producer + String aProducer; + ::utl::ConfigManager* pMgr = ::utl::ConfigManager::GetConfigManager(); + if ( pMgr ) + { + Any aProductName = pMgr->GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME ); + ::rtl::OUString sProductName; + aProductName >>= sProductName; + aProducer = sProductName; + aProductName = pMgr->GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTVERSION ); + aProductName >>= sProductName; + aProducer.AppendAscii(" "); + aProducer += String( sProductName ); + } + aContext.DocumentInfo.Producer = aProducer; + aContext.DocumentInfo.Creator = aCreator; for( sal_Int32 nData = 0, nDataCount = rFilterData.getLength(); nData < nDataCount; ++nData ) { @@ -482,11 +526,15 @@ sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "EncryptFile" ) ) ) rFilterData[ nData ].Value >>= mbEncrypt; else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentOpenPassword" ) ) ) - rFilterData[ nData ].Value >>= msOpenPassword; + rFilterData[ nData ].Value >>= aOpenPassword; else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "RestrictPermissions" ) ) ) rFilterData[ nData ].Value >>= mbRestrictPermissions; else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PermissionPassword" ) ) ) - rFilterData[ nData ].Value >>= msPermissionPassword; + rFilterData[ nData ].Value >>= aPermissionPassword; + else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PreparedPasswords" ) ) ) + rFilterData[ nData ].Value >>= xEnc; + else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PreparedPermissionPassword" ) ) ) + rFilterData[ nData ].Value >>= aPreparedPermissionPassword; else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "Printing" ) ) ) rFilterData[ nData ].Value >>= mnPrintAllowed; else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "Changes" ) ) ) @@ -521,14 +569,17 @@ sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue break; case 1: aContext.Version = PDFWriter::PDF_A_1; -//force the tagged PDF as well + //force the tagged PDF as well mbUseTaggedPDF = sal_True; -//force embedding of standard fonts + //force embedding of standard fonts mbEmbedStandardFonts = sal_True; -//force disabling of form conversion + //force disabling of form conversion mbExportFormFields = sal_False; -// PDF/A does not allow transparencies + // PDF/A does not allow transparencies mbRemoveTransparencies = sal_True; + // no encryption + mbEncrypt = sal_False; + xEnc.clear(); break; } @@ -604,23 +655,17 @@ sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue if( aContext.Version != PDFWriter::PDF_A_1 ) { //set values needed in encryption - aContext.Encrypt = mbEncrypt; //set encryption level, fixed, but here it can set by the UI if needed. // true is 128 bit, false 40 //note that in 40 bit mode the UI needs reworking, since the current UI is meaningfull only for //128bit security mode - aContext.Security128bit = sal_True; - -//set the open password - if( aContext.Encrypt && msOpenPassword.getLength() > 0 ) - aContext.UserPassword = msOpenPassword; + aContext.Encryption.Security128bit = sal_True; //set check for permission change password // if not enabled and no permission password, force permissions to default as if PDF where without encryption - if( mbRestrictPermissions && msPermissionPassword.getLength() > 0 ) + if( mbRestrictPermissions && (xEnc.is() || aPermissionPassword.getLength() > 0) ) { - aContext.OwnerPassword = msPermissionPassword; - aContext.Encrypt = sal_True; + mbEncrypt = sal_True; //permission set as desired, done after } else @@ -638,9 +683,9 @@ sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue break; default: case 2: - aContext.AccessPermissions.CanPrintFull = sal_True; + aContext.Encryption.CanPrintFull = sal_True; case 1: - aContext.AccessPermissions.CanPrintTheDocument = sal_True; + aContext.Encryption.CanPrintTheDocument = sal_True; break; } @@ -649,26 +694,36 @@ sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue case 0: //already in struct PDFSecPermissions CTOR break; case 1: - aContext.AccessPermissions.CanAssemble = sal_True; + aContext.Encryption.CanAssemble = sal_True; break; case 2: - aContext.AccessPermissions.CanFillInteractive = sal_True; + aContext.Encryption.CanFillInteractive = sal_True; break; case 3: - aContext.AccessPermissions.CanAddOrModify = sal_True; + aContext.Encryption.CanAddOrModify = sal_True; break; default: case 4: - aContext.AccessPermissions.CanModifyTheContent = - aContext.AccessPermissions.CanCopyOrExtract = - aContext.AccessPermissions.CanAddOrModify = - aContext.AccessPermissions.CanFillInteractive = sal_True; + aContext.Encryption.CanModifyTheContent = + aContext.Encryption.CanCopyOrExtract = + aContext.Encryption.CanAddOrModify = + aContext.Encryption.CanFillInteractive = sal_True; break; } - aContext.AccessPermissions.CanCopyOrExtract = mbCanCopyOrExtract; - aContext.AccessPermissions.CanExtractForAccessibility = mbCanExtractForAccessibility; + aContext.Encryption.CanCopyOrExtract = mbCanCopyOrExtract; + aContext.Encryption.CanExtractForAccessibility = mbCanExtractForAccessibility; + if( mbEncrypt && ! xEnc.is() ) + xEnc = PDFWriter::InitEncryption( aPermissionPassword, aOpenPassword, aContext.Encryption.Security128bit ); + if( mbEncrypt && aPermissionPassword.getLength() && ! aPreparedPermissionPassword.getLength() ) + aPreparedPermissionPassword = comphelper::OStorageHelper::CreatePackageEncryptionData( aPermissionPassword ); } + // after this point we don't need the legacy clear passwords anymore + // however they are still inside the passed filter data sequence + // which is sadly out out our control + aPermissionPassword = rtl::OUString(); + aOpenPassword = rtl::OUString(); + /* * FIXME: the entries are only implicitly defined by the resource file. Should there * ever be an additional form submit format this could get invalid. @@ -731,7 +786,7 @@ sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue //<--- } // all context data set, time to create the printing device - PDFWriter* pPDFWriter = new PDFWriter( aContext ); + PDFWriter* pPDFWriter = new PDFWriter( aContext, xEnc ); OutputDevice* pOut = pPDFWriter->GetReferenceDevice(); vcl::PDFExtOutDevData* pPDFExtOutDevData = NULL; @@ -744,41 +799,10 @@ sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue // get mimetype OUString aSrcMimetype = getMimetypeForDocument( mxMSF, mxSrcDoc ); pPDFWriter->AddStream( aSrcMimetype, - new PDFExportStreamDoc( mxSrcDoc, msPermissionPassword ), + new PDFExportStreamDoc( mxSrcDoc, aPreparedPermissionPassword ), false ); } - PDFDocInfo aDocInfo; - Reference< document::XDocumentPropertiesSupplier > xDocumentPropsSupplier( mxSrcDoc, UNO_QUERY ); - if ( xDocumentPropsSupplier.is() ) - { - Reference< document::XDocumentProperties > xDocumentProps( xDocumentPropsSupplier->getDocumentProperties() ); - if ( xDocumentProps.is() ) - { - aDocInfo.Title = xDocumentProps->getTitle(); - aDocInfo.Author = xDocumentProps->getAuthor(); - aDocInfo.Subject = xDocumentProps->getSubject(); - aDocInfo.Keywords = ::comphelper::string::convertCommaSeparated(xDocumentProps->getKeywords()); - } - } - // getting the string for the producer - String aProducer; - ::utl::ConfigManager* pMgr = ::utl::ConfigManager::GetConfigManager(); - if ( pMgr ) - { - Any aProductName = pMgr->GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME ); - ::rtl::OUString sProductName; - aProductName >>= sProductName; - aProducer = sProductName; - aProductName = pMgr->GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTVERSION ); - aProductName >>= sProductName; - aProducer.AppendAscii(" "); - aProducer += String( sProductName ); - } - aDocInfo.Producer = aProducer; - aDocInfo.Creator = aCreator; - - pPDFWriter->SetDocInfo( aDocInfo ); if ( pOut ) { @@ -926,12 +950,59 @@ sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue return bRet; } +namespace +{ + +typedef cppu::WeakComponentImplHelper1< task::XInteractionRequest > PDFErrorRequestBase; + +class PDFErrorRequest : private cppu::BaseMutex, + public PDFErrorRequestBase +{ + task::PDFExportException maExc; +public: + PDFErrorRequest( const task::PDFExportException& i_rExc ); + + // XInteractionRequest + virtual uno::Any SAL_CALL getRequest() throw (uno::RuntimeException); + virtual uno::Sequence< uno::Reference< task::XInteractionContinuation > > SAL_CALL getContinuations() throw (uno::RuntimeException); +}; + +PDFErrorRequest::PDFErrorRequest( const task::PDFExportException& i_rExc ) : + PDFErrorRequestBase( m_aMutex ), + maExc( i_rExc ) +{ +} + +uno::Any SAL_CALL PDFErrorRequest::getRequest() throw (uno::RuntimeException) +{ + osl::MutexGuard const guard( m_aMutex ); + + uno::Any aRet; + aRet <<= maExc; + return aRet; +} + +uno::Sequence< uno::Reference< task::XInteractionContinuation > > SAL_CALL PDFErrorRequest::getContinuations() throw (uno::RuntimeException) +{ + return uno::Sequence< uno::Reference< task::XInteractionContinuation > >(); +} + +} // namespace + void PDFExport::showErrors( const std::set< PDFWriter::ErrorCode >& rErrors ) { - if( ! rErrors.empty() ) + if( ! rErrors.empty() && mxIH.is() ) { - ImplErrorDialog aDlg( rErrors ); - aDlg.Execute(); + task::PDFExportException aExc; + aExc.ErrorCodes.realloc( sal_Int32(rErrors.size()) ); + sal_Int32 i = 0; + for( std::set< PDFWriter::ErrorCode >::const_iterator it = rErrors.begin(); + it != rErrors.end(); ++it, i++ ) + { + aExc.ErrorCodes.getArray()[i] = (sal_Int32)*it; + } + Reference< task::XInteractionRequest > xReq( new PDFErrorRequest( aExc ) ); + mxIH->handle( xReq ); } } @@ -939,8 +1010,15 @@ void PDFExport::showErrors( const std::set< PDFWriter::ErrorCode >& rErrors ) sal_Bool PDFExport::ImplExportPage( PDFWriter& rWriter, PDFExtOutDevData& rPDFExtOutDevData, const GDIMetaFile& rMtf ) { - vcl::PDFWriter::PlayMetafileContext aCtx; + const Size aSizePDF( OutputDevice::LogicToLogic( rMtf.GetPrefSize(), rMtf.GetPrefMapMode(), MAP_POINT ) ); + Point aOrigin; + Rectangle aPageRect( aOrigin, rMtf.GetPrefSize() ); + sal_Bool bRet = sal_True; + + rWriter.NewPage( aSizePDF.Width(), aSizePDF.Height() ); + rWriter.SetMapMode( rMtf.GetPrefMapMode() ); + vcl::PDFWriter::PlayMetafileContext aCtx; GDIMetaFile aMtf; if( mbRemoveTransparencies ) { @@ -957,14 +1035,6 @@ sal_Bool PDFExport::ImplExportPage( PDFWriter& rWriter, PDFExtOutDevData& rPDFEx aCtx.m_nJPEGQuality = mnQuality; - const Size aSizePDF( OutputDevice::LogicToLogic( rMtf.GetPrefSize(), rMtf.GetPrefMapMode(), MAP_POINT ) ); - Point aOrigin; - Rectangle aPageRect( aOrigin, rMtf.GetPrefSize() ); - sal_Bool bRet = sal_True; - - rWriter.NewPage( aSizePDF.Width(), aSizePDF.Height() ); - rWriter.SetMapMode( rMtf.GetPrefMapMode() ); - basegfx::B2DRectangle aB2DRect( aPageRect.Left(), aPageRect.Top(), aPageRect.Right(), aPageRect.Bottom() ); rWriter.SetClipRegion( basegfx::B2DPolyPolygon( basegfx::tools::createPolygonFromRect( aB2DRect ) ) ); diff --git a/filter/source/pdf/pdfexport.hxx b/filter/source/pdf/pdfexport.hxx index 71bee383133c..5b07a50765b1 100644 --- a/filter/source/pdf/pdfexport.hxx +++ b/filter/source/pdf/pdfexport.hxx @@ -56,6 +56,7 @@ private: Reference< XComponent > mxSrcDoc; Reference< lang::XMultiServiceFactory > mxMSF; Reference< task::XStatusIndicator > mxStatusIndicator; + Reference< task::XInteractionHandler > mxIH; sal_Bool mbUseTaggedPDF; sal_Int32 mnPDFTypeSelection; @@ -98,9 +99,7 @@ private: sal_Bool mbFirstPageLeft; sal_Bool mbEncrypt; - rtl::OUString msOpenPassword; sal_Bool mbRestrictPermissions; - rtl::OUString msPermissionPassword; sal_Int32 mnPrintAllowed; sal_Int32 mnChangesAllowed; sal_Bool mbCanCopyOrExtract; @@ -120,7 +119,10 @@ private: void ImplWriteWatermark( ::vcl::PDFWriter& rWriter, const Size& rPageSize ); public: - PDFExport( const Reference< XComponent >& rxSrcDoc, Reference< task::XStatusIndicator >& xStatusIndicator, const Reference< lang::XMultiServiceFactory >& xFact ); + PDFExport( const Reference< XComponent >& rxSrcDoc, + const Reference< task::XStatusIndicator >& xStatusIndicator, + const Reference< task::XInteractionHandler >& xIH, + const Reference< lang::XMultiServiceFactory >& xFact ); ~PDFExport(); sal_Bool ExportSelection( vcl::PDFWriter& rPDFWriter, Reference< com::sun::star::view::XRenderable >& rRenderable, Any& rSelection, diff --git a/filter/source/pdf/pdffilter.component b/filter/source/pdf/pdffilter.component index 36766b61eb97..438d697a77b1 100644 --- a/filter/source/pdf/pdffilter.component +++ b/filter/source/pdf/pdffilter.component @@ -34,4 +34,7 @@ <implementation name="com.sun.star.comp.PDF.PDFFilter"> <service name="com.sun.star.document.PDFFilter"/> </implementation> + <implementation name="com.sun.star.comp.PDF.PDFExportInteractionHandler"> + <service name="com.sun.star.filter.pdfexport.PDFExportInteractionHandler"/> + </implementation> </component> diff --git a/filter/source/pdf/pdffilter.cxx b/filter/source/pdf/pdffilter.cxx index 0c08be6d8a66..0abb2eb1d3da 100644 --- a/filter/source/pdf/pdffilter.cxx +++ b/filter/source/pdf/pdffilter.cxx @@ -60,6 +60,7 @@ sal_Bool PDFFilter::implExport( const Sequence< PropertyValue >& rDescriptor ) const PropertyValue* pValue = rDescriptor.getConstArray(); sal_Bool bRet = sal_False; Reference< task::XStatusIndicator > xStatusIndicator; + Reference< task::XInteractionHandler > xIH; for ( sal_Int32 i = 0 ; ( i < nLength ) && !xOStm.is(); ++i) { @@ -69,6 +70,8 @@ sal_Bool PDFFilter::implExport( const Sequence< PropertyValue >& rDescriptor ) pValue[ i ].Value >>= aFilterData; else if ( pValue[ i ].Name.equalsAscii( "StatusIndicator" ) ) pValue[ i ].Value >>= xStatusIndicator; + else if( pValue[i].Name.equalsAscii( "InteractionHandler" ) ) + pValue[i].Value >>= xIH; } /* we don't get FilterData if we are exporting directly @@ -117,7 +120,7 @@ sal_Bool PDFFilter::implExport( const Sequence< PropertyValue >& rDescriptor ) } if( mxSrcDoc.is() && xOStm.is() ) { - PDFExport aExport( mxSrcDoc, xStatusIndicator, mxMSF ); + PDFExport aExport( mxSrcDoc, xStatusIndicator, xIH, mxMSF ); ::utl::TempFile aTempFile; aTempFile.EnableKillingFile(); diff --git a/filter/source/pdf/pdffilter.hxx b/filter/source/pdf/pdffilter.hxx index b4720c1627c7..ea223496522e 100644 --- a/filter/source/pdf/pdffilter.hxx +++ b/filter/source/pdf/pdffilter.hxx @@ -42,6 +42,7 @@ #include <com/sun/star/beans/XPropertyAccess.hpp> #include <comphelper/property.hxx> #include <com/sun/star/task/XStatusIndicator.hpp> +#include <com/sun/star/task/XInteractionHandler.hpp> #include <osl/diagnose.h> #include <rtl/process.h> diff --git a/filter/source/pdf/pdfinteract.cxx b/filter/source/pdf/pdfinteract.cxx new file mode 100644 index 000000000000..23ea98d6bf51 --- /dev/null +++ b/filter/source/pdf/pdfinteract.cxx @@ -0,0 +1,137 @@ + /************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_filter.hxx" + +#include "pdfinteract.hxx" +#include "impdialog.hxx" + +#include "com/sun/star/task/XInteractionRequest.hpp" +#include "com/sun/star/task/PDFExportException.hpp" + +// ------------- +// - PDFInteractionHandler - +// ------------- + +PDFInteractionHandler::PDFInteractionHandler( const Reference< XMultiServiceFactory > &rxMSF ) : + mxMSF( rxMSF ) +{ +} + +// ----------------------------------------------------------------------------- + +PDFInteractionHandler::~PDFInteractionHandler() +{ +} + + +void SAL_CALL PDFInteractionHandler::handle( const Reference< task::XInteractionRequest >& i_xRequest ) + throw (RuntimeException) +{ + handleInteractionRequest( i_xRequest ); +} + +sal_Bool SAL_CALL PDFInteractionHandler::handleInteractionRequest( const Reference< task::XInteractionRequest >& i_xRequest ) + throw (RuntimeException) +{ + sal_Bool bHandled = sal_False; + + Any aRequest( i_xRequest->getRequest() ); + task::PDFExportException aExc; + if( aRequest >>= aExc ) + { + std::set< vcl::PDFWriter::ErrorCode > aCodes; + sal_Int32 nCodes = aExc.ErrorCodes.getLength(); + for( sal_Int32 i = 0; i < nCodes; i++ ) + aCodes.insert( (vcl::PDFWriter::ErrorCode)aExc.ErrorCodes.getConstArray()[i] ); + ImplErrorDialog aDlg( aCodes ); + aDlg.Execute(); + bHandled = sal_True; + } + return bHandled; +} + +// ----------------------------------------------------------------------------- + +OUString PDFInteractionHandler_getImplementationName () + throw (RuntimeException) +{ + return OUString ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.PDF.PDFExportInteractionHandler" ) ); +} + +// ----------------------------------------------------------------------------- + +#define SERVICE_NAME "com.sun.star.filter.pdfexport.PDFExportInteractionHandler" + +sal_Bool SAL_CALL PDFInteractionHandler_supportsService( const OUString& ServiceName ) + throw (RuntimeException) +{ + return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME ) ); +} + +// ----------------------------------------------------------------------------- + +Sequence< OUString > SAL_CALL PDFInteractionHandler_getSupportedServiceNames( ) throw (RuntimeException) +{ + Sequence < OUString > aRet(1); + OUString* pArray = aRet.getArray(); + pArray[0] = OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME ) ); + return aRet; +} + +#undef SERVICE_NAME + +// ----------------------------------------------------------------------------- + +Reference< XInterface > SAL_CALL PDFInteractionHandler_createInstance( const Reference< XMultiServiceFactory > & rSMgr) throw( Exception ) +{ + return (cppu::OWeakObject*) new PDFInteractionHandler( rSMgr ); +} + +// ----------------------------------------------------------------------------- + +OUString SAL_CALL PDFInteractionHandler::getImplementationName() + throw (RuntimeException) +{ + return PDFInteractionHandler_getImplementationName(); +} + +// ----------------------------------------------------------------------------- + +sal_Bool SAL_CALL PDFInteractionHandler::supportsService( const OUString& rServiceName ) + throw (RuntimeException) +{ + return PDFInteractionHandler_supportsService( rServiceName ); +} + +// ----------------------------------------------------------------------------- + +::com::sun::star::uno::Sequence< OUString > SAL_CALL PDFInteractionHandler::getSupportedServiceNames( ) throw (RuntimeException) +{ + return PDFInteractionHandler_getSupportedServiceNames(); +} diff --git a/filter/source/pdf/pdfinteract.hxx b/filter/source/pdf/pdfinteract.hxx new file mode 100644 index 000000000000..4cffc70c962a --- /dev/null +++ b/filter/source/pdf/pdfinteract.hxx @@ -0,0 +1,91 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef PDFINTERACT_HXX +#define PDFINTERACT_HXX + +#include "com/sun/star/lang/XServiceInfo.hpp" +#include "cppuhelper/implbase2.hxx" +#include "com/sun/star/lang/XMultiServiceFactory.hpp" +#include "com/sun/star/task/XInteractionHandler2.hpp" + +using namespace ::rtl; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; + +// ------------- +// - PDFFilter - +// ------------- + +class PDFInteractionHandler : public cppu::WeakImplHelper2 < task::XInteractionHandler2, + XServiceInfo > +{ +private: + + Reference< XMultiServiceFactory > mxMSF; + +protected: + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() throw(RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(RuntimeException); + + // XIniteractionHandler + virtual void SAL_CALL handle( const Reference< task::XInteractionRequest >& ) throw(RuntimeException); + + // XIniteractionHandler2 + virtual sal_Bool SAL_CALL handleInteractionRequest( const Reference< task::XInteractionRequest >& ) throw(RuntimeException); +public: + + PDFInteractionHandler( const Reference< XMultiServiceFactory >& rxMSF ); + virtual ~PDFInteractionHandler(); +}; + +// ----------------------------------------------------------------------------- + +OUString PDFInteractionHandler_getImplementationName () + throw ( RuntimeException ); + +// ----------------------------------------------------------------------------- + +sal_Bool SAL_CALL PDFInteractionHandler_supportsService( const OUString& ServiceName ) + throw ( RuntimeException ); + +// ----------------------------------------------------------------------------- + +Sequence< OUString > SAL_CALL PDFInteractionHandler_getSupportedServiceNames( ) + throw ( RuntimeException ); + +// ----------------------------------------------------------------------------- + +Reference< XInterface > +SAL_CALL PDFInteractionHandler_createInstance( const Reference< XMultiServiceFactory > & rSMgr) + throw ( Exception ); + +#endif // PDFINTERACT_HXX + diff --git a/filter/source/pdf/pdfuno.cxx b/filter/source/pdf/pdfuno.cxx index 78bfff4c89f7..69b3d7a1ebc2 100644 --- a/filter/source/pdf/pdfuno.cxx +++ b/filter/source/pdf/pdfuno.cxx @@ -36,6 +36,7 @@ #include <pdffilter.hxx> #include <pdfdialog.hxx> +#include <pdfinteract.hxx> using namespace ::rtl; using namespace ::cppu; @@ -76,6 +77,13 @@ extern "C" PDFDialog_createInstance, PDFDialog_getSupportedServiceNames() ); } + else if( aImplName.equals( PDFInteractionHandler_getImplementationName() ) ) + { + xFactory = createSingleFactory( reinterpret_cast< XMultiServiceFactory* >( pServiceManager ), + OUString::createFromAscii( pImplName ), + PDFInteractionHandler_createInstance, PDFInteractionHandler_getSupportedServiceNames() ); + + } if( xFactory.is() ) { diff --git a/filter/source/xsltdialog/xmlfiltersettingsdialog.cxx b/filter/source/xsltdialog/xmlfiltersettingsdialog.cxx index 46cab18f6c77..9334c892028e 100644 --- a/filter/source/xsltdialog/xmlfiltersettingsdialog.cxx +++ b/filter/source/xsltdialog/xmlfiltersettingsdialog.cxx @@ -1433,9 +1433,7 @@ XMLFilterListBox::XMLFilterListBox( SvxPathControl_Impl * pParent ) static long nTabs[] = {3, 0, nTabSize, 2*nTabSize }; Size aHeadSize( mpHeaderBar->GetSizePixel() ); - WinBits nBits = WB_SORT | WB_HSCROLL | WB_CLIPCHILDREN | WB_TABSTOP; pParent->SetFocusControl( this ); - SetWindowBits( nBits ); // SetDoubleClickHdl( aLink ); // SetSelectHdl( LINK( this, SvxPathTabPage, PathSelect_Impl ) ); SetSelectionMode( MULTIPLE_SELECTION ); diff --git a/hwpfilter/prj/build.lst b/hwpfilter/prj/build.lst index ae47fe725ccc..51240453413d 100644 --- a/hwpfilter/prj/build.lst +++ b/hwpfilter/prj/build.lst @@ -1,4 +1,4 @@ -hw hwpfilter : offuh cppuhelper ZLIB:zlib NULL +hw hwpfilter : offuh cppuhelper ZLIB:zlib LIBXSLT:libxslt NULL hw hwpfilter usr1 - all hw_mkout NULL hw hwpfilter\prj get - all hw_prj NULL hw hwpfilter\inc nmake - all hw_inc NULL diff --git a/oox/inc/oox/core/binarycodec.hxx b/oox/inc/oox/core/binarycodec.hxx index 1e9dba07c388..ced63250f3e1 100644 --- a/oox/inc/oox/core/binarycodec.hxx +++ b/oox/inc/oox/core/binarycodec.hxx @@ -28,6 +28,9 @@ #ifndef OOX_CORE_BINARYCODEC_HXX #define OOX_CORE_BINARYCODEC_HXX +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/beans/NamedValue.hpp> + #include <rtl/cipher.h> #include <rtl/digest.h> @@ -85,6 +88,22 @@ public: */ void initKey( const sal_uInt8 pnPassData[ 16 ] ); + /** Initializes the algorithm with the encryption data. + + @param aData + The sequence contains the necessary data to initialize + the codec. + */ + bool initCodec( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aData ); + + /** Retrieves the encryption data + + @return + The sequence contains the necessary data to initialize + the codec. + */ + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > getEncryptionData(); + /** Verifies the validity of the password using the passed key and hash. @precond @@ -150,16 +169,6 @@ public: */ bool skip( sal_Int32 nBytes ); - // static ----------------------------------------------------------------- - - /** Calculates the 16-bit hash value for the given password. - - The password data may be longer than 16 bytes. The array does not need - to be terminated with a null byte (but it can without invalidating the - result). - */ - static sal_uInt16 getHash( const sal_uInt8* pnPassData, sal_Int32 nSize ); - private: CodecType meCodecType; /// Codec type. sal_uInt8 mpnKey[ 16 ]; /// Encryption key. @@ -189,6 +198,22 @@ public: ~BinaryCodec_RCF(); + /** Initializes the algorithm with the encryption data. + + @param aData + The sequence contains the necessary data to initialize + the codec. + */ + bool initCodec( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aData ); + + /** Retrieves the encryption data + + @return + The sequence contains the necessary data to initialize + the codec. + */ + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > getEncryptionData(); + /** Initializes the algorithm with the specified password and document ID. @param pnPassData @@ -278,9 +303,14 @@ public: bool skip( sal_Int32 nBytes ); private: + void InitKeyImpl( + const sal_uInt8 pKeyData[64], + const sal_uInt8 pUnique[16] ); + rtlCipher mhCipher; rtlDigest mhDigest; sal_uInt8 mpnDigestValue[ RTL_DIGEST_LENGTH_MD5 ]; + sal_uInt8 mpnUnique[16]; }; // ============================================================================ diff --git a/oox/inc/oox/core/filterbase.hxx b/oox/inc/oox/core/filterbase.hxx index c3b82af62f5d..80dc233491d4 100644 --- a/oox/inc/oox/core/filterbase.hxx +++ b/oox/inc/oox/core/filterbase.hxx @@ -29,6 +29,7 @@ #define OOX_CORE_FILTERBASE_HXX #include <memory> +#include <com/sun/star/beans/NamedValue.hpp> #include <com/sun/star/document/XExporter.hpp> #include <com/sun/star/document/XFilter.hpp> #include <com/sun/star/document/XImporter.hpp> @@ -209,9 +210,10 @@ public: /** Returns the VBA project manager. */ ::oox::ole::VbaProject& getVbaProject() const; - /** Requests a password from the media descriptor or from the user. On - success, the password will be inserted into the media descriptor. */ - ::rtl::OUString requestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ) const; + /** Requests the encryption data from the media descriptor or from the user. On + success, the encryption data will be inserted into the media descriptor. */ + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > + requestEncryptionData( ::comphelper::IDocPasswordVerifier& rVerifier ) const; /** Imports the raw binary data from the specified stream. @return True, if the data could be imported from the stream. */ diff --git a/oox/inc/oox/dump/dumperbase.hxx b/oox/inc/oox/dump/dumperbase.hxx index ed1a3e1fc938..d9acaa1f1011 100644 --- a/oox/inc/oox/dump/dumperbase.hxx +++ b/oox/inc/oox/dump/dumperbase.hxx @@ -910,7 +910,7 @@ public: void eraseNameList( const ::rtl::OUString& rListName ); NameListRef getNameList( const ::rtl::OUString& rListName ) const; - ::rtl::OUString requestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ); + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > requestEncryptionData( ::comphelper::IDocPasswordVerifier& rVerifier ); inline bool isPasswordCancelled() const { return mbPwCancelled; } protected: @@ -1011,7 +1011,7 @@ public: template< typename Type > bool hasName( const NameListWrapper& rListWrp, Type nKey ) const; - ::rtl::OUString requestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ); + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > requestEncryptionData( ::comphelper::IDocPasswordVerifier& rVerifier ); bool isPasswordCancelled() const; protected: diff --git a/oox/inc/oox/xls/biffcodec.hxx b/oox/inc/oox/xls/biffcodec.hxx index 438eb7e359be..9b9157c7e494 100644 --- a/oox/inc/oox/xls/biffcodec.hxx +++ b/oox/inc/oox/xls/biffcodec.hxx @@ -52,10 +52,9 @@ public: /** Derived classes return a clone of the decoder for usage in new streams. */ inline BiffDecoderBase* clone() { return implClone(); } - /** Implementation of the ::comphelper::IDocPasswordVerifier interface, - calls the new virtual function implVerify(). */ - virtual ::comphelper::DocPasswordVerifierResult - verifyPassword( const ::rtl::OUString& rPassword ); + /** Implementation of the ::comphelper::IDocPasswordVerifier interface. */ + virtual ::comphelper::DocPasswordVerifierResult verifyPassword( const ::rtl::OUString& rPassword, ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& o_rEncryptionData ); + virtual ::comphelper::DocPasswordVerifierResult verifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& o_rEncryptionData ); /** Returns true, if the decoder has been initialized correctly. */ inline bool isValid() const { return mbValid; } @@ -73,7 +72,8 @@ private: /** Derived classes implement password verification and initialization of the decoder. */ - virtual bool implVerify( const ::rtl::OUString& rPassword ) = 0; + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > implVerifyPassword( const ::rtl::OUString& rPassword ) = 0; + virtual bool implVerifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rEncryptionData ) = 0; /** Implementation of decryption of a memory block. */ virtual void implDecode( @@ -104,7 +104,9 @@ private: virtual BiffDecoder_XOR* implClone(); /** Implements password verification and initialization of the decoder. */ - virtual bool implVerify( const ::rtl::OUString& rPassword ); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > implVerifyPassword( const ::rtl::OUString& rPassword ); + virtual bool implVerifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rEncryptionData ); + /** Implementation of decryption of a memory block. */ virtual void implDecode( @@ -115,7 +117,7 @@ private: private: ::oox::core::BinaryCodec_XOR maCodec; /// Cipher algorithm implementation. - ::std::vector< sal_uInt8 > maPassword; + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > maEncryptionData; sal_uInt16 mnKey; sal_uInt16 mnHash; }; @@ -139,7 +141,8 @@ private: virtual BiffDecoder_RCF* implClone(); /** Implements password verification and initialization of the decoder. */ - virtual bool implVerify( const ::rtl::OUString& rPassword ); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > implVerifyPassword( const ::rtl::OUString& rPassword ); + virtual bool implVerifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rEncryptionData ); /** Implementation of decryption of a memory block. */ virtual void implDecode( @@ -150,7 +153,7 @@ private: private: ::oox::core::BinaryCodec_RCF maCodec; /// Cipher algorithm implementation. - ::std::vector< sal_uInt16 > maPassword; + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > maEncryptionData; ::std::vector< sal_uInt8 > maSalt; ::std::vector< sal_uInt8 > maVerifier; ::std::vector< sal_uInt8 > maVerifierHash; diff --git a/oox/prj/build.lst b/oox/prj/build.lst index 345c72e00558..03735c73dd11 100644 --- a/oox/prj/build.lst +++ b/oox/prj/build.lst @@ -1,4 +1,4 @@ -oox oox : vos cppu cppuhelper comphelper sal offapi sax basegfx xmlscript tools vcl BOOST:boost OPENSSL:openssl NULL +oox oox : vos cppu cppuhelper comphelper sal offapi sax basegfx xmlscript tools vcl BOOST:boost OPENSSL:openssl LIBXSLT:libxslt NULL oox oox usr1 - all oox_mkout NULL oox oox\prj get - all oox_prj NULL oox oox\source\token nmake - all oox_token NULL diff --git a/oox/source/core/binarycodec.cxx b/oox/source/core/binarycodec.cxx index b2c117a12d90..3f406ba1af08 100644 --- a/oox/source/core/binarycodec.cxx +++ b/oox/source/core/binarycodec.cxx @@ -31,6 +31,11 @@ #include <string.h> #include "oox/helper/attributelist.hxx" +#include <comphelper/sequenceashashmap.hxx> +#include <comphelper/docpasswordhelper.hxx> + +using namespace ::com::sun::star; + namespace oox { namespace core { @@ -177,6 +182,37 @@ void BinaryCodec_XOR::initKey( const sal_uInt8 pnPassData[ 16 ] ) } } +bool BinaryCodec_XOR::initCodec( const uno::Sequence< beans::NamedValue >& aData ) +{ + bool bResult = sal_False; + + ::comphelper::SequenceAsHashMap aHashData( aData ); + uno::Sequence< sal_Int8 > aKey = aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95EncryptionKey" ) ), uno::Sequence< sal_Int8 >() ); + + if ( aKey.getLength() == 16 ) + { + (void)memcpy( mpnKey, aKey.getConstArray(), 16 ); + bResult = sal_True; + + mnBaseKey = (sal_uInt16)aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95BaseKey" ) ), (sal_Int16)0 ); + mnHash = (sal_uInt16)aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95PasswordHash" ) ), (sal_Int16)0 ); + } + else + OSL_ENSURE( sal_False, "Unexpected key size!\n" ); + + return bResult; +} + +uno::Sequence< beans::NamedValue > BinaryCodec_XOR::getEncryptionData() +{ + ::comphelper::SequenceAsHashMap aHashData; + aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95EncryptionKey" ) ) ] <<= uno::Sequence<sal_Int8>( (sal_Int8*)mpnKey, 16 ); + aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95BaseKey" ) ) ] <<= (sal_Int16)mnBaseKey; + aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95PasswordHash" ) ) ] <<= (sal_Int16)mnHash; + + return aHashData.getAsConstNamedValueList(); +} + bool BinaryCodec_XOR::verifyKey( sal_uInt16 nKey, sal_uInt16 nHash ) const { return (nKey == mnBaseKey) && (nHash == mnHash); @@ -231,11 +267,6 @@ bool BinaryCodec_XOR::skip( sal_Int32 nBytes ) return true; } -sal_uInt16 BinaryCodec_XOR::getHash( const sal_uInt8* pnPassData, sal_Int32 nSize ) -{ - return lclGetHash( pnPassData, nSize ); -} - // ============================================================================ BinaryCodec_RCF::BinaryCodec_RCF() @@ -247,56 +278,62 @@ BinaryCodec_RCF::BinaryCodec_RCF() OSL_ENSURE( mhDigest != 0, "BinaryCodec_RCF::BinaryCodec_RCF - cannot create digest" ); (void)memset( mpnDigestValue, 0, sizeof( mpnDigestValue ) ); + (void)memset (mpnUnique, 0, sizeof(mpnUnique)); } BinaryCodec_RCF::~BinaryCodec_RCF() { (void)memset( mpnDigestValue, 0, sizeof( mpnDigestValue ) ); + (void)memset (mpnUnique, 0, sizeof(mpnUnique)); rtl_digest_destroy( mhDigest ); rtl_cipher_destroy( mhCipher ); } -void BinaryCodec_RCF::initKey( const sal_uInt16 pnPassData[ 16 ], const sal_uInt8 pnSalt[ 16 ] ) +bool BinaryCodec_RCF::initCodec( const uno::Sequence< beans::NamedValue >& aData ) { - // create little-endian key data array from password data - sal_uInt8 pnKeyData[ 64 ]; - (void)memset( pnKeyData, 0, sizeof( pnKeyData ) ); + bool bResult = sal_False; - const sal_uInt16* pnCurrPass = pnPassData; - const sal_uInt16* pnPassEnd = pnPassData + 16; - sal_uInt8* pnCurrKey = pnKeyData; - size_t nPassSize = 0; - for( ; (pnCurrPass < pnPassEnd) && (*pnCurrPass != 0); ++pnCurrPass, ++nPassSize ) + ::comphelper::SequenceAsHashMap aHashData( aData ); + uno::Sequence< sal_Int8 > aKey = aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97EncryptionKey" ) ), uno::Sequence< sal_Int8 >() ); + + if ( aKey.getLength() == RTL_DIGEST_LENGTH_MD5 ) { - *pnCurrKey++ = static_cast< sal_uInt8 >( *pnCurrPass ); - *pnCurrKey++ = static_cast< sal_uInt8 >( *pnCurrPass >> 8 ); + (void)memcpy( mpnDigestValue, aKey.getConstArray(), RTL_DIGEST_LENGTH_MD5 ); + uno::Sequence< sal_Int8 > aUniqueID = aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97UniqueID" ) ), uno::Sequence< sal_Int8 >() ); + if ( aUniqueID.getLength() == 16 ) + { + (void)memcpy( mpnUnique, aUniqueID.getConstArray(), 16 ); + bResult = sal_False; + } + else + OSL_ENSURE( sal_False, "Unexpected document ID!\n" ); } - pnKeyData[ 2 * nPassSize ] = 0x80; - pnKeyData[ 56 ] = static_cast< sal_uInt8 >( nPassSize << 4 ); + else + OSL_ENSURE( sal_False, "Unexpected key size!\n" ); - // fill raw digest of key data into key data - (void)rtl_digest_updateMD5( mhDigest, pnKeyData, sizeof( pnKeyData ) ); - (void)rtl_digest_rawMD5( mhDigest, pnKeyData, RTL_DIGEST_LENGTH_MD5 ); + return bResult; +} - // update digest with key data and passed salt data - for( size_t nIndex = 0; nIndex < 16; ++nIndex ) - { - rtl_digest_updateMD5( mhDigest, pnKeyData, 5 ); - rtl_digest_updateMD5( mhDigest, pnSalt, 16 ); - } +uno::Sequence< beans::NamedValue > BinaryCodec_RCF::getEncryptionData() +{ + ::comphelper::SequenceAsHashMap aHashData; + aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97EncryptionKey" ) ) ] <<= uno::Sequence< sal_Int8 >( (sal_Int8*)mpnDigestValue, RTL_DIGEST_LENGTH_MD5 ); + aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97UniqueID" ) ) ] <<= uno::Sequence< sal_Int8 >( (sal_Int8*)mpnUnique, 16 ); - // update digest with padding - pnKeyData[ 16 ] = 0x80; - (void)memset( pnKeyData + 17, 0, sizeof( pnKeyData ) - 17 ); - pnKeyData[ 56 ] = 0x80; - pnKeyData[ 57 ] = 0x0A; - rtl_digest_updateMD5( mhDigest, pnKeyData + 16, sizeof( pnKeyData ) - 16 ); + return aHashData.getAsConstNamedValueList(); +} - // fill raw digest of above updates into digest value - rtl_digest_rawMD5( mhDigest, mpnDigestValue, sizeof( mpnDigestValue ) ); +void BinaryCodec_RCF::initKey( const sal_uInt16 pnPassData[ 16 ], const sal_uInt8 pnSalt[ 16 ] ) +{ + uno::Sequence< sal_Int8 > aKey = ::comphelper::DocPasswordHelper::GenerateStd97Key( pnPassData, uno::Sequence< sal_Int8 >( (sal_Int8*)pnSalt, 16 ) ); + // Fill raw digest of above updates into DigestValue. - // erase key data array and leave - (void)memset( pnKeyData, 0, sizeof( pnKeyData ) ); + if ( aKey.getLength() == sizeof(mpnDigestValue) ) + (void)memcpy ( mpnDigestValue, (const sal_uInt8*)aKey.getConstArray(), sizeof(mpnDigestValue) ); + else + memset( mpnDigestValue, 0, sizeof(mpnDigestValue) ); + + (void)memcpy( mpnUnique, pnSalt, 16 ); } bool BinaryCodec_RCF::verifyKey( const sal_uInt8 pnVerifier[ 16 ], const sal_uInt8 pnVerifierHash[ 16 ] ) diff --git a/oox/source/core/filterbase.cxx b/oox/source/core/filterbase.cxx index 9eaf5fb29a14..b215150acb88 100644 --- a/oox/source/core/filterbase.cxx +++ b/oox/source/core/filterbase.cxx @@ -414,7 +414,7 @@ VbaProject& FilterBase::getVbaProject() const return *mxImpl->mxVbaProject; } -OUString FilterBase::requestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ) const +Sequence< NamedValue > FilterBase::requestEncryptionData( ::comphelper::IDocPasswordVerifier& rVerifier ) const { ::std::vector< OUString > aDefaultPasswords; aDefaultPasswords.push_back( CREATE_OUSTRING( "VelvetSweatshop" ) ); diff --git a/oox/source/core/filterdetect.cxx b/oox/source/core/filterdetect.cxx index 4f8bd8ef2463..cdab111e9898 100644 --- a/oox/source/core/filterdetect.cxx +++ b/oox/source/core/filterdetect.cxx @@ -351,7 +351,49 @@ void lclDeriveKey( const sal_uInt8* pnHash, sal_uInt32 nHashLen, sal_uInt8* pnKe // ---------------------------------------------------------------------------- -bool lclGenerateEncryptionKey( const PackageEncryptionInfo& rEncrInfo, const OUString& rPassword, sal_uInt8* pnKey, sal_uInt32 nRequiredKeyLen ) +bool lclCheckEncryptionData( const sal_uInt8* pnKey, sal_uInt32 nKeySize, const sal_uInt8* pnVerifier, sal_uInt32 nVerifierSize, const sal_uInt8* pnVerifierHash, sal_uInt32 nVerifierHashSize ) +{ + bool bResult = false; + + // the only currently supported algorithm needs key size 128 + if ( nKeySize == 16 && nVerifierSize == 16 && nVerifierHashSize == 32 ) + { + // check password + EVP_CIPHER_CTX aes_ctx; + EVP_CIPHER_CTX_init( &aes_ctx ); + EVP_DecryptInit_ex( &aes_ctx, EVP_aes_128_ecb(), 0, pnKey, 0 ); + EVP_CIPHER_CTX_set_padding( &aes_ctx, 0 ); + int nOutLen = 0; + sal_uInt8 pnTmpVerifier[ 16 ]; + (void) memset( pnTmpVerifier, 0, sizeof(pnTmpVerifier) ); + + /*int*/ EVP_DecryptUpdate( &aes_ctx, pnTmpVerifier, &nOutLen, pnVerifier, nVerifierSize ); + EVP_CIPHER_CTX_cleanup( &aes_ctx ); + + EVP_CIPHER_CTX_init( &aes_ctx ); + EVP_DecryptInit_ex( &aes_ctx, EVP_aes_128_ecb(), 0, pnKey, 0 ); + EVP_CIPHER_CTX_set_padding( &aes_ctx, 0 ); + sal_uInt8 pnTmpVerifierHash[ 32 ]; + (void) memset( pnTmpVerifierHash, 0, sizeof(pnTmpVerifierHash) ); + + /*int*/ EVP_DecryptUpdate( &aes_ctx, pnTmpVerifierHash, &nOutLen, pnVerifierHash, nVerifierHashSize ); + EVP_CIPHER_CTX_cleanup( &aes_ctx ); + + rtlDigest aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 ); + rtlDigestError aError = rtl_digest_update( aDigest, pnTmpVerifier, sizeof( pnTmpVerifier ) ); + sal_uInt8 pnSha1Hash[ RTL_DIGEST_LENGTH_SHA1 ]; + aError = rtl_digest_get( aDigest, pnSha1Hash, RTL_DIGEST_LENGTH_SHA1 ); + rtl_digest_destroy( aDigest ); + + bResult = ( memcmp( pnSha1Hash, pnTmpVerifierHash, RTL_DIGEST_LENGTH_SHA1 ) == 0 ); + } + + return bResult; +} + +// ---------------------------------------------------------------------------- + +Sequence< NamedValue > lclGenerateEncryptionKey( const PackageEncryptionInfo& rEncrInfo, const OUString& rPassword, sal_uInt8* pnKey, sal_uInt32 nRequiredKeyLen ) { size_t nBufferSize = rEncrInfo.mnSaltSize + 2 * rPassword.getLength(); sal_uInt8* pnBuffer = new sal_uInt8[ nBufferSize ]; @@ -390,30 +432,18 @@ bool lclGenerateEncryptionKey( const PackageEncryptionInfo& rEncrInfo, const OUS lclDeriveKey( pnHash, RTL_DIGEST_LENGTH_SHA1, pnKey, nRequiredKeyLen ); delete[] pnHash; - // check password - EVP_CIPHER_CTX aes_ctx; - EVP_CIPHER_CTX_init( &aes_ctx ); - EVP_DecryptInit_ex( &aes_ctx, EVP_aes_128_ecb(), 0, pnKey, 0 ); - EVP_CIPHER_CTX_set_padding( &aes_ctx, 0 ); - int nOutLen = 0; - sal_uInt8 pnVerifier[ 16 ] = { 0 }; - /*int*/ EVP_DecryptUpdate( &aes_ctx, pnVerifier, &nOutLen, rEncrInfo.mpnEncrVerifier, sizeof( rEncrInfo.mpnEncrVerifier ) ); - EVP_CIPHER_CTX_cleanup( &aes_ctx ); - - EVP_CIPHER_CTX_init( &aes_ctx ); - EVP_DecryptInit_ex( &aes_ctx, EVP_aes_128_ecb(), 0, pnKey, 0 ); - EVP_CIPHER_CTX_set_padding( &aes_ctx, 0 ); - sal_uInt8 pnVerifierHash[ 32 ] = { 0 }; - /*int*/ EVP_DecryptUpdate( &aes_ctx, pnVerifierHash, &nOutLen, rEncrInfo.mpnEncrVerifierHash, sizeof( rEncrInfo.mpnEncrVerifierHash ) ); - EVP_CIPHER_CTX_cleanup( &aes_ctx ); - - aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 ); - aError = rtl_digest_update( aDigest, pnVerifier, sizeof( pnVerifier ) ); - sal_uInt8 pnSha1Hash[ RTL_DIGEST_LENGTH_SHA1 ]; - aError = rtl_digest_get( aDigest, pnSha1Hash, RTL_DIGEST_LENGTH_SHA1 ); - rtl_digest_destroy( aDigest ); + Sequence< NamedValue > aResult; + if( lclCheckEncryptionData( pnKey, nRequiredKeyLen, rEncrInfo.mpnEncrVerifier, sizeof( rEncrInfo.mpnEncrVerifier ), rEncrInfo.mpnEncrVerifierHash, sizeof( rEncrInfo.mpnEncrVerifierHash ) ) ) + { + SequenceAsHashMap aEncryptionData; + aEncryptionData[ CREATE_OUSTRING( "AES128EncryptionKey" ) ] <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( pnKey ), nRequiredKeyLen ); + aEncryptionData[ CREATE_OUSTRING( "AES128EncryptionSalt" ) ] <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( rEncrInfo.mpnSalt ), rEncrInfo.mnSaltSize ); + aEncryptionData[ CREATE_OUSTRING( "AES128EncryptionVerifier" ) ] <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( rEncrInfo.mpnEncrVerifier ), sizeof( rEncrInfo.mpnEncrVerifier ) ); + aEncryptionData[ CREATE_OUSTRING( "AES128EncryptionVerifierHash" ) ] <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( rEncrInfo.mpnEncrVerifierHash ), sizeof( rEncrInfo.mpnEncrVerifierHash ) ); + aResult = aEncryptionData.getAsConstNamedValueList(); + } - return memcmp( pnSha1Hash, pnVerifierHash, RTL_DIGEST_LENGTH_SHA1 ) == 0; + return aResult; } // the password verifier ------------------------------------------------------ @@ -424,7 +454,9 @@ public: explicit PasswordVerifier( const PackageEncryptionInfo& rEncryptInfo ); virtual ::comphelper::DocPasswordVerifierResult - verifyPassword( const OUString& rPassword ); + verifyPassword( const OUString& rPassword, Sequence< NamedValue >& o_rEncryptionData ); + virtual ::comphelper::DocPasswordVerifierResult + verifyEncryptionData( const Sequence< NamedValue >& rEncryptionData ); inline const sal_uInt8* getKey() const { return &maKey.front(); } @@ -439,11 +471,26 @@ PasswordVerifier::PasswordVerifier( const PackageEncryptionInfo& rEncryptInfo ) { } -::comphelper::DocPasswordVerifierResult PasswordVerifier::verifyPassword( const OUString& rPassword ) +::comphelper::DocPasswordVerifierResult PasswordVerifier::verifyPassword( const OUString& rPassword, Sequence< NamedValue >& o_rEncryptionData ) { // verifies the password and writes the related decryption key into maKey - return lclGenerateEncryptionKey( mrEncryptInfo, rPassword, &maKey.front(), maKey.size() ) ? - ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD; + o_rEncryptionData = lclGenerateEncryptionKey( mrEncryptInfo, rPassword, &maKey.front(), maKey.size() ); + return o_rEncryptionData.hasElements() ? ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD; +} + +::comphelper::DocPasswordVerifierResult PasswordVerifier::verifyEncryptionData( const Sequence< NamedValue >& rEncryptionData ) +{ + SequenceAsHashMap aHashData( rEncryptionData ); + Sequence< sal_Int8 > aKey = aHashData.getUnpackedValueOrDefault( CREATE_OUSTRING( "AES128EncryptionKey" ), Sequence< sal_Int8 >() ); + Sequence< sal_Int8 > aVerifier = aHashData.getUnpackedValueOrDefault( CREATE_OUSTRING( "AES128EncryptionVerifier" ), Sequence< sal_Int8 >() ); + Sequence< sal_Int8 > aVerifierHash = aHashData.getUnpackedValueOrDefault( CREATE_OUSTRING( "AES128EncryptionVerifierHash" ), Sequence< sal_Int8 >() ); + + bool bResult = lclCheckEncryptionData( + reinterpret_cast< const sal_uInt8* >( aKey.getConstArray() ), aKey.getLength(), + reinterpret_cast< const sal_uInt8* >( aVerifier.getConstArray() ), aVerifier.getLength(), + reinterpret_cast< const sal_uInt8* >( aVerifierHash.getConstArray() ), aVerifierHash.getLength() ); + + return bResult ? ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD; } } // namespace @@ -506,10 +553,10 @@ Reference< XInputStream > FilterDetect::extractUnencryptedPackage( MediaDescript (according to the verifier), or with an empty string if user has cancelled the password input dialog. */ PasswordVerifier aVerifier( aEncryptInfo ); - OUString aPassword = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword( + Sequence< NamedValue > aEncryptionData = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword( aVerifier, rMediaDesc, ::comphelper::DocPasswordRequestType_MS, &aDefaultPasswords ); - if( aPassword.getLength() == 0 ) + if( aEncryptionData.getLength() == 0 ) { rMediaDesc[ MediaDescriptor::PROP_ABORTED() ] <<= true; } diff --git a/oox/source/drawingml/textcharacterproperties.cxx b/oox/source/drawingml/textcharacterproperties.cxx index c55751ba25f6..61333535c38f 100644 --- a/oox/source/drawingml/textcharacterproperties.cxx +++ b/oox/source/drawingml/textcharacterproperties.cxx @@ -95,7 +95,7 @@ void TextCharacterProperties::pushToPropMap( PropertyMap& rPropMap, const XmlFil rPropMap[ PROP_CharFontFamilyComplex ] <<= nFontFamily; } - // symbol font not supported + // symbolfont, will now be ... textrun.cxx ... ausgewertet !!!i#113673 if( maCharColor.isUsed() ) rPropMap[ PROP_CharColor ] <<= maCharColor.getColor( rFilter.getGraphicHelper() ); diff --git a/oox/source/drawingml/textrun.cxx b/oox/source/drawingml/textrun.cxx index 944e17691c56..1e435defaa2d 100644 --- a/oox/source/drawingml/textrun.cxx +++ b/oox/source/drawingml/textrun.cxx @@ -77,7 +77,55 @@ void TextRun::insertAt( } else { - xText->insertString( xStart, getText(), sal_False ); + OUString aLatinFontName, aSymbolFontName; + sal_Int16 nLatinFontPitch = 0, nSymbolFontPitch = 0; + sal_Int16 nLatinFontFamily = 0, nSymbolFontFamily = 0; + + if ( !aTextCharacterProps.maSymbolFont.getFontData( aSymbolFontName, nSymbolFontPitch, nSymbolFontFamily, rFilterBase ) ) + xText->insertString( xStart, getText(), sal_False ); + else if ( getText().getLength() ) + { // !!#i113673<<< + aTextCharacterProps.maLatinFont.getFontData( aLatinFontName, nLatinFontPitch, nLatinFontFamily, rFilterBase ); + + sal_Int32 nIndex = 0; + while ( sal_True ) + { + sal_Int32 nCount = 0; + sal_Bool bSymbol = ( getText()[ nIndex ] & 0xff00 ) == 0xf000; + if ( bSymbol ) + { + do + { + nCount++; + } + while( ( ( nCount + nIndex ) < getText().getLength() ) && ( ( getText()[ nCount + nIndex ] & 0xff00 ) == 0xf000 ) ); + aPropSet.setAnyProperty( PROP_CharFontName, Any( aSymbolFontName ) ); + aPropSet.setAnyProperty( PROP_CharFontPitch, Any( nSymbolFontPitch ) ); + aPropSet.setAnyProperty( PROP_CharFontFamily, Any( nSymbolFontFamily ) ); + } + else + { + do + { + nCount++; + } + while( ( ( nCount + nIndex ) < getText().getLength() ) && ( ( getText()[ nCount + nIndex ] & 0xff00 ) != 0xf000 ) ); + aPropSet.setAnyProperty( PROP_CharFontName, Any( aLatinFontName ) ); + aPropSet.setAnyProperty( PROP_CharFontPitch, Any( nLatinFontPitch ) ); + aPropSet.setAnyProperty( PROP_CharFontFamily, Any( nLatinFontFamily ) ); + } + rtl::OUString aSubString( getText().copy( nIndex, nCount ) ); + xText->insertString( xStart, aSubString, sal_False ); + nIndex += nCount; + + if ( nIndex >= getText().getLength() ) + break; + + xStart = Reference< XTextRange >( xAt, UNO_QUERY ); + aPropSet = PropertySet( xStart ); + aTextCharacterProps.pushToPropSet( aPropSet, rFilterBase ); + } + } } } else diff --git a/oox/source/dump/biffdumper.cxx b/oox/source/dump/biffdumper.cxx index 2f362af6ad2d..4e9156b5cc03 100644 --- a/oox/source/dump/biffdumper.cxx +++ b/oox/source/dump/biffdumper.cxx @@ -2422,7 +2422,7 @@ void WorkbookStreamObject::implDumpRecordBody() rStrm.seekToStart(); BiffDecoderRef xDecoder = BiffCodecHelper::implReadFilePass( rStrm, eBiff ); if( xDecoder.get() ) - cfg().requestPassword( *xDecoder ); + cfg().requestEncryptionData( *xDecoder ); setBinaryOnlyMode( !xDecoder || !xDecoder->isValid() ); } break; diff --git a/oox/source/dump/dumperbase.cxx b/oox/source/dump/dumperbase.cxx index 5c1cf3398fc9..32278e425664 100644 --- a/oox/source/dump/dumperbase.cxx +++ b/oox/source/dump/dumperbase.cxx @@ -1583,18 +1583,18 @@ NameListRef SharedConfigData::getNameList( const OUString& rListName ) const return xList; } -OUString SharedConfigData::requestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ) +Sequence< NamedValue > SharedConfigData::requestEncryptionData( ::comphelper::IDocPasswordVerifier& rVerifier ) { - OUString aPassword; + Sequence< NamedValue > aEncryptionData; if( !mbPwCancelled ) { ::std::vector< OUString > aDefaultPasswords; aDefaultPasswords.push_back( CREATE_OUSTRING( "VelvetSweatshop" ) ); - aPassword = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword( + aEncryptionData = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword( rVerifier, mrMediaDesc, ::comphelper::DocPasswordRequestType_MS, &aDefaultPasswords ); - mbPwCancelled = aPassword.getLength() == 0; + mbPwCancelled = !aEncryptionData.hasElements(); } - return aPassword; + return aEncryptionData; } bool SharedConfigData::implIsValid() const @@ -1766,9 +1766,9 @@ NameListRef Config::getNameList( const String& rListName ) const return implGetNameList( rListName ); } -OUString Config::requestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ) +Sequence< NamedValue > Config::requestEncryptionData( ::comphelper::IDocPasswordVerifier& rVerifier ) { - return mxCfgData->requestPassword( rVerifier ); + return mxCfgData->requestEncryptionData( rVerifier ); } bool Config::isPasswordCancelled() const diff --git a/oox/source/ole/vbaproject.cxx b/oox/source/ole/vbaproject.cxx index f51193fe30ba..35e6b7911012 100644 --- a/oox/source/ole/vbaproject.cxx +++ b/oox/source/ole/vbaproject.cxx @@ -427,7 +427,9 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap Reference< XMultiServiceFactory > xModelFactory( mxDocModel, UNO_QUERY_THROW ); Reference< XNameContainer > xBasicLib( createBasicLibrary(), UNO_SET_THROW ); - // set library container to VBA compatibility mode + /* Set library container to VBA compatibility mode. This will create + the VBA Globals object and store it in the Basic manager of the + document. */ try { Reference< XVBACompatibility >( getLibraryContainer( PROP_BasicLibraries ), UNO_QUERY_THROW )->setVBACompatibilityMode( sal_True ); @@ -436,15 +438,6 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap { } - // create the VBAGlobals object, the model will store it in the Basic manager - try - { - xModelFactory->createInstance( CREATE_OUSTRING( "ooo.vba.VBAGlobals" ) ); - } - catch( Exception& ) - { - } - // try to get access to document objects related to code modules Reference< XNameAccess > xDocObjectNA; try @@ -481,7 +474,7 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap for( ::std::vector< OUString >::iterator aIt = aElements.begin(), aEnd = aElements.end(); aIt != aEnd; ++aIt ) { // try to open the element as storage - if( !aIt->equals( CREATE_OUSTRING( "VBA" ) ) ) + if( !aIt->equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "VBA" ) ) ) { StorageRef xSubStrg = rVbaPrjStrg.openSubStorage( *aIt, false ); if( xSubStrg.get() ) try diff --git a/oox/source/xls/biffcodec.cxx b/oox/source/xls/biffcodec.cxx index 774760b7a9c5..89b39ef4fc94 100644 --- a/oox/source/xls/biffcodec.cxx +++ b/oox/source/xls/biffcodec.cxx @@ -53,9 +53,16 @@ BiffDecoderBase::~BiffDecoderBase() { } -::comphelper::DocPasswordVerifierResult BiffDecoderBase::verifyPassword( const OUString& rPassword ) +::comphelper::DocPasswordVerifierResult BiffDecoderBase::verifyPassword( const OUString& rPassword, Sequence< NamedValue >& o_rEncryptionData ) { - mbValid = implVerify( rPassword ); + o_rEncryptionData = implVerifyPassword( rPassword ); + mbValid = o_rEncryptionData.hasElements(); + return mbValid ? ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD; +} + +::comphelper::DocPasswordVerifierResult BiffDecoderBase::verifyEncryptionData( const Sequence< NamedValue >& rEncryptionData ) +{ + mbValid = implVerifyEncryptionData( rEncryptionData ); return mbValid ? ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD; } @@ -74,7 +81,6 @@ void BiffDecoderBase::decode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcData, BiffDecoder_XOR::BiffDecoder_XOR( sal_uInt16 nKey, sal_uInt16 nHash ) : maCodec( ::oox::core::BinaryCodec_XOR::CODEC_EXCEL ), - maPassword( 16 ), mnKey( nKey ), mnHash( nHash ) { @@ -83,12 +89,12 @@ BiffDecoder_XOR::BiffDecoder_XOR( sal_uInt16 nKey, sal_uInt16 nHash ) : BiffDecoder_XOR::BiffDecoder_XOR( const BiffDecoder_XOR& rDecoder ) : BiffDecoderBase(), // must be called to prevent compiler warning maCodec( ::oox::core::BinaryCodec_XOR::CODEC_EXCEL ), - maPassword( rDecoder.maPassword ), + maEncryptionData( rDecoder.maEncryptionData ), mnKey( rDecoder.mnKey ), mnHash( rDecoder.mnHash ) { if( isValid() ) - maCodec.initKey( &maPassword.front() ); + maCodec.initCodec( maEncryptionData ); } BiffDecoder_XOR* BiffDecoder_XOR::implClone() @@ -96,24 +102,40 @@ BiffDecoder_XOR* BiffDecoder_XOR::implClone() return new BiffDecoder_XOR( *this ); } -bool BiffDecoder_XOR::implVerify( const OUString& rPassword ) +Sequence< NamedValue > BiffDecoder_XOR::implVerifyPassword( const OUString& rPassword ) { + maEncryptionData.realloc( 0 ); + /* Convert password to a byte string. TODO: this needs some finetuning according to the spec... */ OString aBytePassword = OUStringToOString( rPassword, osl_getThreadTextEncoding() ); sal_Int32 nLen = aBytePassword.getLength(); if( (0 < nLen) && (nLen < 16) ) { - // copy byte string to sal_uInt8 array - maPassword.clear(); - maPassword.resize( 16, 0 ); - memcpy( &maPassword.front(), aBytePassword.getStr(), static_cast< size_t >( nLen ) ); + // init codec + maCodec.initKey( reinterpret_cast< const sal_uInt8* >( aBytePassword.getStr() ) ); + if( maCodec.verifyKey( mnKey, mnHash ) ) + maEncryptionData = maCodec.getEncryptionData(); + } + + return maEncryptionData; +} + +bool BiffDecoder_XOR::implVerifyEncryptionData( const Sequence< NamedValue >& rEncryptionData ) +{ + maEncryptionData.realloc( 0 ); + + if( rEncryptionData.hasElements() ) + { // init codec - maCodec.initKey( &maPassword.front() ); - return maCodec.verifyKey( mnKey, mnHash ); + maCodec.initCodec( rEncryptionData ); + + if( maCodec.verifyKey( mnKey, mnHash ) ) + maEncryptionData = rEncryptionData; } - return false; + + return maEncryptionData.hasElements(); } void BiffDecoder_XOR::implDecode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcData, sal_Int64 nStreamPos, sal_uInt16 nBytes ) @@ -144,7 +166,6 @@ sal_Int32 lclGetRcfOffset( sal_Int64 nStreamPos ) // ---------------------------------------------------------------------------- BiffDecoder_RCF::BiffDecoder_RCF( sal_uInt8 pnSalt[ 16 ], sal_uInt8 pnVerifier[ 16 ], sal_uInt8 pnVerifierHash[ 16 ] ) : - maPassword( 16, 0 ), maSalt( pnSalt, pnSalt + 16 ), maVerifier( pnVerifier, pnVerifier + 16 ), maVerifierHash( pnVerifierHash, pnVerifierHash + 16 ) @@ -153,13 +174,13 @@ BiffDecoder_RCF::BiffDecoder_RCF( sal_uInt8 pnSalt[ 16 ], sal_uInt8 pnVerifier[ BiffDecoder_RCF::BiffDecoder_RCF( const BiffDecoder_RCF& rDecoder ) : BiffDecoderBase(), // must be called to prevent compiler warning - maPassword( rDecoder.maPassword ), + maEncryptionData( rDecoder.maEncryptionData ), maSalt( rDecoder.maSalt ), maVerifier( rDecoder.maVerifier ), maVerifierHash( rDecoder.maVerifierHash ) { if( isValid() ) - maCodec.initKey( &maPassword.front(), &maSalt.front() ); + maCodec.initCodec( maEncryptionData ); } BiffDecoder_RCF* BiffDecoder_RCF::implClone() @@ -167,25 +188,44 @@ BiffDecoder_RCF* BiffDecoder_RCF::implClone() return new BiffDecoder_RCF( *this ); } -bool BiffDecoder_RCF::implVerify( const OUString& rPassword ) +Sequence< NamedValue > BiffDecoder_RCF::implVerifyPassword( const OUString& rPassword ) { + maEncryptionData.realloc( 0 ); + sal_Int32 nLen = rPassword.getLength(); if( (0 < nLen) && (nLen < 16) ) { // copy string to sal_uInt16 array - maPassword.clear(); - maPassword.resize( 16, 0 ); + ::std::vector< sal_uInt16 > aPassVect( 16 ); const sal_Unicode* pcChar = rPassword.getStr(); const sal_Unicode* pcCharEnd = pcChar + nLen; - ::std::vector< sal_uInt16 >::iterator aIt = maPassword.begin(); + ::std::vector< sal_uInt16 >::iterator aIt = aPassVect.begin(); for( ; pcChar < pcCharEnd; ++pcChar, ++aIt ) *aIt = static_cast< sal_uInt16 >( *pcChar ); // init codec - maCodec.initKey( &maPassword.front(), &maSalt.front() ); - return maCodec.verifyKey( &maVerifier.front(), &maVerifierHash.front() ); + maCodec.initKey( &aPassVect.front(), &maSalt.front() ); + if( maCodec.verifyKey( &maVerifier.front(), &maVerifierHash.front() ) ) + maEncryptionData = maCodec.getEncryptionData(); } - return false; + + return maEncryptionData; +} + +bool BiffDecoder_RCF::implVerifyEncryptionData( const Sequence< NamedValue >& rEncryptionData ) +{ + maEncryptionData.realloc( 0 ); + + if( rEncryptionData.hasElements() ) + { + // init codec + maCodec.initCodec( rEncryptionData ); + + if( maCodec.verifyKey( &maVerifier.front(), &maVerifierHash.front() ) ) + maEncryptionData = rEncryptionData; + } + + return maEncryptionData.hasElements(); } void BiffDecoder_RCF::implDecode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcData, sal_Int64 nStreamPos, sal_uInt16 nBytes ) @@ -319,7 +359,7 @@ bool BiffCodecHelper::importFilePass( BiffInputStream& rStrm ) mxDecoder = implReadFilePass( rStrm, getBiff() ); // request and verify a password (decoder implements IDocPasswordVerifier) if( mxDecoder.get() ) - getBaseFilter().requestPassword( *mxDecoder ); + getBaseFilter().requestEncryptionData( *mxDecoder ); // correct password is indicated by isValid() function of decoder return mxDecoder.get() && mxDecoder->isValid(); } diff --git a/oox/source/xls/worksheethelper.cxx b/oox/source/xls/worksheethelper.cxx index b4f8a4459234..2bd8deeeae57 100644 --- a/oox/source/xls/worksheethelper.cxx +++ b/oox/source/xls/worksheethelper.cxx @@ -376,7 +376,7 @@ public: Size getCellSize( sal_Int32 nCol, sal_Int32 nRow ) const; /** Returns the address of the cell that contains the passed point in 1/100 mm. */ - CellAddress getCellAddressFromPosition( const Point& rPosition, const CellAddress* pStartAddr = 0 ) const; + CellAddress getCellAddressFromPosition( const Point& rPosition, const Size& rDrawPageSize ) const; /** Returns the cell range address that contains the passed rectangle in 1/100 mm. */ CellRangeAddress getCellRangeFromRectangle( const Rectangle& rRect ) const; @@ -771,41 +771,117 @@ Size WorksheetData::getCellSize( sal_Int32 nCol, sal_Int32 nRow ) const return aSize; } -CellAddress WorksheetData::getCellAddressFromPosition( const Point& rPosition, const CellAddress* pStartAddr ) const +namespace { + +inline sal_Int32 lclGetMidAddr( sal_Int32 nBegAddr, sal_Int32 nEndAddr, sal_Int32 nBegPos, sal_Int32 nEndPos, sal_Int32 nSearchPos ) +{ + // use sal_Int64 to prevent integer overflow + return nBegAddr + 1 + static_cast< sal_Int32 >( static_cast< sal_Int64 >( nEndAddr - nBegAddr - 2 ) * (nSearchPos - nBegPos) / (nEndPos - nBegPos) ); +} + +bool lclPrepareInterval( sal_Int32 nBegAddr, sal_Int32& rnMidAddr, sal_Int32 nEndAddr, + sal_Int32 nBegPos, sal_Int32 nEndPos, sal_Int32 nSearchPos ) { - // prepare start address for search loop - sal_Int32 nCol = pStartAddr ? ::std::min< sal_Int32 >( pStartAddr->Column + 1, mrMaxApiPos.Column ) : 1; - sal_Int32 nRow = pStartAddr ? ::std::min< sal_Int32 >( pStartAddr->Row + 1, mrMaxApiPos.Row ) : 1; + // searched position before nBegPos -> use nBegAddr + if( nSearchPos <= nBegPos ) + { + rnMidAddr = nBegAddr; + return false; + } + + // searched position after nEndPos, or begin next to end -> use nEndAddr + if( (nSearchPos >= nEndPos) || (nBegAddr + 1 >= nEndAddr) ) + { + rnMidAddr = nEndAddr; + return false; + } + + /* Otherwise find mid address according to position. lclGetMidAddr() will + return an address between nBegAddr and nEndAddr. */ + rnMidAddr = lclGetMidAddr( nBegAddr, nEndAddr, nBegPos, nEndPos, nSearchPos ); + return true; +} + +bool lclUpdateInterval( sal_Int32& rnBegAddr, sal_Int32& rnMidAddr, sal_Int32& rnEndAddr, + sal_Int32& rnBegPos, sal_Int32 nMidPos, sal_Int32& rnEndPos, sal_Int32 nSearchPos ) +{ + // nSearchPos < nMidPos: use the interval [begin,mid] in the next iteration + if( nSearchPos < nMidPos ) + { + // if rnBegAddr is next to rnMidAddr, the latter is the column/row in question + if( rnBegAddr + 1 >= rnMidAddr ) + return false; + // otherwise, set interval end to mid + rnEndPos = nMidPos; + rnEndAddr = rnMidAddr; + rnMidAddr = lclGetMidAddr( rnBegAddr, rnEndAddr, rnBegPos, rnEndPos, nSearchPos ); + return true; + } + + // nSearchPos > nMidPos: use the interval [mid,end] in the next iteration + if( nSearchPos > nMidPos ) + { + // if rnMidAddr is next to rnEndAddr, the latter is the column/row in question + if( rnMidAddr + 1 >= rnEndAddr ) + { + rnMidAddr = rnEndAddr; + return false; + } + // otherwise, set interval start to mid + rnBegPos = nMidPos; + rnBegAddr = rnMidAddr; + rnMidAddr = lclGetMidAddr( rnBegAddr, rnEndAddr, rnBegPos, rnEndPos, nSearchPos ); + return true; + } + + // nSearchPos == nMidPos: rnMidAddr is the column/row in question, do not loop anymore + return false; +} + +} // namespace + +CellAddress WorksheetData::getCellAddressFromPosition( const Point& rPosition, const Size& rDrawPageSize ) const +{ + // starting cell address and its position in drawing layer (top-left edge) + sal_Int32 nBegCol = 0; + sal_Int32 nBegRow = 0; + Point aBegPos( 0, 0 ); + + // end cell address and its position in drawing layer (bottom-right edge) + sal_Int32 nEndCol = mrMaxApiPos.Column + 1; + sal_Int32 nEndRow = mrMaxApiPos.Row + 1; + Point aEndPos( rDrawPageSize.Width, rDrawPageSize.Height ); + + // starting point for interval search + sal_Int32 nMidCol, nMidRow; + bool bLoopCols = lclPrepareInterval( nBegCol, nMidCol, nEndCol, aBegPos.X, aEndPos.X, rPosition.X ); + bool bLoopRows = lclPrepareInterval( nBegRow, nMidRow, nEndRow, aBegPos.Y, aEndPos.Y, rPosition.Y ); + Point aMidPos = getCellPosition( nMidCol, nMidRow ); /* The loop will find the column/row index of the cell right of/below the cell containing the passed point, unless the point is located at the top or left border of the containing cell. */ - bool bNextCol = true; - bool bNextRow = true; - Point aCellPos; - do + while( bLoopCols || bLoopRows ) { - aCellPos = getCellPosition( nCol, nRow ); - if( bNextCol && ((bNextCol = (aCellPos.X < rPosition.X) && (nCol < mrMaxApiPos.Column)) == true) ) - ++nCol; - if( bNextRow && ((bNextRow = (aCellPos.Y < rPosition.Y) && (nRow < mrMaxApiPos.Row)) == true) ) - ++nRow; + bLoopCols = bLoopCols && lclUpdateInterval( nBegCol, nMidCol, nEndCol, aBegPos.X, aMidPos.X, aEndPos.X, rPosition.X ); + bLoopRows = bLoopRows && lclUpdateInterval( nBegRow, nMidRow, nEndRow, aBegPos.Y, aMidPos.Y, aEndPos.Y, rPosition.Y ); + aMidPos = getCellPosition( nMidCol, nMidRow ); } - while( bNextCol || bNextRow ); /* The cell left of/above the current search position contains the passed point, unless the point is located on the top/left border of the cell, or the last column/row of the sheet has been reached. */ - if( aCellPos.X > rPosition.X ) --nCol; - if( aCellPos.Y > rPosition.Y ) --nRow; - return CellAddress( getSheetIndex(), nCol, nRow ); + if( aMidPos.X > rPosition.X ) --nMidCol; + if( aMidPos.Y > rPosition.Y ) --nMidRow; + return CellAddress( getSheetIndex(), nMidCol, nMidRow ); } CellRangeAddress WorksheetData::getCellRangeFromRectangle( const Rectangle& rRect ) const { - CellAddress aStartAddr = getCellAddressFromPosition( Point( rRect.X, rRect.Y ) ); + Size aPageSize = getDrawPageSize(); + CellAddress aStartAddr = getCellAddressFromPosition( Point( rRect.X, rRect.Y ), aPageSize ); Point aBotRight( rRect.X + rRect.Width, rRect.Y + rRect.Height ); - CellAddress aEndAddr = getCellAddressFromPosition( aBotRight ); + CellAddress aEndAddr = getCellAddressFromPosition( aBotRight, aPageSize ); bool bMultiCols = aStartAddr.Column < aEndAddr.Column; bool bMultiRows = aStartAddr.Row < aEndAddr.Row; if( bMultiCols || bMultiRows ) @@ -921,17 +997,25 @@ void WorksheetData::extendUsedArea( const CellRangeAddress& rRange ) void WorksheetData::extendShapeBoundingBox( const Rectangle& rShapeRect ) { + // scale EMUs to 1/100 mm + const UnitConverter& rUnitConv = getUnitConverter(); + Rectangle aShapeRectHmm( + rUnitConv.scaleToMm100( rShapeRect.X, UNIT_EMU ), + rUnitConv.scaleToMm100( rShapeRect.Y, UNIT_EMU ), + rUnitConv.scaleToMm100( rShapeRect.Width, UNIT_EMU ), + rUnitConv.scaleToMm100( rShapeRect.Height, UNIT_EMU ) ); + if( (maShapeBoundingBox.Width == 0) && (maShapeBoundingBox.Height == 0) ) { // width and height of maShapeBoundingBox are assumed to be zero on first cell - maShapeBoundingBox = rShapeRect; + maShapeBoundingBox = aShapeRectHmm; } else { - sal_Int32 nEndX = ::std::max( maShapeBoundingBox.X + maShapeBoundingBox.Width, rShapeRect.X + rShapeRect.Width ); - sal_Int32 nEndY = ::std::max( maShapeBoundingBox.Y + maShapeBoundingBox.Height, rShapeRect.Y + rShapeRect.Height ); - maShapeBoundingBox.X = ::std::min( maShapeBoundingBox.X, rShapeRect.X ); - maShapeBoundingBox.Y = ::std::min( maShapeBoundingBox.Y, rShapeRect.Y ); + sal_Int32 nEndX = ::std::max( maShapeBoundingBox.X + maShapeBoundingBox.Width, aShapeRectHmm.X + aShapeRectHmm.Width ); + sal_Int32 nEndY = ::std::max( maShapeBoundingBox.Y + maShapeBoundingBox.Height, aShapeRectHmm.Y + aShapeRectHmm.Height ); + maShapeBoundingBox.X = ::std::min( maShapeBoundingBox.X, aShapeRectHmm.X ); + maShapeBoundingBox.Y = ::std::min( maShapeBoundingBox.Y, aShapeRectHmm.Y ); maShapeBoundingBox.Width = nEndX - maShapeBoundingBox.X; maShapeBoundingBox.Height = nEndY - maShapeBoundingBox.Y; } diff --git a/unoxml/prj/build.lst b/unoxml/prj/build.lst index 1a6b330c2c6b..4da29cb9d669 100644 --- a/unoxml/prj/build.lst +++ b/unoxml/prj/build.lst @@ -1,4 +1,4 @@ -ux unoxml : offuh cppuhelper LIBXML2:libxml2 REDLAND:redland tools NULL +ux unoxml : offuh cppuhelper LIBXML2:libxml2 LIBXSLT:libxslt REDLAND:redland tools NULL ux unoxml\source\dom nmake - all ux_dom NULL ux unoxml\source\xpath nmake - all ux_xpath ux_dom NULL ux unoxml\source\events nmake - all ux_events ux_dom NULL diff --git a/writerfilter/qa/cppunittests/doctok/makefile.mk b/writerfilter/qa/cppunittests/doctok/makefile.mk index 298bb4da906b..e7de9f8b4446 100644 --- a/writerfilter/qa/cppunittests/doctok/makefile.mk +++ b/writerfilter/qa/cppunittests/doctok/makefile.mk @@ -28,8 +28,6 @@ PRJ=..$/..$/.. PRJNAME=writerfilter TARGET=test-doctok -# this is removed at the moment because we need some enhancements -# TESTDIR=TRUE ENABLE_EXCEPTIONS=TRUE diff --git a/writerfilter/qa/cppunittests/qname/makefile.mk b/writerfilter/qa/cppunittests/qname/makefile.mk index c2e989d91beb..2f51eb3844c7 100644 --- a/writerfilter/qa/cppunittests/qname/makefile.mk +++ b/writerfilter/qa/cppunittests/qname/makefile.mk @@ -28,8 +28,6 @@ PRJ=..$/..$/.. PRJNAME=writerfilter TARGET=test-qname -# this is removed at the moment because we need some enhancements -# TESTDIR=TRUE ENABLE_EXCEPTIONS=TRUE diff --git a/writerfilter/qa/cppunittests/sl/makefile.mk b/writerfilter/qa/cppunittests/sl/makefile.mk index b7a943e376e9..fa7cafc1dd00 100644 --- a/writerfilter/qa/cppunittests/sl/makefile.mk +++ b/writerfilter/qa/cppunittests/sl/makefile.mk @@ -28,8 +28,6 @@ PRJ=..$/..$/.. PRJNAME=writerfilter TARGET=test-od_sl -# this is removed at the moment because we need some enhancements -# TESTDIR=TRUE ENABLE_EXCEPTIONS=TRUE diff --git a/writerfilter/qa/cppunittests/xxml/makefile.mk b/writerfilter/qa/cppunittests/xxml/makefile.mk index 32d0febc1c85..7f0d3f9731b4 100644 --- a/writerfilter/qa/cppunittests/xxml/makefile.mk +++ b/writerfilter/qa/cppunittests/xxml/makefile.mk @@ -28,8 +28,6 @@ PRJ=..$/..$/.. PRJNAME=writerfilter TARGET=test-xxml -# this is removed at the moment because we need some enhancements -# TESTDIR=TRUE ENABLE_EXCEPTIONS=TRUE diff --git a/writerfilter/source/filter/RtfFilter.cxx b/writerfilter/source/filter/RtfFilter.cxx new file mode 100644 index 000000000000..040843afd7ce --- /dev/null +++ b/writerfilter/source/filter/RtfFilter.cxx @@ -0,0 +1,146 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * Copyright 2010 Miklos Vajna. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_ +#include <cppuhelper/implementationentry.hxx> +#endif +#include <osl/module.hxx> +#include <tools/solar.h> +#include <RtfFilter.hxx> + +using namespace ::rtl; +using namespace ::cppu; +using namespace ::com::sun::star; + +RtfFilter::RtfFilter( const uno::Reference< uno::XComponentContext >& rxContext) : + m_xContext( rxContext ) +{ +} + +RtfFilter::~RtfFilter() +{ +} + +sal_Bool RtfFilter::filter( const uno::Sequence< beans::PropertyValue >& aDescriptor ) + throw (uno::RuntimeException) +{ + OSL_TRACE("%s", OSL_THIS_FUNC); + if( m_xSrcDoc.is() ) + { + uno::Reference< lang::XMultiServiceFactory > xMSF(m_xContext->getServiceManager(), uno::UNO_QUERY_THROW); + uno::Reference< uno::XInterface > xIfc( xMSF->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Writer.RtfExport" ))), uno::UNO_QUERY_THROW); + if (!xIfc.is()) + return sal_False; + uno::Reference< document::XExporter > xExprtr(xIfc, uno::UNO_QUERY_THROW); + uno::Reference< document::XFilter > xFltr(xIfc, uno::UNO_QUERY_THROW); + if (!xExprtr.is() || !xFltr.is()) + return sal_False; + xExprtr->setSourceDocument(m_xSrcDoc); + return xFltr->filter(aDescriptor); + } + else if ( m_xDstDoc.is() ) + { + uno::Reference< lang::XMultiServiceFactory > xMSF(m_xContext->getServiceManager(), uno::UNO_QUERY_THROW); + uno::Reference< uno::XInterface > xIfc( xMSF->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Writer.RtfImport" ))), uno::UNO_QUERY_THROW); + if (!xIfc.is()) + return sal_False; + uno::Reference< document::XImporter > xImprtr(xIfc, uno::UNO_QUERY_THROW); + uno::Reference< document::XFilter > xFltr(xIfc, uno::UNO_QUERY_THROW); + if (!xImprtr.is() || !xFltr.is()) + return sal_False; + xImprtr->setTargetDocument(m_xDstDoc); + return xFltr->filter(aDescriptor); + } + return sal_False; +} + +void RtfFilter::cancel( ) throw (uno::RuntimeException) +{ +} + +void RtfFilter::setSourceDocument( const uno::Reference< lang::XComponent >& xDoc ) + throw (lang::IllegalArgumentException, uno::RuntimeException) +{ + m_xSrcDoc = xDoc; +} + +void RtfFilter::setTargetDocument( const uno::Reference< lang::XComponent >& xDoc ) + throw (lang::IllegalArgumentException, uno::RuntimeException) +{ + m_xDstDoc = xDoc; +} + +void RtfFilter::initialize( const uno::Sequence< uno::Any >& /*aArguments*/ ) throw (uno::Exception, uno::RuntimeException) +{ + // The DOCX exporter here extracts 'type' of the filter, ie 'Word' or + // 'Word Template' but we don't need it for RTF. +} + +OUString RtfFilter::getImplementationName( ) throw (uno::RuntimeException) +{ + return RtfFilter_getImplementationName(); +} + +#define SERVICE_NAME1 "com.sun.star.document.ImportFilter" +#define SERVICE_NAME2 "com.sun.star.document.ExportFilter" +sal_Bool RtfFilter::supportsService( const OUString& rServiceName ) throw (uno::RuntimeException) +{ + return (rServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME1 ) ) || + rServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME2 ) )); +} + +uno::Sequence< OUString > RtfFilter::getSupportedServiceNames( ) throw (uno::RuntimeException) +{ + return RtfFilter_getSupportedServiceNames(); +} + +/* Helpers, used by shared lib exports. */ + +OUString RtfFilter_getImplementationName () throw (uno::RuntimeException) +{ + return OUString ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Writer.RtfFilter" ) ); +} + +uno::Sequence< OUString > RtfFilter_getSupportedServiceNames( ) throw (uno::RuntimeException) +{ + uno::Sequence < OUString > aRet(2); + OUString* pArray = aRet.getArray(); + pArray[0] = OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME1 ) ); + pArray[1] = OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME2 ) ); + return aRet; +} +#undef SERVICE_NAME1 +#undef SERVICE_NAME2 + +uno::Reference< uno::XInterface > RtfFilter_createInstance( const uno::Reference< uno::XComponentContext >& xContext) + throw( uno::Exception ) +{ + return (cppu::OWeakObject*) new RtfFilter( xContext ); +} + +/* vi:set shiftwidth=4 expandtab: */ diff --git a/writerfilter/source/filter/RtfFilter.hxx b/writerfilter/source/filter/RtfFilter.hxx new file mode 100644 index 000000000000..3a4be622ab17 --- /dev/null +++ b/writerfilter/source/filter/RtfFilter.hxx @@ -0,0 +1,102 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * Copyright 2010 Miklos Vajna. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _RTFFILTER_HXX +#define _RTFFILTER_HXX + +#include <com/sun/star/document/XFilter.hpp> +#include <com/sun/star/document/XImporter.hpp> +#include <com/sun/star/document/XExporter.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/xml/sax/XDocumentHandler.hpp> +#include <cppuhelper/implbase5.hxx> +#include <WriterFilterDllApi.hxx> + +class WRITERFILTER_DLLPUBLIC RtfFilter : public cppu::WeakImplHelper5 +< + com::sun::star::document::XFilter, + com::sun::star::document::XImporter, + com::sun::star::document::XExporter, + com::sun::star::lang::XInitialization, + com::sun::star::lang::XServiceInfo +> +{ + +protected: + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xContext; + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > m_xSrcDoc, m_xDstDoc; + ::rtl::OUString m_sFilterName; + ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler > m_xHandler; + + +public: + RtfFilter( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext); + virtual ~RtfFilter(); + + // XFilter + virtual sal_Bool SAL_CALL filter( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor ) + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL cancel( ) + throw (::com::sun::star::uno::RuntimeException); + + // XImporter + virtual void SAL_CALL setTargetDocument( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& xDoc ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + + // XExporter + virtual void SAL_CALL setSourceDocument( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& xDoc ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + + // XInitialization + virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) + throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) + throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() + throw (::com::sun::star::uno::RuntimeException); + +}; + + +::rtl::OUString RtfFilter_getImplementationName() + throw ( ::com::sun::star::uno::RuntimeException ); + +::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL RtfFilter_getSupportedServiceNames( ) + throw ( ::com::sun::star::uno::RuntimeException ); + +::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL RtfFilter_createInstance( + const ::com::sun::star::uno::Reference< + ::com::sun::star::uno::XComponentContext > &xContext) + throw( ::com::sun::star::uno::Exception ); +#endif + diff --git a/writerfilter/source/filter/WriterFilter.cxx b/writerfilter/source/filter/WriterFilter.cxx index f8775d097f66..deede335d9af 100644 --- a/writerfilter/source/filter/WriterFilter.cxx +++ b/writerfilter/source/filter/WriterFilter.cxx @@ -30,6 +30,7 @@ #endif #include <WriterFilter.hxx> #include <WriterFilterDetection.hxx> +#include <RtfFilter.hxx> using namespace ::rtl; using namespace ::cppu; @@ -56,6 +57,7 @@ static struct ::cppu::ImplementationEntry s_component_entries [] = { { WriterFilter_createInstance, WriterFilter_getImplementationName, WriterFilter_getSupportedServiceNames, ::cppu::createSingleComponentFactory, 0, 0 }, { WriterFilterDetection_createInstance, WriterFilterDetection_getImplementationName, WriterFilterDetection_getSupportedServiceNames, ::cppu::createSingleComponentFactory, 0, 0} , + { RtfFilter_createInstance, RtfFilter_getImplementationName, RtfFilter_getSupportedServiceNames, ::cppu::createSingleComponentFactory, 0, 0 }, { 0, 0, 0, 0, 0, 0 } // terminate with NULL }; diff --git a/writerfilter/source/filter/makefile.mk b/writerfilter/source/filter/makefile.mk index f578e2853243..6b11fd4ff1f3 100644 --- a/writerfilter/source/filter/makefile.mk +++ b/writerfilter/source/filter/makefile.mk @@ -40,7 +40,8 @@ ENABLE_EXCEPTIONS=TRUE SLOFILES= $(SLO)$/WriterFilter.obj \ $(SLO)$/WriterFilterDetection.obj \ - $(SLO)$/ImportFilter.obj + $(SLO)$/ImportFilter.obj \ + $(SLO)$/RtfFilter.obj # --- Targets ---------------------------------- diff --git a/writerfilter/util/writerfilter.component b/writerfilter/util/writerfilter.component index 5d4c628df978..7a81b6cc3a2b 100644 --- a/writerfilter/util/writerfilter.component +++ b/writerfilter/util/writerfilter.component @@ -35,4 +35,8 @@ <implementation name="com.sun.star.comp.Writer.WriterFilterDetector"> <service name="com.sun.star.document.ExtendedTypeDetection"/> </implementation> + <implementation name="com.sun.star.comp.Writer.RtfFilter"> + <service name="com.sun.star.document.ImportFilter"/> + <service name="com.sun.star.document.ExportFilter"/> + </implementation> </component> diff --git a/writerperfect/prj/build.lst b/writerperfect/prj/build.lst index 3bb3867d8633..9c1fbafc16eb 100644 --- a/writerperfect/prj/build.lst +++ b/writerperfect/prj/build.lst @@ -1,4 +1,4 @@ -wp writerperfect : LIBWPD:libwpd sot comphelper xmloff NULL +wp writerperfect : LIBWPD:libwpd sot comphelper xmloff LIBXSLT:libxslt NULL wp writerperfect usr1 - all wp_mkout NULL wp writerperfect\source\stream nmake - all wp_stream NULL wp writerperfect\source\filter nmake - all wp_filter NULL diff --git a/xmerge/prj/build.lst b/xmerge/prj/build.lst index c9f6a8e4d332..39cde4210a1b 100644 --- a/xmerge/prj/build.lst +++ b/xmerge/prj/build.lst @@ -1,4 +1,4 @@ -xmrg xmerge : solenv unoil javaunohelper NULL +xmrg xmerge : solenv unoil javaunohelper LIBXSLT:libxslt NULL xmrg xmerge usr1 - all xmrg_mkout NULL xmrg xmerge\inc nmake - all xmrg_inc NULL xmrg xmerge\source\xmerge nmake - all xmrg_xmerge xmrg_inc NULL |