xref: /AOO41X/main/comphelper/source/misc/storagehelper.cxx (revision 49b34792d04777c7048569d1e476ae6e26e03037)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_comphelper.hxx"
26 #include <com/sun/star/embed/ElementModes.hpp>
27 #include <com/sun/star/embed/XEncryptionProtectedSource2.hpp>
28 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
29 #include <com/sun/star/beans/XPropertySet.hpp>
30 #include <com/sun/star/beans/PropertyValue.hpp>
31 #include <com/sun/star/beans/NamedValue.hpp>
32 #include <com/sun/star/beans/IllegalTypeException.hpp>
33 #include <com/sun/star/xml/crypto/XDigestContext.hpp>
34 #include <com/sun/star/xml/crypto/XDigestContextSupplier.hpp>
35 #include <com/sun/star/xml/crypto/DigestID.hpp>
36 
37 #include <rtl/digest.h>
38 
39 #include <ucbhelper/content.hxx>
40 
41 #include <comphelper/fileformat.h>
42 #include <comphelper/processfactory.hxx>
43 #include <comphelper/documentconstants.hxx>
44 
45 #include <comphelper/storagehelper.hxx>
46 
47 
48 using namespace ::com::sun::star;
49 
50 namespace comphelper {
51 
52 // ----------------------------------------------------------------------
GetStorageFactory(const uno::Reference<lang::XMultiServiceFactory> & xSF)53 uno::Reference< lang::XSingleServiceFactory > OStorageHelper::GetStorageFactory(
54                             const uno::Reference< lang::XMultiServiceFactory >& xSF )
55         throw ( uno::Exception )
56 {
57     uno::Reference< lang::XMultiServiceFactory > xFactory = xSF.is() ? xSF : ::comphelper::getProcessServiceFactory();
58     if ( !xFactory.is() )
59         throw uno::RuntimeException();
60 
61     uno::Reference < lang::XSingleServiceFactory > xStorageFactory(
62                     xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.embed.StorageFactory" ) ),
63                     uno::UNO_QUERY );
64 
65     if ( !xStorageFactory.is() )
66         throw uno::RuntimeException();
67 
68     return xStorageFactory;
69 }
70 
71 // ----------------------------------------------------------------------
GetFileSystemStorageFactory(const uno::Reference<lang::XMultiServiceFactory> & xSF)72 uno::Reference< lang::XSingleServiceFactory > OStorageHelper::GetFileSystemStorageFactory(
73                             const uno::Reference< lang::XMultiServiceFactory >& xSF )
74         throw ( uno::Exception )
75 {
76     uno::Reference< lang::XMultiServiceFactory > xFactory = xSF.is() ? xSF : ::comphelper::getProcessServiceFactory();
77     if ( !xFactory.is() )
78         throw uno::RuntimeException();
79 
80     uno::Reference < lang::XSingleServiceFactory > xStorageFactory(
81                     xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.embed.FileSystemStorageFactory" ) ),
82                     uno::UNO_QUERY );
83 
84     if ( !xStorageFactory.is() )
85         throw uno::RuntimeException();
86 
87     return xStorageFactory;
88 }
89 
90 // ----------------------------------------------------------------------
GetTemporaryStorage(const uno::Reference<lang::XMultiServiceFactory> & xFactory)91 uno::Reference< embed::XStorage > OStorageHelper::GetTemporaryStorage(
92             const uno::Reference< lang::XMultiServiceFactory >& xFactory )
93     throw ( uno::Exception )
94 {
95     uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstance(),
96                                                     uno::UNO_QUERY );
97     if ( !xTempStorage.is() )
98         throw uno::RuntimeException();
99 
100     return xTempStorage;
101 }
102 
103 // ----------------------------------------------------------------------
GetStorageFromURL(const::rtl::OUString & aURL,sal_Int32 nStorageMode,const uno::Reference<lang::XMultiServiceFactory> & xFactory)104 uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromURL(
105             const ::rtl::OUString& aURL,
106             sal_Int32 nStorageMode,
107             const uno::Reference< lang::XMultiServiceFactory >& xFactory )
108     throw ( uno::Exception )
109 {
110     uno::Sequence< uno::Any > aArgs( 2 );
111     aArgs[0] <<= aURL;
112     aArgs[1] <<= nStorageMode;
113 
114     uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ),
115                                                     uno::UNO_QUERY );
116     if ( !xTempStorage.is() )
117         throw uno::RuntimeException();
118 
119     return xTempStorage;
120 }
121 
122 // ----------------------------------------------------------------------
GetStorageFromURL2(const::rtl::OUString & aURL,sal_Int32 nStorageMode,const uno::Reference<lang::XMultiServiceFactory> & xFactory)123 uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromURL2(
124             const ::rtl::OUString& aURL,
125             sal_Int32 nStorageMode,
126             const uno::Reference< lang::XMultiServiceFactory >& xFactory )
127     throw ( uno::Exception )
128 {
129     uno::Sequence< uno::Any > aArgs( 2 );
130     aArgs[0] <<= aURL;
131     aArgs[1] <<= nStorageMode;
132 
133     uno::Reference< lang::XSingleServiceFactory > xFact;
134     try {
135         ::ucbhelper::Content aCntnt( aURL,
136             uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
137         if (aCntnt.isDocument()) {
138             xFact = GetStorageFactory( xFactory );
139         } else {
140             xFact = GetFileSystemStorageFactory( xFactory );
141         }
142     } catch (uno::Exception &) { }
143 
144     if (!xFact.is()) throw uno::RuntimeException();
145 
146     uno::Reference< embed::XStorage > xTempStorage(
147         xFact->createInstanceWithArguments( aArgs ), uno::UNO_QUERY );
148     if ( !xTempStorage.is() )
149         throw uno::RuntimeException();
150 
151     return xTempStorage;
152 }
153 
154 // ----------------------------------------------------------------------
GetStorageFromInputStream(const uno::Reference<io::XInputStream> & xStream,const uno::Reference<lang::XMultiServiceFactory> & xFactory)155 uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromInputStream(
156             const uno::Reference < io::XInputStream >& xStream,
157             const uno::Reference< lang::XMultiServiceFactory >& xFactory )
158         throw ( uno::Exception )
159 {
160     uno::Sequence< uno::Any > aArgs( 2 );
161     aArgs[0] <<= xStream;
162     aArgs[1] <<= embed::ElementModes::READ;
163 
164     uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ),
165                                                     uno::UNO_QUERY );
166     if ( !xTempStorage.is() )
167         throw uno::RuntimeException();
168 
169     return xTempStorage;
170 }
171 
172 // ----------------------------------------------------------------------
GetStorageFromStream(const uno::Reference<io::XStream> & xStream,sal_Int32 nStorageMode,const uno::Reference<lang::XMultiServiceFactory> & xFactory)173 uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromStream(
174             const uno::Reference < io::XStream >& xStream,
175             sal_Int32 nStorageMode,
176             const uno::Reference< lang::XMultiServiceFactory >& xFactory )
177         throw ( uno::Exception )
178 {
179     uno::Sequence< uno::Any > aArgs( 2 );
180     aArgs[0] <<= xStream;
181     aArgs[1] <<= nStorageMode;
182 
183     uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ),
184                                                     uno::UNO_QUERY );
185     if ( !xTempStorage.is() )
186         throw uno::RuntimeException();
187 
188     return xTempStorage;
189 }
190 
191 // ----------------------------------------------------------------------
CopyInputToOutput(const uno::Reference<io::XInputStream> & xInput,const uno::Reference<io::XOutputStream> & xOutput)192 void OStorageHelper::CopyInputToOutput(
193             const uno::Reference< io::XInputStream >& xInput,
194             const uno::Reference< io::XOutputStream >& xOutput )
195     throw ( uno::Exception )
196 {
197     static const sal_Int32 nConstBufferSize = 32000;
198 
199     sal_Int32 nRead;
200     uno::Sequence < sal_Int8 > aSequence ( nConstBufferSize );
201 
202     do
203     {
204         nRead = xInput->readBytes ( aSequence, nConstBufferSize );
205         if ( nRead < nConstBufferSize )
206         {
207             uno::Sequence < sal_Int8 > aTempBuf ( aSequence.getConstArray(), nRead );
208             xOutput->writeBytes ( aTempBuf );
209         }
210         else
211             xOutput->writeBytes ( aSequence );
212     }
213     while ( nRead == nConstBufferSize );
214 }
215 
216 // ----------------------------------------------------------------------
GetInputStreamFromURL(const::rtl::OUString & aURL,const uno::Reference<lang::XMultiServiceFactory> & xSF)217 uno::Reference< io::XInputStream > OStorageHelper::GetInputStreamFromURL(
218             const ::rtl::OUString& aURL,
219             const uno::Reference< lang::XMultiServiceFactory >& xSF )
220     throw ( uno::Exception )
221 {
222     uno::Reference< lang::XMultiServiceFactory > xFactory = xSF.is() ? xSF : ::comphelper::getProcessServiceFactory();
223     if ( !xFactory.is() )
224         throw uno::RuntimeException();
225 
226     uno::Reference < ::com::sun::star::ucb::XSimpleFileAccess > xTempAccess(
227             xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
228             uno::UNO_QUERY );
229 
230     if ( !xTempAccess.is() )
231         throw uno::RuntimeException();
232 
233     uno::Reference< io::XInputStream > xInputStream = xTempAccess->openFileRead( aURL );
234     if ( !xInputStream.is() )
235         throw uno::RuntimeException();
236 
237     return xInputStream;
238 }
239 
240 // ----------------------------------------------------------------------
SetCommonStorageEncryptionData(const uno::Reference<embed::XStorage> & xStorage,const uno::Sequence<beans::NamedValue> & aEncryptionData)241 void OStorageHelper::SetCommonStorageEncryptionData(
242             const uno::Reference< embed::XStorage >& xStorage,
243             const uno::Sequence< beans::NamedValue >& aEncryptionData )
244     throw ( uno::Exception )
245 {
246     uno::Reference< embed::XEncryptionProtectedSource2 > xEncrSet( xStorage, uno::UNO_QUERY );
247     if ( !xEncrSet.is() )
248         throw io::IOException(); // TODO
249 
250     xEncrSet->setEncryptionData( aEncryptionData );
251 }
252 
253 // ----------------------------------------------------------------------
GetXStorageFormat(const uno::Reference<embed::XStorage> & xStorage)254 sal_Int32 OStorageHelper::GetXStorageFormat(
255             const uno::Reference< embed::XStorage >& xStorage )
256         throw ( uno::Exception )
257 {
258     uno::Reference< beans::XPropertySet > xStorProps( xStorage, uno::UNO_QUERY_THROW );
259 
260     ::rtl::OUString aMediaType;
261     xStorProps->getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) ) >>= aMediaType;
262 
263     sal_Int32 nResult = 0;
264 
265     // TODO/LATER: the filter configuration could be used to detect it later, or batter a special service
266     if (
267         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_WRITER_ASCII       ) ||
268         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_WRITER_WEB_ASCII   ) ||
269         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_WRITER_GLOBAL_ASCII) ||
270         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_DRAW_ASCII         ) ||
271         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_IMPRESS_ASCII      ) ||
272         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_CALC_ASCII         ) ||
273         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_CHART_ASCII        ) ||
274         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_MATH_ASCII         )
275        )
276     {
277         nResult = SOFFICE_FILEFORMAT_60;
278     }
279     else
280     if (
281         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII        ) ||
282         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_WEB_ASCII    ) ||
283         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_ASCII ) ||
284         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_ASCII     ) ||
285         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII) ||
286         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII ) ||
287         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_CHART_ASCII       ) ||
288         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_ASCII     ) ||
289         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_DATABASE_ASCII    ) ||
290         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_REPORT_ASCII    ) ||
291         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_REPORT_CHART_ASCII    ) ||
292         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_TEMPLATE_ASCII        ) ||
293         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_TEMPLATE_ASCII     ) ||
294         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE_ASCII) ||
295         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_TEMPLATE_ASCII ) ||
296         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_CHART_TEMPLATE_ASCII       ) ||
297         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_TEMPLATE_ASCII     )
298        )
299     {
300         nResult = SOFFICE_FILEFORMAT_8;
301     }
302     else
303     {
304         // the mediatype is not known
305         throw beans::IllegalTypeException();
306     }
307 
308     return nResult;
309 }
310 
311 // ----------------------------------------------------------------------
GetTemporaryStorageOfFormat(const::rtl::OUString & aFormat,const uno::Reference<lang::XMultiServiceFactory> & xFactory)312 uno::Reference< embed::XStorage > OStorageHelper::GetTemporaryStorageOfFormat(
313             const ::rtl::OUString& aFormat,
314             const uno::Reference< lang::XMultiServiceFactory >& xFactory )
315     throw ( uno::Exception )
316 {
317     uno::Reference< lang::XMultiServiceFactory > xFactoryToUse = xFactory.is() ? xFactory : ::comphelper::getProcessServiceFactory();
318     if ( !xFactoryToUse.is() )
319         throw uno::RuntimeException();
320 
321     uno::Reference< io::XStream > xTmpStream(
322         xFactoryToUse->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) ) ),
323         uno::UNO_QUERY_THROW );
324 
325     return GetStorageOfFormatFromStream( aFormat, xTmpStream, embed::ElementModes::READWRITE, xFactoryToUse );
326 }
327 
328 // ----------------------------------------------------------------------
GetStorageOfFormatFromURL(const::rtl::OUString & aFormat,const::rtl::OUString & aURL,sal_Int32 nStorageMode,const uno::Reference<lang::XMultiServiceFactory> & xFactory,sal_Bool bRepairStorage)329 uno::Reference< embed::XStorage > OStorageHelper::GetStorageOfFormatFromURL(
330             const ::rtl::OUString& aFormat,
331             const ::rtl::OUString& aURL,
332             sal_Int32 nStorageMode,
333             const uno::Reference< lang::XMultiServiceFactory >& xFactory,
334             sal_Bool bRepairStorage )
335     throw ( uno::Exception )
336 {
337     uno::Sequence< beans::PropertyValue > aProps( 1 );
338     aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) );
339     aProps[0].Value <<= aFormat;
340     if ( bRepairStorage )
341     {
342         aProps.realloc( 2 );
343         aProps[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RepairPackage" ) );
344         aProps[1].Value <<= bRepairStorage;
345     }
346 
347     uno::Sequence< uno::Any > aArgs( 3 );
348     aArgs[0] <<= aURL;
349     aArgs[1] <<= nStorageMode;
350     aArgs[2] <<= aProps;
351 
352     uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ),
353                                                     uno::UNO_QUERY );
354     if ( !xTempStorage.is() )
355         throw uno::RuntimeException();
356 
357     return xTempStorage;
358 }
359 
360 // ----------------------------------------------------------------------
GetStorageOfFormatFromInputStream(const::rtl::OUString & aFormat,const uno::Reference<io::XInputStream> & xStream,const uno::Reference<lang::XMultiServiceFactory> & xFactory,sal_Bool bRepairStorage)361 uno::Reference< embed::XStorage > OStorageHelper::GetStorageOfFormatFromInputStream(
362             const ::rtl::OUString& aFormat,
363             const uno::Reference < io::XInputStream >& xStream,
364             const uno::Reference< lang::XMultiServiceFactory >& xFactory,
365             sal_Bool bRepairStorage )
366         throw ( uno::Exception )
367 {
368     uno::Sequence< beans::PropertyValue > aProps( 1 );
369     aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) );
370     aProps[0].Value <<= aFormat;
371     if ( bRepairStorage )
372     {
373         aProps.realloc( 2 );
374         aProps[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RepairPackage" ) );
375         aProps[1].Value <<= bRepairStorage;
376     }
377 
378     uno::Sequence< uno::Any > aArgs( 3 );
379     aArgs[0] <<= xStream;
380     aArgs[1] <<= embed::ElementModes::READ;
381     aArgs[2] <<= aProps;
382 
383     uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ),
384                                                     uno::UNO_QUERY );
385     if ( !xTempStorage.is() )
386         throw uno::RuntimeException();
387 
388     return xTempStorage;
389 }
390 
391 // ----------------------------------------------------------------------
GetStorageOfFormatFromStream(const::rtl::OUString & aFormat,const uno::Reference<io::XStream> & xStream,sal_Int32 nStorageMode,const uno::Reference<lang::XMultiServiceFactory> & xFactory,sal_Bool bRepairStorage)392 uno::Reference< embed::XStorage > OStorageHelper::GetStorageOfFormatFromStream(
393             const ::rtl::OUString& aFormat,
394             const uno::Reference < io::XStream >& xStream,
395             sal_Int32 nStorageMode,
396             const uno::Reference< lang::XMultiServiceFactory >& xFactory,
397             sal_Bool bRepairStorage )
398         throw ( uno::Exception )
399 {
400     uno::Sequence< beans::PropertyValue > aProps( 1 );
401     aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) );
402     aProps[0].Value <<= aFormat;
403     if ( bRepairStorage )
404     {
405         aProps.realloc( 2 );
406         aProps[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RepairPackage" ) );
407         aProps[1].Value <<= bRepairStorage;
408     }
409 
410     uno::Sequence< uno::Any > aArgs( 3 );
411     aArgs[0] <<= xStream;
412     aArgs[1] <<= nStorageMode;
413     aArgs[2] <<= aProps;
414 
415     uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ),
416                                                     uno::UNO_QUERY );
417     if ( !xTempStorage.is() )
418         throw uno::RuntimeException();
419 
420     return xTempStorage;
421 }
422 
423 // ----------------------------------------------------------------------
CreatePackageEncryptionData(const::rtl::OUString & aPassword,const uno::Reference<lang::XMultiServiceFactory> & xSF)424 uno::Sequence< beans::NamedValue > OStorageHelper::CreatePackageEncryptionData( const ::rtl::OUString& aPassword, const uno::Reference< lang::XMultiServiceFactory >& xSF )
425 {
426     // TODO/LATER: Should not the method be part of DocPasswordHelper?
427     uno::Sequence< beans::NamedValue > aEncryptionData;
428     sal_Int32 nSha1Ind = 0;
429     if ( !aPassword.isEmpty() )
430     {
431         // generate SHA256 start key
432         try
433         {
434             uno::Reference< lang::XMultiServiceFactory > xFactory = xSF.is() ? xSF : ::comphelper::getProcessServiceFactory();
435             if ( !xFactory.is() )
436                 throw uno::RuntimeException();
437 
438             uno::Reference< xml::crypto::XDigestContextSupplier > xDigestContextSupplier( xFactory->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.crypto.NSSInitializer" ) ) ), uno::UNO_QUERY_THROW );
439             uno::Reference< xml::crypto::XDigestContext > xDigestContext( xDigestContextSupplier->getDigestContext( xml::crypto::DigestID::SHA256, uno::Sequence< beans::NamedValue >() ), uno::UNO_SET_THROW );
440 
441             ::rtl::OString aUTF8Password( ::rtl::OUStringToOString( aPassword, RTL_TEXTENCODING_UTF8 ) );
442             xDigestContext->updateDigest( uno::Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aUTF8Password.getStr() ), aUTF8Password.getLength() ) );
443             uno::Sequence< sal_Int8 > aDigest = xDigestContext->finalizeDigestAndDispose();
444 
445             aEncryptionData.realloc( ++nSha1Ind );
446             aEncryptionData[0].Name = PACKAGE_ENCRYPTIONDATA_SHA256UTF8;
447             aEncryptionData[0].Value <<= aDigest;
448         }
449         catch ( uno::Exception& )
450         {
451             OSL_ENSURE( false, "Can not create SHA256 digest!" );
452         }
453 
454         // MS_1252 encoding was used for SO60 document format password encoding,
455         // this encoding supports only a minor subset of nonascii characters,
456         // but for compatibility reasons it has to be used for old document formats
457         aEncryptionData.realloc( nSha1Ind + 2 );
458         aEncryptionData[nSha1Ind].Name = PACKAGE_ENCRYPTIONDATA_SHA1UTF8;
459         aEncryptionData[nSha1Ind + 1].Name = PACKAGE_ENCRYPTIONDATA_SHA1MS1252;
460 
461         rtl_TextEncoding pEncoding[2] = { RTL_TEXTENCODING_UTF8, RTL_TEXTENCODING_MS_1252 };
462 
463         for ( sal_Int32 nInd = 0; nInd < 2; nInd++ )
464         {
465             ::rtl::OString aByteStrPass = ::rtl::OUStringToOString( aPassword, pEncoding[nInd] );
466 
467             sal_uInt8 pBuffer[RTL_DIGEST_LENGTH_SHA1];
468             rtlDigestError nError = rtl_digest_SHA1( aByteStrPass.getStr(),
469                                                     aByteStrPass.getLength(),
470                                                     pBuffer,
471                                                     RTL_DIGEST_LENGTH_SHA1 );
472 
473             if ( nError != rtl_Digest_E_None )
474             {
475                 aEncryptionData.realloc( nSha1Ind );
476                 break;
477             }
478 
479             aEncryptionData[nSha1Ind+nInd].Value <<= uno::Sequence< sal_Int8 >( (sal_Int8*)pBuffer, RTL_DIGEST_LENGTH_SHA1 );
480         }
481     }
482 
483     return aEncryptionData;
484 }
485 
486 // ----------------------------------------------------------------------
IsValidZipEntryFileName(const::rtl::OUString & aName,sal_Bool bSlashAllowed)487 sal_Bool OStorageHelper::IsValidZipEntryFileName( const ::rtl::OUString& aName, sal_Bool bSlashAllowed )
488 {
489     return IsValidZipEntryFileName( aName.getStr(), aName.getLength(), bSlashAllowed );
490 }
491 
492 // ----------------------------------------------------------------------
IsValidZipEntryFileName(const sal_Unicode * pChar,sal_Int32 nLength,sal_Bool bSlashAllowed)493 sal_Bool OStorageHelper::IsValidZipEntryFileName(
494     const sal_Unicode *pChar, sal_Int32 nLength, sal_Bool bSlashAllowed )
495 {
496     for ( sal_Int32 i = 0; i < nLength; i++ )
497     {
498         switch ( pChar[i] )
499         {
500             case '\\':
501             case '?':
502             case '<':
503             case '>':
504             case '\"':
505             case '|':
506             case ':':
507                 return sal_False;
508             case '/':
509                 if ( !bSlashAllowed )
510                     return sal_False;
511                 break;
512             default:
513                 if ( pChar[i] < 32  || (pChar[i] >= 0xD800 && pChar[i] <= 0xDFFF) )
514                     return sal_False;
515         }
516     }
517     return sal_True;
518 }
519 
520 // ----------------------------------------------------------------------
PathHasSegment(const::rtl::OUString & aPath,const::rtl::OUString & aSegment)521 sal_Bool OStorageHelper::PathHasSegment( const ::rtl::OUString& aPath, const ::rtl::OUString& aSegment )
522 {
523     sal_Bool bResult = sal_False;
524     const sal_Int32 nPathLen = aPath.getLength();
525     const sal_Int32 nSegLen = aSegment.getLength();
526 
527     if ( nSegLen && nPathLen >= nSegLen )
528     {
529         ::rtl::OUString aEndSegment( RTL_CONSTASCII_USTRINGPARAM( "/" ) );
530         aEndSegment += aSegment;
531 
532         ::rtl::OUString aInternalSegment( aEndSegment );
533         aInternalSegment += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) );
534 
535         if ( aPath.indexOf( aInternalSegment ) >= 0 )
536             bResult = sal_True;
537 
538         if ( !bResult && !aPath.compareTo( aSegment, nSegLen ) )
539         {
540             if ( nPathLen == nSegLen || aPath.getStr()[nSegLen] == (sal_Unicode)'/' )
541                 bResult = sal_True;
542         }
543 
544         if ( !bResult && nPathLen > nSegLen && aPath.copy( nPathLen - nSegLen - 1, nSegLen + 1 ).equals( aEndSegment ) )
545             bResult = sal_True;
546     }
547 
548     return bResult;
549 }
550 
551 }
552 
553