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