Version 6.1.4.1, tag libreoffice-6.1.4.1
[LibreOffice.git] / package / source / manifest / ManifestImport.cxx
blobcd0034a2e1df7f900b8a8e8b314534b090309ef1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "ManifestImport.hxx"
21 #include "ManifestDefines.hxx"
22 #include <sax/tools/converter.hxx>
23 #include <osl/diagnose.h>
24 #include <com/sun/star/xml/sax/XAttributeList.hpp>
25 #include <com/sun/star/xml/crypto/DigestID.hpp>
26 #include <com/sun/star/xml/crypto/CipherID.hpp>
27 #include <com/sun/star/beans/PropertyValue.hpp>
28 #include <comphelper/base64.hxx>
29 #include <comphelper/sequence.hxx>
31 using namespace com::sun::star::uno;
32 using namespace com::sun::star::beans;
33 using namespace com::sun::star;
34 using namespace std;
36 ManifestImport::ManifestImport( vector < Sequence < PropertyValue > > & rNewManVector )
37 : bIgnoreEncryptData ( false )
38 , bPgpEncryption ( false )
39 , nDerivedKeySize( 0 )
40 , rManVector ( rNewManVector )
42 , sFileEntryElement ( ELEMENT_FILE_ENTRY )
43 , sEncryptionDataElement( ELEMENT_ENCRYPTION_DATA )
44 , sAlgorithmElement ( ELEMENT_ALGORITHM )
45 , sStartKeyAlgElement ( ELEMENT_START_KEY_GENERATION )
46 , sKeyDerivationElement( ELEMENT_KEY_DERIVATION )
48 , sMediaTypeAttribute ( ATTRIBUTE_MEDIA_TYPE )
49 , sVersionAttribute ( ATTRIBUTE_VERSION )
50 , sFullPathAttribute ( ATTRIBUTE_FULL_PATH )
51 , sSizeAttribute ( ATTRIBUTE_SIZE )
52 , sSaltAttribute ( ATTRIBUTE_SALT )
53 , sInitialisationVectorAttribute ( ATTRIBUTE_INITIALISATION_VECTOR )
54 , sIterationCountAttribute ( ATTRIBUTE_ITERATION_COUNT )
55 , sKeySizeAttribute ( ATTRIBUTE_KEY_SIZE )
56 , sAlgorithmNameAttribute ( ATTRIBUTE_ALGORITHM_NAME )
57 , sStartKeyAlgNameAttribute ( ATTRIBUTE_START_KEY_GENERATION_NAME )
58 , sKeyDerivationNameAttribute ( ATTRIBUTE_KEY_DERIVATION_NAME )
59 , sChecksumAttribute ( ATTRIBUTE_CHECKSUM )
60 , sChecksumTypeAttribute ( ATTRIBUTE_CHECKSUM_TYPE )
62 , sKeyInfoElement ( ELEMENT_ENCRYPTED_KEYINFO )
63 , sManifestKeyInfoElement ( ELEMENT_MANIFEST_KEYINFO )
64 , sEncryptedKeyElement ( ELEMENT_ENCRYPTEDKEY )
65 , sEncryptionMethodElement ( ELEMENT_ENCRYPTIONMETHOD )
66 , sPgpDataElement ( ELEMENT_PGPDATA )
67 , sPgpKeyIDElement ( ELEMENT_PGPKEYID )
68 , sPGPKeyPacketElement ( ELEMENT_PGPKEYPACKET )
69 , sAlgorithmAttribute ( ATTRIBUTE_ALGORITHM )
70 , sCipherDataElement ( ELEMENT_CIPHERDATA )
71 , sCipherValueElement ( ELEMENT_CIPHERVALUE )
73 , sManifestKeyInfoElement13 ( ELEMENT_MANIFEST13_KEYINFO )
74 , sEncryptedKeyElement13 ( ELEMENT_ENCRYPTEDKEY13 )
75 , sEncryptionMethodElement13 ( ELEMENT_ENCRYPTIONMETHOD13 )
76 , sPgpDataElement13 ( ELEMENT_PGPDATA13 )
77 , sPgpKeyIDElement13 ( ELEMENT_PGPKEYID13 )
78 , sPGPKeyPacketElement13 ( ELEMENT_PGPKEYPACKET13 )
79 , sAlgorithmAttribute13 ( ATTRIBUTE_ALGORITHM13 )
80 , sCipherDataElement13 ( ELEMENT_CIPHERDATA13 )
81 , sCipherValueElement13 ( ELEMENT_CIPHERVALUE13 )
83 , sFullPathProperty ( "FullPath" )
84 , sMediaTypeProperty ( "MediaType" )
85 , sVersionProperty ( "Version" )
86 , sIterationCountProperty ( "IterationCount" )
87 , sDerivedKeySizeProperty ( "DerivedKeySize" )
88 , sSaltProperty ( "Salt" )
89 , sInitialisationVectorProperty ( "InitialisationVector" )
90 , sSizeProperty ( "Size" )
91 , sDigestProperty ( "Digest" )
92 , sEncryptionAlgProperty ( "EncryptionAlgorithm" )
93 , sStartKeyAlgProperty ( "StartKeyAlgorithm" )
94 , sDigestAlgProperty ( "DigestAlgorithm" )
96 , sSHA256_URL_ODF12 ( SHA256_URL_ODF12 )
97 , sSHA256_URL ( SHA256_URL )
98 , sSHA1_Name ( SHA1_NAME )
99 , sSHA1_URL ( SHA1_URL )
101 , sSHA256_1k_URL ( SHA256_1K_URL )
102 , sSHA1_1k_Name ( SHA1_1K_NAME )
103 , sSHA1_1k_URL ( SHA1_1K_URL )
105 , sBlowfish_Name ( BLOWFISH_NAME )
106 , sBlowfish_URL ( BLOWFISH_URL )
107 , sAES128_URL ( AES128_URL )
108 , sAES192_URL ( AES192_URL )
109 , sAES256_URL ( AES256_URL )
111 , sPBKDF2_Name ( PBKDF2_NAME )
112 , sPBKDF2_URL ( PBKDF2_URL )
114 aStack.reserve( 10 );
117 ManifestImport::~ManifestImport()
121 void SAL_CALL ManifestImport::startDocument( )
125 void SAL_CALL ManifestImport::endDocument( )
129 void ManifestImport::doFileEntry(StringHashMap &rConvertedAttribs)
131 aSequence.resize(PKG_SIZE_ENCR_MNFST);
133 aSequence[PKG_MNFST_FULLPATH].Name = sFullPathProperty;
134 aSequence[PKG_MNFST_FULLPATH].Value <<= rConvertedAttribs[sFullPathAttribute];
135 aSequence[PKG_MNFST_MEDIATYPE].Name = sMediaTypeProperty;
136 aSequence[PKG_MNFST_MEDIATYPE].Value <<= rConvertedAttribs[sMediaTypeAttribute];
138 OUString sVersion = rConvertedAttribs[sVersionAttribute];
139 if ( sVersion.getLength() ) {
140 aSequence[PKG_MNFST_VERSION].Name = sVersionProperty;
141 aSequence[PKG_MNFST_VERSION].Value <<= sVersion;
144 OUString sSize = rConvertedAttribs[sSizeAttribute];
145 if ( sSize.getLength() ) {
146 sal_Int64 nSize = sSize.toInt64();
147 aSequence[PKG_MNFST_UCOMPSIZE].Name = sSizeProperty;
148 aSequence[PKG_MNFST_UCOMPSIZE].Value <<= nSize;
152 void ManifestImport::doKeyInfoEntry(StringHashMap &)
156 void ManifestImport::doEncryptedKey(StringHashMap &)
158 aKeyInfoSequence.clear();
159 aKeyInfoSequence.resize(3);
162 void ManifestImport::doEncryptionMethod(StringHashMap &rConvertedAttribs,
163 const OUString& rAlgoAttrName)
165 OUString aString = rConvertedAttribs[rAlgoAttrName];
166 if ( aKeyInfoSequence.size() != 3
167 || aString != "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" )
169 bIgnoreEncryptData = true;
173 void ManifestImport::doEncryptedKeyInfo(StringHashMap &)
177 void ManifestImport::doEncryptedCipherData(StringHashMap &)
181 void ManifestImport::doEncryptedPgpData(StringHashMap &)
185 void ManifestImport::doEncryptedCipherValue()
187 if ( aKeyInfoSequence.size() == 3 )
189 aKeyInfoSequence[2].Name = "CipherValue";
190 uno::Sequence < sal_Int8 > aDecodeBuffer;
191 ::comphelper::Base64::decode(aDecodeBuffer, aCurrentCharacters);
192 aKeyInfoSequence[2].Value <<= aDecodeBuffer;
193 aCurrentCharacters = ""; // consumed
195 else
196 bIgnoreEncryptData = true;
199 void ManifestImport::doEncryptedKeyId()
201 if ( aKeyInfoSequence.size() == 3 )
203 aKeyInfoSequence[0].Name = "KeyId";
204 uno::Sequence < sal_Int8 > aDecodeBuffer;
205 ::comphelper::Base64::decode(aDecodeBuffer, aCurrentCharacters);
206 aKeyInfoSequence[0].Value <<= aDecodeBuffer;
207 aCurrentCharacters = ""; // consumed
209 else
210 bIgnoreEncryptData = true;
213 void ManifestImport::doEncryptedKeyPacket()
215 if ( aKeyInfoSequence.size() == 3 )
217 aKeyInfoSequence[1].Name = "KeyPacket";
218 uno::Sequence < sal_Int8 > aDecodeBuffer;
219 ::comphelper::Base64::decode(aDecodeBuffer, aCurrentCharacters);
220 aKeyInfoSequence[1].Value <<= aDecodeBuffer;
221 aCurrentCharacters = ""; // consumed
223 else
224 bIgnoreEncryptData = true;
227 void ManifestImport::doEncryptionData(StringHashMap &rConvertedAttribs)
229 // If this element exists, then this stream is encrypted and we need
230 // to import the initialisation vector, salt and iteration count used
231 nDerivedKeySize = 0;
232 OUString aString = rConvertedAttribs[sChecksumTypeAttribute];
233 if ( !bIgnoreEncryptData ) {
234 if ( aString == sSHA1_1k_Name || aString == sSHA1_1k_URL ) {
235 aSequence[PKG_MNFST_DIGESTALG].Name = sDigestAlgProperty;
236 aSequence[PKG_MNFST_DIGESTALG].Value <<= xml::crypto::DigestID::SHA1_1K;
237 } else if ( aString == sSHA256_1k_URL ) {
238 aSequence[PKG_MNFST_DIGESTALG].Name = sDigestAlgProperty;
239 aSequence[PKG_MNFST_DIGESTALG].Value <<= xml::crypto::DigestID::SHA256_1K;
240 } else
241 bIgnoreEncryptData = true;
243 if ( !bIgnoreEncryptData ) {
244 aString = rConvertedAttribs[sChecksumAttribute];
245 uno::Sequence < sal_Int8 > aDecodeBuffer;
246 ::comphelper::Base64::decode(aDecodeBuffer, aString);
247 aSequence[PKG_MNFST_DIGEST].Name = sDigestProperty;
248 aSequence[PKG_MNFST_DIGEST].Value <<= aDecodeBuffer;
253 void ManifestImport::doAlgorithm(StringHashMap &rConvertedAttribs)
255 if ( !bIgnoreEncryptData ) {
256 OUString aString = rConvertedAttribs[sAlgorithmNameAttribute];
257 if ( aString == sBlowfish_Name || aString == sBlowfish_URL ) {
258 aSequence[PKG_MNFST_ENCALG].Name = sEncryptionAlgProperty;
259 aSequence[PKG_MNFST_ENCALG].Value <<= xml::crypto::CipherID::BLOWFISH_CFB_8;
260 } else if ( aString == sAES256_URL ) {
261 aSequence[PKG_MNFST_ENCALG].Name = sEncryptionAlgProperty;
262 aSequence[PKG_MNFST_ENCALG].Value <<= xml::crypto::CipherID::AES_CBC_W3C_PADDING;
263 OSL_ENSURE( !nDerivedKeySize || nDerivedKeySize == 32, "Unexpected derived key length!" );
264 nDerivedKeySize = 32;
265 } else if ( aString == sAES192_URL ) {
266 aSequence[PKG_MNFST_ENCALG].Name = sEncryptionAlgProperty;
267 aSequence[PKG_MNFST_ENCALG].Value <<= xml::crypto::CipherID::AES_CBC_W3C_PADDING;
268 OSL_ENSURE( !nDerivedKeySize || nDerivedKeySize == 24, "Unexpected derived key length!" );
269 nDerivedKeySize = 24;
270 } else if ( aString == sAES128_URL ) {
271 aSequence[PKG_MNFST_ENCALG].Name = sEncryptionAlgProperty;
272 aSequence[PKG_MNFST_ENCALG].Value <<= xml::crypto::CipherID::AES_CBC_W3C_PADDING;
273 OSL_ENSURE( !nDerivedKeySize || nDerivedKeySize == 16, "Unexpected derived key length!" );
274 nDerivedKeySize = 16;
275 } else
276 bIgnoreEncryptData = true;
278 if ( !bIgnoreEncryptData ) {
279 aString = rConvertedAttribs[sInitialisationVectorAttribute];
280 uno::Sequence < sal_Int8 > aDecodeBuffer;
281 ::comphelper::Base64::decode(aDecodeBuffer, aString);
282 aSequence[PKG_MNFST_INIVECTOR].Name = sInitialisationVectorProperty;
283 aSequence[PKG_MNFST_INIVECTOR].Value <<= aDecodeBuffer;
288 void ManifestImport::doKeyDerivation(StringHashMap &rConvertedAttribs)
290 if ( !bIgnoreEncryptData ) {
291 OUString aString = rConvertedAttribs[sKeyDerivationNameAttribute];
292 if ( aString == sPBKDF2_Name || aString == sPBKDF2_URL ) {
293 aString = rConvertedAttribs[sSaltAttribute];
294 uno::Sequence < sal_Int8 > aDecodeBuffer;
295 ::comphelper::Base64::decode(aDecodeBuffer, aString);
296 aSequence[PKG_MNFST_SALT].Name = sSaltProperty;
297 aSequence[PKG_MNFST_SALT].Value <<= aDecodeBuffer;
299 aString = rConvertedAttribs[sIterationCountAttribute];
300 aSequence[PKG_MNFST_ITERATION].Name = sIterationCountProperty;
301 aSequence[PKG_MNFST_ITERATION].Value <<= aString.toInt32();
303 aString = rConvertedAttribs[sKeySizeAttribute];
304 if ( aString.getLength() ) {
305 sal_Int32 nKey = aString.toInt32();
306 OSL_ENSURE( !nDerivedKeySize || nKey == nDerivedKeySize , "Provided derived key length differs from the expected one!" );
307 nDerivedKeySize = nKey;
308 } else if ( !nDerivedKeySize )
309 nDerivedKeySize = 16;
310 else if ( nDerivedKeySize != 16 )
311 OSL_ENSURE( false, "Default derived key length differs from the expected one!" );
313 aSequence[PKG_MNFST_DERKEYSIZE].Name = sDerivedKeySizeProperty;
314 aSequence[PKG_MNFST_DERKEYSIZE].Value <<= nDerivedKeySize;
315 } else if ( bPgpEncryption ) {
316 if ( aString != "PGP" )
317 bIgnoreEncryptData = true;
318 } else
319 bIgnoreEncryptData = true;
323 void ManifestImport::doStartKeyAlg(StringHashMap &rConvertedAttribs)
325 OUString aString = rConvertedAttribs[sStartKeyAlgNameAttribute];
326 if (aString == sSHA256_URL || aString == sSHA256_URL_ODF12) {
327 aSequence[PKG_MNFST_STARTALG].Name = sStartKeyAlgProperty;
328 aSequence[PKG_MNFST_STARTALG].Value <<= xml::crypto::DigestID::SHA256;
329 } else if ( aString == sSHA1_Name || aString == sSHA1_URL ) {
330 aSequence[PKG_MNFST_STARTALG].Name = sStartKeyAlgProperty;
331 aSequence[PKG_MNFST_STARTALG].Value <<= xml::crypto::DigestID::SHA1;
332 } else
333 bIgnoreEncryptData = true;
336 void SAL_CALL ManifestImport::startElement( const OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs )
338 StringHashMap aConvertedAttribs;
339 OUString aConvertedName = PushNameAndNamespaces( aName, xAttribs, aConvertedAttribs );
341 size_t nLevel = aStack.size();
343 assert(nLevel >= 1);
345 switch (nLevel) {
346 case 1: {
347 if (aConvertedName != ELEMENT_MANIFEST) //manifest:manifest
348 aStack.back().m_bValid = false;
349 break;
351 case 2: {
352 if (aConvertedName == sFileEntryElement) //manifest:file-entry
353 doFileEntry(aConvertedAttribs);
354 else if (aConvertedName == sManifestKeyInfoElement) //loext:keyinfo
355 doKeyInfoEntry(aConvertedAttribs);
356 else if (aConvertedName == sManifestKeyInfoElement13) //manifest:keyinfo
357 doKeyInfoEntry(aConvertedAttribs);
358 else
359 aStack.back().m_bValid = false;
360 break;
362 case 3: {
363 ManifestStack::reverse_iterator aIter = aStack.rbegin();
364 ++aIter;
366 if (!aIter->m_bValid)
367 aStack.back().m_bValid = false;
368 else if (aConvertedName == sEncryptionDataElement) //manifest:encryption-data
369 doEncryptionData(aConvertedAttribs);
370 else if (aConvertedName == sEncryptedKeyElement) //loext:encrypted-key
371 doEncryptedKey(aConvertedAttribs);
372 else if (aConvertedName == sEncryptedKeyElement13) //manifest:encrypted-key
373 doEncryptedKey(aConvertedAttribs);
374 else
375 aStack.back().m_bValid = false;
376 break;
378 case 4: {
379 ManifestStack::reverse_iterator aIter = aStack.rbegin();
380 ++aIter;
382 if (!aIter->m_bValid)
383 aStack.back().m_bValid = false;
384 else if (aConvertedName == sAlgorithmElement) //manifest:algorithm,
385 doAlgorithm(aConvertedAttribs);
386 else if (aConvertedName == sKeyDerivationElement) //manifest:key-derivation,
387 doKeyDerivation(aConvertedAttribs);
388 else if (aConvertedName == sStartKeyAlgElement) //manifest:start-key-generation
389 doStartKeyAlg(aConvertedAttribs);
390 else if (aConvertedName == sEncryptionMethodElement) //loext:encryption-method
391 doEncryptionMethod(aConvertedAttribs, sAlgorithmAttribute);
392 else if (aConvertedName == sEncryptionMethodElement13) //manifest:encryption-method
393 doEncryptionMethod(aConvertedAttribs, sAlgorithmAttribute13);
394 else if (aConvertedName == sKeyInfoElement) //loext:KeyInfo
395 doEncryptedKeyInfo(aConvertedAttribs);
396 else if (aConvertedName == sCipherDataElement) //loext:CipherData
397 doEncryptedCipherData(aConvertedAttribs);
398 else if (aConvertedName == sCipherDataElement13) //manifest:CipherData
399 doEncryptedCipherData(aConvertedAttribs);
400 else if (aConvertedName == sPgpDataElement13) //manifest:PGPData
401 doEncryptedPgpData(aConvertedAttribs);
402 else
403 aStack.back().m_bValid = false;
404 break;
406 case 5: {
407 ManifestStack::reverse_iterator aIter = aStack.rbegin();
408 ++aIter;
410 if (!aIter->m_bValid)
411 aStack.back().m_bValid = false;
412 else if (aConvertedName == sPgpDataElement) //loext:PGPData
413 doEncryptedPgpData(aConvertedAttribs);
414 else if (aConvertedName == sCipherValueElement) //loext:CipherValue
415 // ciphervalue action happens on endElement
416 aCurrentCharacters = "";
417 else if (aConvertedName == sCipherValueElement13) //manifest:CipherValue
418 // ciphervalue action happens on endElement
419 aCurrentCharacters = "";
420 else if (aConvertedName == sPgpKeyIDElement13) //manifest:PGPKeyID
421 // ciphervalue action happens on endElement
422 aCurrentCharacters = "";
423 else if (aConvertedName == sPGPKeyPacketElement13) //manifest:PGPKeyPacket
424 // ciphervalue action happens on endElement
425 aCurrentCharacters = "";
426 else
427 aStack.back().m_bValid = false;
428 break;
430 case 6: {
431 ManifestStack::reverse_iterator aIter = aStack.rbegin();
432 ++aIter;
434 if (!aIter->m_bValid)
435 aStack.back().m_bValid = false;
436 else if (aConvertedName == sPgpKeyIDElement) //loext:PGPKeyID
437 // ciphervalue action happens on endElement
438 aCurrentCharacters = "";
439 else if (aConvertedName == sPGPKeyPacketElement) //loext:PGPKeyPacket
440 // ciphervalue action happens on endElement
441 aCurrentCharacters = "";
442 else
443 aStack.back().m_bValid = false;
444 break;
446 default:
447 aStack.back().m_bValid = false;
448 break;
452 namespace
454 bool isEmpty(const css::beans::PropertyValue &rProp)
456 return rProp.Name.isEmpty();
460 void SAL_CALL ManifestImport::endElement( const OUString& aName )
462 size_t nLevel = aStack.size();
464 assert(nLevel >= 1);
466 OUString aConvertedName = ConvertName( aName );
467 if ( !aStack.empty() && aStack.rbegin()->m_aConvertedName == aConvertedName ) {
468 if ( aConvertedName == sFileEntryElement && aStack.back().m_bValid ) {
469 // root folder gets KeyInfo entry if any, for PGP encryption
470 if (!bIgnoreEncryptData && !aKeys.empty() && aSequence[PKG_MNFST_FULLPATH].Value.get<OUString>() == "/" )
472 aSequence[PKG_SIZE_NOENCR_MNFST].Name = "KeyInfo";
473 aSequence[PKG_SIZE_NOENCR_MNFST].Value <<= comphelper::containerToSequence(aKeys);
475 css::beans::PropertyValue aEmpty;
476 aSequence.erase(std::remove_if(aSequence.begin(), aSequence.end(),
477 isEmpty), aSequence.end());
479 bIgnoreEncryptData = false;
480 rManVector.push_back ( comphelper::containerToSequence(aSequence) );
482 aSequence.clear();
484 else if ( (aConvertedName == sEncryptedKeyElement
485 || aConvertedName == sEncryptedKeyElement13)
486 && aStack.back().m_bValid ) {
487 if ( !bIgnoreEncryptData )
489 aKeys.push_back( comphelper::containerToSequence(aKeyInfoSequence) );
490 bPgpEncryption = true;
492 aKeyInfoSequence.clear();
495 // end element handling for elements with cdata
496 switch (nLevel) {
497 case 5: {
498 if (aConvertedName == sCipherValueElement) //loext:CipherValue
499 doEncryptedCipherValue();
500 else if (aConvertedName == sCipherValueElement13) //manifest:CipherValue
501 doEncryptedCipherValue();
502 else if (aConvertedName == sPgpKeyIDElement13) //manifest:PGPKeyID
503 doEncryptedKeyId();
504 else if (aConvertedName == sPGPKeyPacketElement13) //manifest:PGPKeyPacket
505 doEncryptedKeyPacket();
506 else
507 aStack.back().m_bValid = false;
508 break;
510 case 6: {
511 if (aConvertedName == sPgpKeyIDElement) //loext:PGPKeyID
512 doEncryptedKeyId();
513 else if (aConvertedName == sPGPKeyPacketElement) //loext:PGPKeyPacket
514 doEncryptedKeyPacket();
515 else
516 aStack.back().m_bValid = false;
517 break;
521 aStack.pop_back();
522 return;
526 void SAL_CALL ManifestImport::characters( const OUString& aChars )
528 aCurrentCharacters += aChars;
531 void SAL_CALL ManifestImport::ignorableWhitespace( const OUString& /*aWhitespaces*/ )
535 void SAL_CALL ManifestImport::processingInstruction( const OUString& /*aTarget*/, const OUString& /*aData*/ )
539 void SAL_CALL ManifestImport::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& /*xLocator*/ )
543 OUString ManifestImport::PushNameAndNamespaces( const OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs, StringHashMap& o_aConvertedAttribs )
545 StringHashMap aNamespaces;
546 ::std::vector< ::std::pair< OUString, OUString > > aAttribsStrs;
548 if ( xAttribs.is() ) {
549 sal_Int16 nAttrCount = xAttribs.is() ? xAttribs->getLength() : 0;
550 aAttribsStrs.reserve( nAttrCount );
552 for( sal_Int16 nInd = 0; nInd < nAttrCount; nInd++ ) {
553 OUString aAttrName = xAttribs->getNameByIndex( nInd );
554 OUString aAttrValue = xAttribs->getValueByIndex( nInd );
555 if ( aAttrName.getLength() >= 5
556 && aAttrName.startsWith("xmlns")
557 && ( aAttrName.getLength() == 5 || aAttrName[5] == ':' ) ) {
558 // this is a namespace declaration
559 OUString aNsName( ( aAttrName.getLength() == 5 ) ? OUString() : aAttrName.copy( 6 ) );
560 aNamespaces[aNsName] = aAttrValue;
561 } else {
562 // this is no namespace declaration
563 aAttribsStrs.emplace_back( aAttrName, aAttrValue );
568 OUString aConvertedName = ConvertNameWithNamespace( aName, aNamespaces );
569 if ( !aConvertedName.getLength() )
570 aConvertedName = ConvertName( aName );
572 aStack.emplace_back( aConvertedName, aNamespaces );
574 for (const std::pair<OUString,OUString> & rAttribsStr : aAttribsStrs) {
575 // convert the attribute names on filling
576 o_aConvertedAttribs[ConvertName( rAttribsStr.first )] = rAttribsStr.second;
579 return aConvertedName;
582 OUString ManifestImport::ConvertNameWithNamespace( const OUString& aName, const StringHashMap& aNamespaces )
584 OUString aNsAlias;
585 OUString aPureName = aName;
587 sal_Int32 nInd = aName.indexOf( ':' );
588 if ( nInd != -1 && nInd < aName.getLength() ) {
589 aNsAlias = aName.copy( 0, nInd );
590 aPureName = aName.copy( nInd + 1 );
593 OUString aResult;
595 StringHashMap::const_iterator aIter = aNamespaces.find( aNsAlias );
596 if ( aIter != aNamespaces.end()
597 && ( aIter->second == MANIFEST_NAMESPACE || aIter->second == MANIFEST_OASIS_NAMESPACE ) ) {
598 // no check for manifest.xml consistency currently since the old versions have supported inconsistent documents as well
599 aResult = MANIFEST_NSPREFIX;
600 aResult += aPureName;
603 return aResult;
606 OUString ManifestImport::ConvertName( const OUString& aName )
608 OUString aConvertedName;
609 for ( ManifestStack::reverse_iterator aIter = aStack.rbegin(); !aConvertedName.getLength() && aIter != aStack.rend(); ++aIter ) {
610 if ( !aIter->m_aNamespaces.empty() )
611 aConvertedName = ConvertNameWithNamespace( aName, aIter->m_aNamespaces );
614 if ( !aConvertedName.getLength() )
615 aConvertedName = aName;
617 return aConvertedName;
620 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */