Update ooo320-m1
[ooovba.git] / package / source / manifest / ManifestImport.cxx
blob545c0f01dab33a99fe595c98f054cd9e250f4b18
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ManifestImport.cxx,v $
10 * $Revision: 1.12 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * ( a copy is included in the LICENSE file that accompanied this code ).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER( update_precomp.py ): autogen include statement, do not remove
32 #include "precompiled_package.hxx"
33 #include <ManifestImport.hxx>
34 #include <ManifestDefines.hxx>
35 #ifndef _BASE64_CODEC_HXX_
36 #include <Base64Codec.hxx>
37 #endif
38 #include <com/sun/star/xml/sax/XAttributeList.hpp>
39 #include <com/sun/star/beans/PropertyValue.hpp>
41 using namespace com::sun::star::uno;
42 using namespace com::sun::star::beans;
43 using namespace com::sun::star;
44 using namespace rtl;
45 using namespace std;
47 // ---------------------------------------------------
48 ManifestImport::ManifestImport( vector < Sequence < PropertyValue > > & rNewManVector )
49 : nNumProperty ( 0 )
50 , bIgnoreEncryptData ( sal_False )
51 , rManVector ( rNewManVector )
53 , sFileEntryElement ( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_FILE_ENTRY ) )
54 , sManifestElement ( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_MANIFEST ) )
55 , sEncryptionDataElement( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_ENCRYPTION_DATA ) )
56 , sAlgorithmElement ( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_ALGORITHM ) )
57 , sKeyDerivationElement( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_KEY_DERIVATION ) )
59 , sCdataAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_CDATA ) )
60 , sMediaTypeAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_MEDIA_TYPE ) )
61 , sVersionAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_VERSION ) )
62 , sFullPathAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_FULL_PATH ) )
63 , sSizeAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_SIZE ) )
64 , sSaltAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_SALT ) )
65 , sInitialisationVectorAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_INITIALISATION_VECTOR ) )
66 , sIterationCountAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_ITERATION_COUNT ) )
67 , sAlgorithmNameAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_ALGORITHM_NAME ) )
68 , sKeyDerivationNameAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_KEY_DERIVATION_NAME ) )
69 , sChecksumAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_CHECKSUM ) )
70 , sChecksumTypeAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_CHECKSUM_TYPE ) )
72 , sFullPathProperty ( RTL_CONSTASCII_USTRINGPARAM ( "FullPath" ) )
73 , sMediaTypeProperty ( RTL_CONSTASCII_USTRINGPARAM ( "MediaType" ) )
74 , sVersionProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Version" ) )
75 , sIterationCountProperty ( RTL_CONSTASCII_USTRINGPARAM ( "IterationCount" ) )
76 , sSaltProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Salt" ) )
77 , sInitialisationVectorProperty ( RTL_CONSTASCII_USTRINGPARAM ( "InitialisationVector" ) )
78 , sSizeProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Size" ) )
79 , sDigestProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Digest" ) )
81 , sWhiteSpace ( RTL_CONSTASCII_USTRINGPARAM ( " " ) )
82 , sBlowfish ( RTL_CONSTASCII_USTRINGPARAM ( "Blowfish CFB" ) )
83 , sPBKDF2 ( RTL_CONSTASCII_USTRINGPARAM ( "PBKDF2" ) )
84 , sChecksumType ( RTL_CONSTASCII_USTRINGPARAM ( CHECKSUM_TYPE ) )
86 aStack.reserve( 10 );
89 // ---------------------------------------------------
90 ManifestImport::~ManifestImport ( void )
94 // ---------------------------------------------------
95 void SAL_CALL ManifestImport::startDocument( )
96 throw( xml::sax::SAXException, uno::RuntimeException )
100 // ---------------------------------------------------
101 void SAL_CALL ManifestImport::endDocument( )
102 throw( xml::sax::SAXException, uno::RuntimeException )
106 // ---------------------------------------------------
107 void SAL_CALL ManifestImport::startElement( const OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs )
108 throw( xml::sax::SAXException, uno::RuntimeException )
110 StringHashMap aConvertedAttribs;
111 ::rtl::OUString aConvertedName = PushNameAndNamespaces( aName, xAttribs, aConvertedAttribs );
113 if ( aConvertedName == sFileEntryElement )
115 aSequence.realloc ( PKG_SIZE_ENCR_MNFST );
117 // Put full-path property first for MBA
118 aSequence[nNumProperty].Name = sFullPathProperty;
119 aSequence[nNumProperty++].Value <<= aConvertedAttribs[sFullPathAttribute];
120 aSequence[nNumProperty].Name = sMediaTypeProperty;
121 aSequence[nNumProperty++].Value <<= aConvertedAttribs[sMediaTypeAttribute];
123 OUString sVersion = aConvertedAttribs[sVersionAttribute];
124 if ( sVersion.getLength() )
126 aSequence[nNumProperty].Name = sVersionProperty;
127 aSequence[nNumProperty++].Value <<= sVersion;
130 OUString sSize = aConvertedAttribs[sSizeAttribute];
131 if ( sSize.getLength() )
133 sal_Int32 nSize;
134 nSize = sSize.toInt32();
135 aSequence[nNumProperty].Name = sSizeProperty;
136 aSequence[nNumProperty++].Value <<= nSize;
139 else if ( aStack.size() > 1 )
141 ManifestStack::reverse_iterator aIter = aStack.rbegin();
142 aIter++;
144 if ( aIter->m_aConvertedName.equals( sFileEntryElement ) )
146 if ( aConvertedName.equals( sEncryptionDataElement ) )
148 // If this element exists, then this stream is encrypted and we need
149 // to store the initialisation vector, salt and iteration count used
150 OUString aString = aConvertedAttribs[sChecksumTypeAttribute];
151 if ( aString == sChecksumType && !bIgnoreEncryptData )
153 aString = aConvertedAttribs[sChecksumAttribute];
154 Sequence < sal_uInt8 > aDecodeBuffer;
155 Base64Codec::decodeBase64 ( aDecodeBuffer, aString );
156 aSequence[nNumProperty].Name = sDigestProperty;
157 aSequence[nNumProperty++].Value <<= aDecodeBuffer;
161 else if ( aIter->m_aConvertedName.equals( sEncryptionDataElement ) )
163 if ( aConvertedName == sAlgorithmElement )
165 OUString aString = aConvertedAttribs[sAlgorithmNameAttribute];
166 if ( aString == sBlowfish && !bIgnoreEncryptData )
168 aString = aConvertedAttribs[sInitialisationVectorAttribute];
169 Sequence < sal_uInt8 > aDecodeBuffer;
170 Base64Codec::decodeBase64 ( aDecodeBuffer, aString );
171 aSequence[nNumProperty].Name = sInitialisationVectorProperty;
172 aSequence[nNumProperty++].Value <<= aDecodeBuffer;
174 else
175 // If we don't recognise the algorithm, then the key derivation info
176 // is useless to us
177 bIgnoreEncryptData = sal_True;
179 else if ( aConvertedName == sKeyDerivationElement )
181 OUString aString = aConvertedAttribs[sKeyDerivationNameAttribute];
182 if ( aString == sPBKDF2 && !bIgnoreEncryptData )
184 aString = aConvertedAttribs[sSaltAttribute];
185 Sequence < sal_uInt8 > aDecodeBuffer;
186 Base64Codec::decodeBase64 ( aDecodeBuffer, aString );
187 aSequence[nNumProperty].Name = sSaltProperty;
188 aSequence[nNumProperty++].Value <<= aDecodeBuffer;
190 aString = aConvertedAttribs[sIterationCountAttribute];
191 aSequence[nNumProperty].Name = sIterationCountProperty;
192 aSequence[nNumProperty++].Value <<= aString.toInt32();
194 else
195 // If we don't recognise the key derivation technique, then the
196 // algorithm info is useless to us
197 bIgnoreEncryptData = sal_True;
203 // ---------------------------------------------------
204 void SAL_CALL ManifestImport::endElement( const OUString& aName )
205 throw( xml::sax::SAXException, uno::RuntimeException )
207 ::rtl::OUString aConvertedName = ConvertName( aName );
208 if ( !aStack.empty() && aStack.rbegin()->m_aConvertedName.equals( aConvertedName ) )
210 if ( aConvertedName.equals( sFileEntryElement ) )
212 aSequence.realloc ( nNumProperty );
213 bIgnoreEncryptData = sal_False;
214 rManVector.push_back ( aSequence );
215 nNumProperty = 0;
218 aStack.pop_back();
222 // ---------------------------------------------------
223 void SAL_CALL ManifestImport::characters( const OUString& /*aChars*/ )
224 throw( xml::sax::SAXException, uno::RuntimeException )
228 // ---------------------------------------------------
229 void SAL_CALL ManifestImport::ignorableWhitespace( const OUString& /*aWhitespaces*/ )
230 throw( xml::sax::SAXException, uno::RuntimeException )
234 // ---------------------------------------------------
235 void SAL_CALL ManifestImport::processingInstruction( const OUString& /*aTarget*/, const OUString& /*aData*/ )
236 throw( xml::sax::SAXException, uno::RuntimeException )
240 // ---------------------------------------------------
241 void SAL_CALL ManifestImport::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& /*xLocator*/ )
242 throw( xml::sax::SAXException, uno::RuntimeException )
246 // ---------------------------------------------------
247 ::rtl::OUString ManifestImport::PushNameAndNamespaces( const ::rtl::OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs, StringHashMap& o_aConvertedAttribs )
249 StringHashMap aNamespaces;
250 ::std::vector< ::std::pair< ::rtl::OUString, ::rtl::OUString > > aAttribsStrs;
252 if ( xAttribs.is() )
254 sal_Int16 nAttrCount = xAttribs.is() ? xAttribs->getLength() : 0;
255 aAttribsStrs.reserve( nAttrCount );
257 for( sal_Int16 nInd = 0; nInd < nAttrCount; nInd++ )
259 ::rtl::OUString aAttrName = xAttribs->getNameByIndex( nInd );
260 ::rtl::OUString aAttrValue = xAttribs->getValueByIndex( nInd );
261 if ( aAttrName.getLength() >= 5
262 && aAttrName.compareToAscii( "xmlns", 5 ) == 0
263 && ( aAttrName.getLength() == 5 || aAttrName.getStr()[5] == ( sal_Unicode )':' ) )
265 // this is a namespace declaration
266 ::rtl::OUString aNsName( ( aAttrName.getLength() == 5 ) ? ::rtl::OUString() : aAttrName.copy( 6 ) );
267 aNamespaces[aNsName] = aAttrValue;
269 else
271 // this is no namespace declaration
272 aAttribsStrs.push_back( pair< ::rtl::OUString, ::rtl::OUString >( aAttrName, aAttrValue ) );
277 ::rtl::OUString aConvertedName = ConvertNameWithNamespace( aName, aNamespaces );
278 if ( !aConvertedName.getLength() )
279 aConvertedName = ConvertName( aName );
281 aStack.push_back( ManifestScopeEntry( aConvertedName, aNamespaces ) );
283 for ( sal_uInt16 nInd = 0; nInd < aAttribsStrs.size(); nInd++ )
285 // convert the attribute names on filling
286 o_aConvertedAttribs[ConvertName( aAttribsStrs[nInd].first )] = aAttribsStrs[nInd].second;
289 return aConvertedName;
292 // ---------------------------------------------------
293 ::rtl::OUString ManifestImport::ConvertNameWithNamespace( const ::rtl::OUString& aName, const StringHashMap& aNamespaces )
295 ::rtl::OUString aNsAlias;
296 ::rtl::OUString aPureName = aName;
298 sal_Int32 nInd = aName.indexOf( ( sal_Unicode )':' );
299 if ( nInd != -1 && nInd < aName.getLength() )
301 aNsAlias = aName.copy( 0, nInd );
302 aPureName = aName.copy( nInd + 1 );
305 ::rtl::OUString aResult;
307 StringHashMap::const_iterator aIter = aNamespaces.find( aNsAlias );
308 if ( aIter != aNamespaces.end()
309 && ( aIter->second.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MANIFEST_NAMESPACE ) ) )
310 || aIter->second.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MANIFEST_OASIS_NAMESPACE ) ) ) ) )
312 // no check for manifest.xml consistency currently since the old versions have supported inconsistent documents as well
313 aResult = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MANIFEST_NSPREFIX ) );
314 aResult += aPureName;
317 return aResult;
320 // ---------------------------------------------------
321 ::rtl::OUString ManifestImport::ConvertName( const ::rtl::OUString& aName )
323 ::rtl::OUString aConvertedName;
324 for ( ManifestStack::reverse_iterator aIter = aStack.rbegin(); !aConvertedName.getLength() && aIter != aStack.rend(); aIter++ )
326 if ( !aIter->m_aNamespaces.empty() )
327 aConvertedName = ConvertNameWithNamespace( aName, aIter->m_aNamespaces );
330 if ( !aConvertedName.getLength() )
331 aConvertedName = aName;
333 return aConvertedName;