1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER( update_precomp.py ): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_package.hxx"
26*b1cdbd2cSJim Jagielski #include <ManifestImport.hxx>
27*b1cdbd2cSJim Jagielski #include <ManifestDefines.hxx>
28*b1cdbd2cSJim Jagielski #include <sax/tools/converter.hxx>
29*b1cdbd2cSJim Jagielski 
30*b1cdbd2cSJim Jagielski #include <com/sun/star/xml/sax/XAttributeList.hpp>
31*b1cdbd2cSJim Jagielski #include <com/sun/star/xml/crypto/DigestID.hpp>
32*b1cdbd2cSJim Jagielski #include <com/sun/star/xml/crypto/CipherID.hpp>
33*b1cdbd2cSJim Jagielski 
34*b1cdbd2cSJim Jagielski using namespace com::sun::star::uno;
35*b1cdbd2cSJim Jagielski using namespace com::sun::star::beans;
36*b1cdbd2cSJim Jagielski using namespace com::sun::star;
37*b1cdbd2cSJim Jagielski using namespace rtl;
38*b1cdbd2cSJim Jagielski using namespace std;
39*b1cdbd2cSJim Jagielski 
40*b1cdbd2cSJim Jagielski // helper for ignoring multiple settings of the same property
41*b1cdbd2cSJim Jagielski #define setProperty(e,v) do{ if(!maValues[e].hasValue()) maValues[e] <<= v;} while(0)
42*b1cdbd2cSJim Jagielski 
getMnfstPropName(int nManifestPropId)43*b1cdbd2cSJim Jagielski static const char* getMnfstPropName( int nManifestPropId )
44*b1cdbd2cSJim Jagielski {
45*b1cdbd2cSJim Jagielski 	const char* pName;
46*b1cdbd2cSJim Jagielski 	switch( nManifestPropId )
47*b1cdbd2cSJim Jagielski 	{
48*b1cdbd2cSJim Jagielski 		case PKG_MNFST_MEDIATYPE:	pName = "MediaType"; break;
49*b1cdbd2cSJim Jagielski 		case PKG_MNFST_VERSION:		pName = "Version"; break;
50*b1cdbd2cSJim Jagielski 		case PKG_MNFST_FULLPATH:	pName = "FullPath"; break;
51*b1cdbd2cSJim Jagielski 		case PKG_MNFST_INIVECTOR:	pName = "InitialisationVector"; break;
52*b1cdbd2cSJim Jagielski 		case PKG_MNFST_SALT:		pName = "Salt"; break;
53*b1cdbd2cSJim Jagielski 		case PKG_MNFST_ITERATION:	pName = "IterationCount"; break;
54*b1cdbd2cSJim Jagielski 		case PKG_MNFST_UCOMPSIZE:	pName = "Size"; break;
55*b1cdbd2cSJim Jagielski 		case PKG_MNFST_DIGEST:		pName = "Digest"; break;
56*b1cdbd2cSJim Jagielski 		case PKG_MNFST_ENCALG:		pName = "EncryptionAlgorithm"; break;
57*b1cdbd2cSJim Jagielski 		case PKG_MNFST_STARTALG:	pName = "StartKeyAlgorithm"; break;
58*b1cdbd2cSJim Jagielski 		case PKG_MNFST_DIGESTALG:	pName = "DigestAlgorithm"; break;
59*b1cdbd2cSJim Jagielski 		case PKG_MNFST_DERKEYSIZE:	pName = "DerivedKeySize"; break;
60*b1cdbd2cSJim Jagielski 		default: pName = NULL;
61*b1cdbd2cSJim Jagielski 	}
62*b1cdbd2cSJim Jagielski 	return pName;
63*b1cdbd2cSJim Jagielski }
64*b1cdbd2cSJim Jagielski 
65*b1cdbd2cSJim Jagielski // ---------------------------------------------------
ManifestImport(vector<Sequence<PropertyValue>> & rNewManVector)66*b1cdbd2cSJim Jagielski ManifestImport::ManifestImport( vector < Sequence < PropertyValue > > & rNewManVector )
67*b1cdbd2cSJim Jagielski : rManVector ( rNewManVector )
68*b1cdbd2cSJim Jagielski , nDerivedKeySize( 0 )
69*b1cdbd2cSJim Jagielski , bIgnoreEncryptData( false )
70*b1cdbd2cSJim Jagielski 
71*b1cdbd2cSJim Jagielski , sCdataAttribute     			( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_CDATA ) )
72*b1cdbd2cSJim Jagielski , sMediaTypeAttribute 			( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_MEDIA_TYPE ) )
73*b1cdbd2cSJim Jagielski , sVersionAttribute 			( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_VERSION ) )
74*b1cdbd2cSJim Jagielski , sFullPathAttribute  			( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_FULL_PATH ) )
75*b1cdbd2cSJim Jagielski , sSizeAttribute 				( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_SIZE ) )
76*b1cdbd2cSJim Jagielski , sSaltAttribute 				( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_SALT ) )
77*b1cdbd2cSJim Jagielski , sInitialisationVectorAttribute(RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_INITIALISATION_VECTOR ) )
78*b1cdbd2cSJim Jagielski , sIterationCountAttribute 		( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_ITERATION_COUNT ) )
79*b1cdbd2cSJim Jagielski , sKeySizeAttribute            ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_KEY_SIZE ) )
80*b1cdbd2cSJim Jagielski , sAlgorithmNameAttribute 		( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_ALGORITHM_NAME ) )
81*b1cdbd2cSJim Jagielski , sStartKeyAlgNameAttribute    ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_START_KEY_GENERATION_NAME ) )
82*b1cdbd2cSJim Jagielski , sKeyDerivationNameAttribute 	( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_KEY_DERIVATION_NAME ) )
83*b1cdbd2cSJim Jagielski , sChecksumAttribute 			( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_CHECKSUM ) )
84*b1cdbd2cSJim Jagielski , sChecksumTypeAttribute 		( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_CHECKSUM_TYPE ) )
85*b1cdbd2cSJim Jagielski {
86*b1cdbd2cSJim Jagielski     aStack.reserve( 10 );
87*b1cdbd2cSJim Jagielski }
88*b1cdbd2cSJim Jagielski 
89*b1cdbd2cSJim Jagielski // ---------------------------------------------------
~ManifestImport(void)90*b1cdbd2cSJim Jagielski ManifestImport::~ManifestImport ( void )
91*b1cdbd2cSJim Jagielski {
92*b1cdbd2cSJim Jagielski }
93*b1cdbd2cSJim Jagielski 
94*b1cdbd2cSJim Jagielski // ---------------------------------------------------
startDocument()95*b1cdbd2cSJim Jagielski void SAL_CALL ManifestImport::startDocument(  )
96*b1cdbd2cSJim Jagielski 		throw( xml::sax::SAXException, uno::RuntimeException )
97*b1cdbd2cSJim Jagielski {
98*b1cdbd2cSJim Jagielski }
99*b1cdbd2cSJim Jagielski 
100*b1cdbd2cSJim Jagielski // ---------------------------------------------------
endDocument()101*b1cdbd2cSJim Jagielski void SAL_CALL ManifestImport::endDocument(  )
102*b1cdbd2cSJim Jagielski 		throw( xml::sax::SAXException, uno::RuntimeException )
103*b1cdbd2cSJim Jagielski {
104*b1cdbd2cSJim Jagielski }
105*b1cdbd2cSJim Jagielski 
106*b1cdbd2cSJim Jagielski // ---------------------------------------------------
startElement(const OUString & aName,const uno::Reference<xml::sax::XAttributeList> & xAttribs)107*b1cdbd2cSJim Jagielski void SAL_CALL ManifestImport::startElement( const OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs )
108*b1cdbd2cSJim Jagielski 		throw( xml::sax::SAXException, uno::RuntimeException )
109*b1cdbd2cSJim Jagielski {
110*b1cdbd2cSJim Jagielski     StringHashMap aConvertedAttribs;
111*b1cdbd2cSJim Jagielski     ::rtl::OUString aConvertedName = PushNameAndNamespaces( aName, xAttribs, aConvertedAttribs );
112*b1cdbd2cSJim Jagielski 
113*b1cdbd2cSJim Jagielski 	if ( aConvertedName.equalsAscii( ELEMENT_FILE_ENTRY ) )
114*b1cdbd2cSJim Jagielski 	{
115*b1cdbd2cSJim Jagielski 		setProperty( PKG_MNFST_FULLPATH, aConvertedAttribs[sFullPathAttribute]);
116*b1cdbd2cSJim Jagielski 		setProperty( PKG_MNFST_MEDIATYPE, aConvertedAttribs[sMediaTypeAttribute]);
117*b1cdbd2cSJim Jagielski 
118*b1cdbd2cSJim Jagielski 		const OUString& sVersion = aConvertedAttribs[sVersionAttribute];
119*b1cdbd2cSJim Jagielski         if ( sVersion.getLength() )
120*b1cdbd2cSJim Jagielski        		setProperty( PKG_MNFST_VERSION, sVersion );
121*b1cdbd2cSJim Jagielski 
122*b1cdbd2cSJim Jagielski 		const OUString& sSize = aConvertedAttribs[sSizeAttribute];
123*b1cdbd2cSJim Jagielski 		if ( sSize.getLength() )
124*b1cdbd2cSJim Jagielski        		setProperty( PKG_MNFST_UCOMPSIZE, sSize.toInt32() );
125*b1cdbd2cSJim Jagielski 	}
126*b1cdbd2cSJim Jagielski 	else if ( aStack.size() > 1 )
127*b1cdbd2cSJim Jagielski 	{
128*b1cdbd2cSJim Jagielski         ManifestStack::reverse_iterator aIter = aStack.rbegin();
129*b1cdbd2cSJim Jagielski         aIter++;
130*b1cdbd2cSJim Jagielski 
131*b1cdbd2cSJim Jagielski 		if ( aIter->m_aConvertedName.equalsAscii( ELEMENT_FILE_ENTRY ) )
132*b1cdbd2cSJim Jagielski         {
133*b1cdbd2cSJim Jagielski             if ( aConvertedName.equalsAscii( ELEMENT_ENCRYPTION_DATA ) )
134*b1cdbd2cSJim Jagielski             {
135*b1cdbd2cSJim Jagielski                 // If this element exists, then this stream is encrypted and we need
136*b1cdbd2cSJim Jagielski                 // to import the initialisation vector, salt and iteration count used
137*b1cdbd2cSJim Jagielski                 nDerivedKeySize = 0;
138*b1cdbd2cSJim Jagielski                 if ( !bIgnoreEncryptData )
139*b1cdbd2cSJim Jagielski                 {
140*b1cdbd2cSJim Jagielski                     sal_Int32 nDigestId = 0;
141*b1cdbd2cSJim Jagielski                     const OUString& rChecksumType = aConvertedAttribs[sChecksumTypeAttribute];
142*b1cdbd2cSJim Jagielski                     if( rChecksumType.equalsAscii( SHA1_1K_NAME )
143*b1cdbd2cSJim Jagielski                     ||  rChecksumType.equalsAscii( SHA1_1K_URL ) )
144*b1cdbd2cSJim Jagielski        		            nDigestId = xml::crypto::DigestID::SHA1_1K;
145*b1cdbd2cSJim Jagielski                     else if ( rChecksumType.equalsAscii( SHA256_1K_URL ) )
146*b1cdbd2cSJim Jagielski        		            nDigestId = xml::crypto::DigestID::SHA256_1K;
147*b1cdbd2cSJim Jagielski                     else
148*b1cdbd2cSJim Jagielski                         bIgnoreEncryptData = true;
149*b1cdbd2cSJim Jagielski 
150*b1cdbd2cSJim Jagielski                     if ( !bIgnoreEncryptData )
151*b1cdbd2cSJim Jagielski                     {
152*b1cdbd2cSJim Jagielski                         setProperty( PKG_MNFST_DIGESTALG, nDigestId );
153*b1cdbd2cSJim Jagielski                         const OUString& sChecksumData = aConvertedAttribs[sChecksumAttribute];
154*b1cdbd2cSJim Jagielski                         uno::Sequence < sal_Int8 > aDecodeBuffer;
155*b1cdbd2cSJim Jagielski                         ::sax::Converter::decodeBase64( aDecodeBuffer, sChecksumData );
156*b1cdbd2cSJim Jagielski                         setProperty( PKG_MNFST_DIGEST, aDecodeBuffer );
157*b1cdbd2cSJim Jagielski                     }
158*b1cdbd2cSJim Jagielski                 }
159*b1cdbd2cSJim Jagielski             }
160*b1cdbd2cSJim Jagielski         }
161*b1cdbd2cSJim Jagielski         else if ( aIter->m_aConvertedName.equalsAscii( ELEMENT_ENCRYPTION_DATA ) )
162*b1cdbd2cSJim Jagielski         {
163*b1cdbd2cSJim Jagielski             if ( aConvertedName.equalsAscii( ELEMENT_ALGORITHM ) )
164*b1cdbd2cSJim Jagielski             {
165*b1cdbd2cSJim Jagielski                 if ( !bIgnoreEncryptData )
166*b1cdbd2cSJim Jagielski                 {
167*b1cdbd2cSJim Jagielski                     sal_Int32 nCypherId = 0;
168*b1cdbd2cSJim Jagielski                     const OUString& rAlgoName = aConvertedAttribs[sAlgorithmNameAttribute];
169*b1cdbd2cSJim Jagielski                     if ( rAlgoName.equalsAscii( BLOWFISH_NAME )
170*b1cdbd2cSJim Jagielski                     ||   rAlgoName.equalsAscii( BLOWFISH_URL ) )
171*b1cdbd2cSJim Jagielski                     	 nCypherId = xml::crypto::CipherID::BLOWFISH_CFB_8;
172*b1cdbd2cSJim Jagielski                     else if( rAlgoName.equalsAscii( AES256_URL ) )
173*b1cdbd2cSJim Jagielski                     {
174*b1cdbd2cSJim Jagielski                     	 nCypherId = xml::crypto::CipherID::AES_CBC_W3C_PADDING;
175*b1cdbd2cSJim Jagielski                         OSL_ENSURE( !nDerivedKeySize || nDerivedKeySize == 32, "Unexpected derived key length!" );
176*b1cdbd2cSJim Jagielski                         nDerivedKeySize = 32;
177*b1cdbd2cSJim Jagielski                     }
178*b1cdbd2cSJim Jagielski                     else if( rAlgoName.equalsAscii( AES192_URL ) )
179*b1cdbd2cSJim Jagielski                     {
180*b1cdbd2cSJim Jagielski                     	 nCypherId = xml::crypto::CipherID::AES_CBC_W3C_PADDING;
181*b1cdbd2cSJim Jagielski                         OSL_ENSURE( !nDerivedKeySize || nDerivedKeySize == 24, "Unexpected derived key length!" );
182*b1cdbd2cSJim Jagielski                         nDerivedKeySize = 24;
183*b1cdbd2cSJim Jagielski                     }
184*b1cdbd2cSJim Jagielski                     else if( rAlgoName.equalsAscii( AES128_URL ) )
185*b1cdbd2cSJim Jagielski                     {
186*b1cdbd2cSJim Jagielski                     	 nCypherId = xml::crypto::CipherID::AES_CBC_W3C_PADDING;
187*b1cdbd2cSJim Jagielski                         OSL_ENSURE( !nDerivedKeySize || nDerivedKeySize == 16, "Unexpected derived key length!" );
188*b1cdbd2cSJim Jagielski                         nDerivedKeySize = 16;
189*b1cdbd2cSJim Jagielski                     }
190*b1cdbd2cSJim Jagielski                     else
191*b1cdbd2cSJim Jagielski                         bIgnoreEncryptData = true;
192*b1cdbd2cSJim Jagielski 
193*b1cdbd2cSJim Jagielski                     if ( !bIgnoreEncryptData )
194*b1cdbd2cSJim Jagielski                     {
195*b1cdbd2cSJim Jagielski                     	 setProperty( PKG_MNFST_ENCALG, nCypherId );
196*b1cdbd2cSJim Jagielski                         const OUString& sInitVector = aConvertedAttribs[sInitialisationVectorAttribute];
197*b1cdbd2cSJim Jagielski                         uno::Sequence < sal_Int8 > aDecodeBuffer;
198*b1cdbd2cSJim Jagielski                         ::sax::Converter::decodeBase64 ( aDecodeBuffer, sInitVector );
199*b1cdbd2cSJim Jagielski                     	 setProperty( PKG_MNFST_INIVECTOR, aDecodeBuffer );
200*b1cdbd2cSJim Jagielski                     }
201*b1cdbd2cSJim Jagielski                 }
202*b1cdbd2cSJim Jagielski             }
203*b1cdbd2cSJim Jagielski             else if ( aConvertedName.equalsAscii( ELEMENT_KEY_DERIVATION ) )
204*b1cdbd2cSJim Jagielski             {
205*b1cdbd2cSJim Jagielski                 if ( !bIgnoreEncryptData )
206*b1cdbd2cSJim Jagielski                 {
207*b1cdbd2cSJim Jagielski                     const OUString& rKeyDerivString = aConvertedAttribs[sKeyDerivationNameAttribute];
208*b1cdbd2cSJim Jagielski                     if ( rKeyDerivString.equalsAscii( PBKDF2_NAME ) || rKeyDerivString.equalsAscii( PBKDF2_URL ) )
209*b1cdbd2cSJim Jagielski                     {
210*b1cdbd2cSJim Jagielski                         const OUString& rSaltString = aConvertedAttribs[sSaltAttribute];
211*b1cdbd2cSJim Jagielski                         uno::Sequence < sal_Int8 > aDecodeBuffer;
212*b1cdbd2cSJim Jagielski                         ::sax::Converter::decodeBase64 ( aDecodeBuffer, rSaltString );
213*b1cdbd2cSJim Jagielski                     	 setProperty( PKG_MNFST_SALT, aDecodeBuffer );
214*b1cdbd2cSJim Jagielski 
215*b1cdbd2cSJim Jagielski                         const OUString& rIterationCount = aConvertedAttribs[sIterationCountAttribute];
216*b1cdbd2cSJim Jagielski                         setProperty( PKG_MNFST_ITERATION, rIterationCount.toInt32() );
217*b1cdbd2cSJim Jagielski 
218*b1cdbd2cSJim Jagielski                         const OUString& rKeySize = aConvertedAttribs[sKeySizeAttribute];
219*b1cdbd2cSJim Jagielski                         if ( rKeySize.getLength() )
220*b1cdbd2cSJim Jagielski                         {
221*b1cdbd2cSJim Jagielski                             const sal_Int32 nKey = rKeySize.toInt32();
222*b1cdbd2cSJim Jagielski                             OSL_ENSURE( !nDerivedKeySize || nKey == nDerivedKeySize , "Provided derived key length differs from the expected one!" );
223*b1cdbd2cSJim Jagielski                             nDerivedKeySize = nKey;
224*b1cdbd2cSJim Jagielski                         }
225*b1cdbd2cSJim Jagielski                         else if ( !nDerivedKeySize )
226*b1cdbd2cSJim Jagielski                             nDerivedKeySize = 16;
227*b1cdbd2cSJim Jagielski                         else if ( nDerivedKeySize != 16 )
228*b1cdbd2cSJim Jagielski                             OSL_ENSURE( sal_False, "Default derived key length differs from the expected one!" );
229*b1cdbd2cSJim Jagielski 
230*b1cdbd2cSJim Jagielski                         setProperty( PKG_MNFST_DERKEYSIZE, nDerivedKeySize );
231*b1cdbd2cSJim Jagielski                     }
232*b1cdbd2cSJim Jagielski                     else
233*b1cdbd2cSJim Jagielski                         bIgnoreEncryptData = true;
234*b1cdbd2cSJim Jagielski                 }
235*b1cdbd2cSJim Jagielski             }
236*b1cdbd2cSJim Jagielski             else if ( aConvertedName.equalsAscii( ELEMENT_START_KEY_GENERATION ) )
237*b1cdbd2cSJim Jagielski             {
238*b1cdbd2cSJim Jagielski                 const OUString& rSKeyAlg = aConvertedAttribs[sStartKeyAlgNameAttribute];
239*b1cdbd2cSJim Jagielski                 if ( rSKeyAlg.equalsAscii( SHA256_URL ) )
240*b1cdbd2cSJim Jagielski                 	setProperty( PKG_MNFST_STARTALG, xml::crypto::DigestID::SHA256 );
241*b1cdbd2cSJim Jagielski                 else if ( rSKeyAlg.equalsAscii( SHA1_NAME ) || rSKeyAlg.equalsAscii( SHA1_URL ) )
242*b1cdbd2cSJim Jagielski                 	setProperty( PKG_MNFST_STARTALG, xml::crypto::DigestID::SHA1 );
243*b1cdbd2cSJim Jagielski                 else
244*b1cdbd2cSJim Jagielski                     bIgnoreEncryptData = true;
245*b1cdbd2cSJim Jagielski             }
246*b1cdbd2cSJim Jagielski         }
247*b1cdbd2cSJim Jagielski 	}
248*b1cdbd2cSJim Jagielski }
249*b1cdbd2cSJim Jagielski 
250*b1cdbd2cSJim Jagielski // ---------------------------------------------------
endElement(const OUString & aName)251*b1cdbd2cSJim Jagielski void SAL_CALL ManifestImport::endElement( const OUString& aName )
252*b1cdbd2cSJim Jagielski 	throw( xml::sax::SAXException, uno::RuntimeException )
253*b1cdbd2cSJim Jagielski {
254*b1cdbd2cSJim Jagielski 	if( aStack.empty() )
255*b1cdbd2cSJim Jagielski 		return;
256*b1cdbd2cSJim Jagielski 
257*b1cdbd2cSJim Jagielski 	const OUString aConvertedName = ConvertName( aName );
258*b1cdbd2cSJim Jagielski 	if( !aStack.rbegin()->m_aConvertedName.equals( aConvertedName ) )
259*b1cdbd2cSJim Jagielski 		return;
260*b1cdbd2cSJim Jagielski 
261*b1cdbd2cSJim Jagielski 	aStack.pop_back();
262*b1cdbd2cSJim Jagielski 
263*b1cdbd2cSJim Jagielski 	if( !aConvertedName.equalsAscii( ELEMENT_FILE_ENTRY ) )
264*b1cdbd2cSJim Jagielski 		return;
265*b1cdbd2cSJim Jagielski 
266*b1cdbd2cSJim Jagielski 	// create the property sequence
267*b1cdbd2cSJim Jagielski 	// Put full-path property first for MBA
268*b1cdbd2cSJim Jagielski 	// TODO: get rid of fullpath-first requirement
269*b1cdbd2cSJim Jagielski 	const bool bHasFullPath = maValues[PKG_MNFST_FULLPATH].hasValue();
270*b1cdbd2cSJim Jagielski 	OSL_ENSURE( bHasFullPath, "Full path missing in manifest" );
271*b1cdbd2cSJim Jagielski 
272*b1cdbd2cSJim Jagielski 	int nNumProperty = bHasFullPath ? 1 : 0;
273*b1cdbd2cSJim Jagielski 	PropertyValue aProperties[ PKG_SIZE_ENCR_MNFST ];
274*b1cdbd2cSJim Jagielski 	for( int i = 0; i < PKG_SIZE_ENCR_MNFST; ++i)
275*b1cdbd2cSJim Jagielski 	{
276*b1cdbd2cSJim Jagielski 		if(! maValues[i].hasValue() )
277*b1cdbd2cSJim Jagielski 			continue;
278*b1cdbd2cSJim Jagielski 
279*b1cdbd2cSJim Jagielski 		const int nDest = (i == PKG_MNFST_FULLPATH) ? 0 : nNumProperty++;
280*b1cdbd2cSJim Jagielski 		PropertyValue& rProp = aProperties[ nDest ];
281*b1cdbd2cSJim Jagielski 		rProp.Name = OUString::createFromAscii( getMnfstPropName(i));
282*b1cdbd2cSJim Jagielski 		rProp.Value = maValues[i];
283*b1cdbd2cSJim Jagielski 		maValues[i].clear();
284*b1cdbd2cSJim Jagielski 	}
285*b1cdbd2cSJim Jagielski 
286*b1cdbd2cSJim Jagielski 	// add the property sequence to the vector of manifests
287*b1cdbd2cSJim Jagielski 	rManVector.push_back ( PropertyValues( aProperties, nNumProperty ) );
288*b1cdbd2cSJim Jagielski 	bIgnoreEncryptData = false;
289*b1cdbd2cSJim Jagielski }
290*b1cdbd2cSJim Jagielski 
291*b1cdbd2cSJim Jagielski // ---------------------------------------------------
characters(const OUString &)292*b1cdbd2cSJim Jagielski void SAL_CALL ManifestImport::characters( const OUString& /*aChars*/ )
293*b1cdbd2cSJim Jagielski 		throw( xml::sax::SAXException, uno::RuntimeException )
294*b1cdbd2cSJim Jagielski {
295*b1cdbd2cSJim Jagielski }
296*b1cdbd2cSJim Jagielski 
297*b1cdbd2cSJim Jagielski // ---------------------------------------------------
ignorableWhitespace(const OUString &)298*b1cdbd2cSJim Jagielski void SAL_CALL ManifestImport::ignorableWhitespace( const OUString& /*aWhitespaces*/ )
299*b1cdbd2cSJim Jagielski 		throw( xml::sax::SAXException, uno::RuntimeException )
300*b1cdbd2cSJim Jagielski {
301*b1cdbd2cSJim Jagielski }
302*b1cdbd2cSJim Jagielski 
303*b1cdbd2cSJim Jagielski // ---------------------------------------------------
processingInstruction(const OUString &,const OUString &)304*b1cdbd2cSJim Jagielski void SAL_CALL ManifestImport::processingInstruction( const OUString& /*aTarget*/, const OUString& /*aData*/ )
305*b1cdbd2cSJim Jagielski 		throw( xml::sax::SAXException, uno::RuntimeException )
306*b1cdbd2cSJim Jagielski {
307*b1cdbd2cSJim Jagielski }
308*b1cdbd2cSJim Jagielski 
309*b1cdbd2cSJim Jagielski // ---------------------------------------------------
setDocumentLocator(const uno::Reference<xml::sax::XLocator> &)310*b1cdbd2cSJim Jagielski void SAL_CALL ManifestImport::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& /*xLocator*/ )
311*b1cdbd2cSJim Jagielski 		throw( xml::sax::SAXException, uno::RuntimeException )
312*b1cdbd2cSJim Jagielski {
313*b1cdbd2cSJim Jagielski }
314*b1cdbd2cSJim Jagielski 
315*b1cdbd2cSJim Jagielski // ---------------------------------------------------
PushNameAndNamespaces(const::rtl::OUString & aName,const uno::Reference<xml::sax::XAttributeList> & xAttribs,StringHashMap & o_aConvertedAttribs)316*b1cdbd2cSJim Jagielski ::rtl::OUString ManifestImport::PushNameAndNamespaces( const ::rtl::OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs, StringHashMap& o_aConvertedAttribs )
317*b1cdbd2cSJim Jagielski {
318*b1cdbd2cSJim Jagielski     StringHashMap aNamespaces;
319*b1cdbd2cSJim Jagielski     ::std::vector< ::std::pair< ::rtl::OUString, ::rtl::OUString > > aAttribsStrs;
320*b1cdbd2cSJim Jagielski 
321*b1cdbd2cSJim Jagielski     if ( xAttribs.is() )
322*b1cdbd2cSJim Jagielski     {
323*b1cdbd2cSJim Jagielski 	    sal_Int16 nAttrCount = xAttribs.is() ? xAttribs->getLength() : 0;
324*b1cdbd2cSJim Jagielski         aAttribsStrs.reserve( nAttrCount );
325*b1cdbd2cSJim Jagielski 
326*b1cdbd2cSJim Jagielski 	    for( sal_Int16 nInd = 0; nInd < nAttrCount; nInd++ )
327*b1cdbd2cSJim Jagielski 	    {
328*b1cdbd2cSJim Jagielski 		    ::rtl::OUString aAttrName = xAttribs->getNameByIndex( nInd );
329*b1cdbd2cSJim Jagielski             ::rtl::OUString aAttrValue = xAttribs->getValueByIndex( nInd );
330*b1cdbd2cSJim Jagielski             if ( aAttrName.getLength() >= 5
331*b1cdbd2cSJim Jagielski               && aAttrName.compareToAscii( "xmlns", 5 ) == 0
332*b1cdbd2cSJim Jagielski               && ( aAttrName.getLength() == 5 || aAttrName.getStr()[5] == ( sal_Unicode )':' ) )
333*b1cdbd2cSJim Jagielski             {
334*b1cdbd2cSJim Jagielski                 // this is a namespace declaration
335*b1cdbd2cSJim Jagielski                 ::rtl::OUString aNsName( ( aAttrName.getLength() == 5 ) ? ::rtl::OUString() : aAttrName.copy( 6 ) );
336*b1cdbd2cSJim Jagielski                 aNamespaces[aNsName] = aAttrValue;
337*b1cdbd2cSJim Jagielski             }
338*b1cdbd2cSJim Jagielski             else
339*b1cdbd2cSJim Jagielski             {
340*b1cdbd2cSJim Jagielski                 // this is no namespace declaration
341*b1cdbd2cSJim Jagielski                 aAttribsStrs.push_back( pair< ::rtl::OUString, ::rtl::OUString >( aAttrName, aAttrValue ) );
342*b1cdbd2cSJim Jagielski             }
343*b1cdbd2cSJim Jagielski         }
344*b1cdbd2cSJim Jagielski     }
345*b1cdbd2cSJim Jagielski 
346*b1cdbd2cSJim Jagielski     ::rtl::OUString aConvertedName = ConvertNameWithNamespace( aName, aNamespaces );
347*b1cdbd2cSJim Jagielski     if ( !aConvertedName.getLength() )
348*b1cdbd2cSJim Jagielski         aConvertedName = ConvertName( aName );
349*b1cdbd2cSJim Jagielski 
350*b1cdbd2cSJim Jagielski     aStack.push_back( ManifestScopeEntry( aConvertedName, aNamespaces ) );
351*b1cdbd2cSJim Jagielski 
352*b1cdbd2cSJim Jagielski     for ( sal_uInt16 nInd = 0; nInd < aAttribsStrs.size(); nInd++ )
353*b1cdbd2cSJim Jagielski     {
354*b1cdbd2cSJim Jagielski         // convert the attribute names on filling
355*b1cdbd2cSJim Jagielski         o_aConvertedAttribs[ConvertName( aAttribsStrs[nInd].first )] = aAttribsStrs[nInd].second;
356*b1cdbd2cSJim Jagielski     }
357*b1cdbd2cSJim Jagielski 
358*b1cdbd2cSJim Jagielski     return aConvertedName;
359*b1cdbd2cSJim Jagielski }
360*b1cdbd2cSJim Jagielski 
361*b1cdbd2cSJim Jagielski 
362*b1cdbd2cSJim Jagielski // ---------------------------------------------------
ConvertNameWithNamespace(const::rtl::OUString & aName,const StringHashMap & aNamespaces)363*b1cdbd2cSJim Jagielski ::rtl::OUString ManifestImport::ConvertNameWithNamespace( const ::rtl::OUString& aName, const StringHashMap& aNamespaces )
364*b1cdbd2cSJim Jagielski {
365*b1cdbd2cSJim Jagielski     ::rtl::OUString aNsAlias;
366*b1cdbd2cSJim Jagielski     ::rtl::OUString aPureName = aName;
367*b1cdbd2cSJim Jagielski 
368*b1cdbd2cSJim Jagielski     sal_Int32 nInd = aName.indexOf( ( sal_Unicode )':' );
369*b1cdbd2cSJim Jagielski     if ( nInd != -1 && nInd < aName.getLength() )
370*b1cdbd2cSJim Jagielski     {
371*b1cdbd2cSJim Jagielski         aNsAlias = aName.copy( 0, nInd );
372*b1cdbd2cSJim Jagielski         aPureName = aName.copy( nInd + 1 );
373*b1cdbd2cSJim Jagielski     }
374*b1cdbd2cSJim Jagielski 
375*b1cdbd2cSJim Jagielski     ::rtl::OUString aResult;
376*b1cdbd2cSJim Jagielski 
377*b1cdbd2cSJim Jagielski     StringHashMap::const_iterator aIter = aNamespaces.find( aNsAlias );
378*b1cdbd2cSJim Jagielski     if ( aIter != aNamespaces.end()
379*b1cdbd2cSJim Jagielski       && ( aIter->second.equalsAscii( MANIFEST_NAMESPACE )
380*b1cdbd2cSJim Jagielski         || aIter->second.equalsAscii( MANIFEST_OASIS_NAMESPACE ) ) )
381*b1cdbd2cSJim Jagielski     {
382*b1cdbd2cSJim Jagielski         // no check for manifest.xml consistency currently since the old versions have supported inconsistent documents as well
383*b1cdbd2cSJim Jagielski         aResult = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MANIFEST_NSPREFIX ) );
384*b1cdbd2cSJim Jagielski         aResult += aPureName;
385*b1cdbd2cSJim Jagielski     }
386*b1cdbd2cSJim Jagielski 
387*b1cdbd2cSJim Jagielski     return aResult;
388*b1cdbd2cSJim Jagielski }
389*b1cdbd2cSJim Jagielski 
390*b1cdbd2cSJim Jagielski // ---------------------------------------------------
ConvertName(const::rtl::OUString & aName)391*b1cdbd2cSJim Jagielski ::rtl::OUString ManifestImport::ConvertName( const ::rtl::OUString& aName )
392*b1cdbd2cSJim Jagielski {
393*b1cdbd2cSJim Jagielski     ::rtl::OUString aConvertedName;
394*b1cdbd2cSJim Jagielski     for ( ManifestStack::reverse_iterator aIter = aStack.rbegin(); !aConvertedName.getLength() && aIter != aStack.rend(); aIter++ )
395*b1cdbd2cSJim Jagielski     {
396*b1cdbd2cSJim Jagielski         if ( !aIter->m_aNamespaces.empty() )
397*b1cdbd2cSJim Jagielski             aConvertedName = ConvertNameWithNamespace( aName, aIter->m_aNamespaces );
398*b1cdbd2cSJim Jagielski     }
399*b1cdbd2cSJim Jagielski 
400*b1cdbd2cSJim Jagielski     if ( !aConvertedName.getLength() )
401*b1cdbd2cSJim Jagielski         aConvertedName = aName;
402*b1cdbd2cSJim Jagielski 
403*b1cdbd2cSJim Jagielski     return aConvertedName;
404*b1cdbd2cSJim Jagielski }
405*b1cdbd2cSJim Jagielski 
406