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