Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
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/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
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 .
18 : : */
19 : :
20 : : #include <com/sun/star/embed/ElementModes.hpp>
21 : : #include <com/sun/star/embed/XEncryptionProtectedSource2.hpp>
22 : : #include <com/sun/star/embed/XStorage.hpp>
23 : : #include <com/sun/star/embed/XTransactedObject.hpp>
24 : : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
25 : : #include <com/sun/star/ucb/SimpleFileAccess.hpp>
26 : : #include <com/sun/star/beans/XPropertySet.hpp>
27 : : #include <com/sun/star/beans/PropertyValue.hpp>
28 : : #include <com/sun/star/beans/NamedValue.hpp>
29 : : #include <com/sun/star/beans/IllegalTypeException.hpp>
30 : : #include <com/sun/star/xml/crypto/XDigestContext.hpp>
31 : : #include <com/sun/star/xml/crypto/XDigestContextSupplier.hpp>
32 : : #include <com/sun/star/xml/crypto/DigestID.hpp>
33 : :
34 : : #include <vector>
35 : : #include <rtl/digest.h>
36 : :
37 : : #include <ucbhelper/content.hxx>
38 : :
39 : : #include <comphelper/fileformat.h>
40 : : #include <comphelper/processfactory.hxx>
41 : : #include <comphelper/documentconstants.hxx>
42 : :
43 : : #include <comphelper/storagehelper.hxx>
44 : :
45 : :
46 : : using namespace ::com::sun::star;
47 : :
48 : : namespace comphelper {
49 : :
50 : : // ----------------------------------------------------------------------
51 : 6628 : uno::Reference< lang::XSingleServiceFactory > OStorageHelper::GetStorageFactory(
52 : : const uno::Reference< lang::XMultiServiceFactory >& xSF )
53 : : throw ( uno::Exception )
54 : : {
55 [ + + ][ + - ]: 6628 : uno::Reference< lang::XMultiServiceFactory > xFactory = xSF.is() ? xSF : ::comphelper::getProcessServiceFactory();
56 [ - + ]: 6628 : if ( !xFactory.is() )
57 [ # # ]: 0 : throw uno::RuntimeException();
58 : :
59 [ + - ]: 6628 : rtl::OUString sService(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.StorageFactory"));
60 : :
61 : : uno::Reference < lang::XSingleServiceFactory > xStorageFactory(
62 [ + - ][ + - ]: 6628 : xFactory->createInstance(sService), uno::UNO_QUERY);
[ + - ]
63 : :
64 [ + + ]: 6628 : if ( !xStorageFactory.is() )
65 : : {
66 : : throw uno::RuntimeException(rtl::OUString(
67 : : RTL_CONSTASCII_USTRINGPARAM("Could not load: ")) + sService,
68 [ + - ][ + - ]: 1623 : uno::Reference< uno::XInterface >());
69 : : }
70 : :
71 : 6628 : return xStorageFactory;
72 : : }
73 : :
74 : : // ----------------------------------------------------------------------
75 : 0 : uno::Reference< lang::XSingleServiceFactory > OStorageHelper::GetFileSystemStorageFactory(
76 : : const uno::Reference< lang::XMultiServiceFactory >& xSF )
77 : : throw ( uno::Exception )
78 : : {
79 [ # # ][ # # ]: 0 : uno::Reference< lang::XMultiServiceFactory > xFactory = xSF.is() ? xSF : ::comphelper::getProcessServiceFactory();
80 [ # # ]: 0 : if ( !xFactory.is() )
81 [ # # ]: 0 : throw uno::RuntimeException();
82 : :
83 [ # # ]: 0 : rtl::OUString sService(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.FileSystemStorageFactory"));
84 : :
85 : : uno::Reference < lang::XSingleServiceFactory > xStorageFactory(
86 [ # # ][ # # ]: 0 : xFactory->createInstance(sService), uno::UNO_QUERY);
[ # # ]
87 : :
88 [ # # ]: 0 : if ( !xStorageFactory.is() )
89 : : {
90 : : throw uno::RuntimeException(rtl::OUString(
91 : : RTL_CONSTASCII_USTRINGPARAM("Could not load: ")) + sService,
92 [ # # ][ # # ]: 0 : uno::Reference< uno::XInterface >());
93 : : }
94 : :
95 : 0 : return xStorageFactory;
96 : : }
97 : :
98 : : // ----------------------------------------------------------------------
99 : 3782 : uno::Reference< embed::XStorage > OStorageHelper::GetTemporaryStorage(
100 : : const uno::Reference< lang::XMultiServiceFactory >& xFactory )
101 : : throw ( uno::Exception )
102 : : {
103 [ + - ]: 6241 : uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstance(),
104 [ + - ][ + - ]: 2459 : uno::UNO_QUERY );
105 [ - + ]: 2459 : if ( !xTempStorage.is() )
106 [ # # ]: 0 : throw uno::RuntimeException();
107 : :
108 : 2459 : return xTempStorage;
109 : : }
110 : :
111 : : // ----------------------------------------------------------------------
112 : 192 : uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromURL(
113 : : const ::rtl::OUString& aURL,
114 : : sal_Int32 nStorageMode,
115 : : const uno::Reference< lang::XMultiServiceFactory >& xFactory )
116 : : throw ( uno::Exception )
117 : : {
118 [ + - ]: 192 : uno::Sequence< uno::Any > aArgs( 2 );
119 [ + - ][ + - ]: 192 : aArgs[0] <<= aURL;
120 [ + - ][ + - ]: 192 : aArgs[1] <<= nStorageMode;
121 : :
122 [ + - ][ + - ]: 384 : uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ),
123 [ + - ][ + - ]: 192 : uno::UNO_QUERY );
124 [ - + ]: 192 : if ( !xTempStorage.is() )
125 [ # # ]: 0 : throw uno::RuntimeException();
126 : :
127 [ + - ]: 192 : return xTempStorage;
128 : : }
129 : :
130 : : // ----------------------------------------------------------------------
131 : 0 : uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromURL2(
132 : : const ::rtl::OUString& aURL,
133 : : sal_Int32 nStorageMode,
134 : : const uno::Reference< lang::XMultiServiceFactory >& xFactory )
135 : : throw ( uno::Exception )
136 : : {
137 [ # # ]: 0 : uno::Sequence< uno::Any > aArgs( 2 );
138 [ # # ][ # # ]: 0 : aArgs[0] <<= aURL;
139 [ # # ][ # # ]: 0 : aArgs[1] <<= nStorageMode;
140 : :
141 : 0 : uno::Reference< lang::XSingleServiceFactory > xFact;
142 : : try {
143 : : ::ucbhelper::Content aCntnt( aURL,
144 [ # # ]: 0 : uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
145 [ # # ][ # # ]: 0 : if (aCntnt.isDocument()) {
146 [ # # ][ # # ]: 0 : xFact = GetStorageFactory( xFactory );
147 : : } else {
148 [ # # ][ # # ]: 0 : xFact = GetFileSystemStorageFactory( xFactory );
149 [ # # ][ # # ]: 0 : }
150 [ # # ]: 0 : } catch (uno::Exception &) { }
151 : :
152 [ # # ][ # # ]: 0 : if (!xFact.is()) throw uno::RuntimeException();
153 : :
154 : : uno::Reference< embed::XStorage > xTempStorage(
155 [ # # ][ # # ]: 0 : xFact->createInstanceWithArguments( aArgs ), uno::UNO_QUERY );
[ # # ]
156 [ # # ]: 0 : if ( !xTempStorage.is() )
157 [ # # ]: 0 : throw uno::RuntimeException();
158 : :
159 [ # # ]: 0 : return xTempStorage;
160 : : }
161 : :
162 : : // ----------------------------------------------------------------------
163 : 24 : uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromInputStream(
164 : : const uno::Reference < io::XInputStream >& xStream,
165 : : const uno::Reference< lang::XMultiServiceFactory >& xFactory )
166 : : throw ( uno::Exception )
167 : : {
168 [ + - ]: 24 : uno::Sequence< uno::Any > aArgs( 2 );
169 [ + - ][ + - ]: 24 : aArgs[0] <<= xStream;
170 [ + - ][ + - ]: 24 : aArgs[1] <<= embed::ElementModes::READ;
171 : :
172 [ + - ][ + - ]: 48 : uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ),
173 [ + - ][ + - ]: 24 : uno::UNO_QUERY );
174 [ - + ]: 24 : if ( !xTempStorage.is() )
175 [ # # ]: 0 : throw uno::RuntimeException();
176 : :
177 [ + - ]: 24 : return xTempStorage;
178 : : }
179 : :
180 : : // ----------------------------------------------------------------------
181 : 0 : uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromStream(
182 : : const uno::Reference < io::XStream >& xStream,
183 : : sal_Int32 nStorageMode,
184 : : const uno::Reference< lang::XMultiServiceFactory >& xFactory )
185 : : throw ( uno::Exception )
186 : : {
187 [ # # ]: 0 : uno::Sequence< uno::Any > aArgs( 2 );
188 [ # # ][ # # ]: 0 : aArgs[0] <<= xStream;
189 [ # # ][ # # ]: 0 : aArgs[1] <<= nStorageMode;
190 : :
191 [ # # ][ # # ]: 0 : uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ),
192 [ # # ][ # # ]: 0 : uno::UNO_QUERY );
193 [ # # ]: 0 : if ( !xTempStorage.is() )
194 [ # # ]: 0 : throw uno::RuntimeException();
195 : :
196 [ # # ]: 0 : return xTempStorage;
197 : : }
198 : :
199 : : // ----------------------------------------------------------------------
200 : 1035 : void OStorageHelper::CopyInputToOutput(
201 : : const uno::Reference< io::XInputStream >& xInput,
202 : : const uno::Reference< io::XOutputStream >& xOutput )
203 : : throw ( uno::Exception )
204 : : {
205 : : static const sal_Int32 nConstBufferSize = 32000;
206 : :
207 : : sal_Int32 nRead;
208 [ + - ]: 1035 : uno::Sequence < sal_Int8 > aSequence ( nConstBufferSize );
209 : :
210 [ + + ]: 1444 : do
211 : : {
212 [ + - ][ + - ]: 1444 : nRead = xInput->readBytes ( aSequence, nConstBufferSize );
213 [ + + ]: 1444 : if ( nRead < nConstBufferSize )
214 : : {
215 [ + - ]: 1035 : uno::Sequence < sal_Int8 > aTempBuf ( aSequence.getConstArray(), nRead );
216 [ + - ][ + - ]: 1035 : xOutput->writeBytes ( aTempBuf );
[ + - ]
217 : : }
218 : : else
219 [ + - ][ + - ]: 409 : xOutput->writeBytes ( aSequence );
220 : : }
221 [ + - ]: 1035 : while ( nRead == nConstBufferSize );
222 : 1035 : }
223 : :
224 : : // ----------------------------------------------------------------------
225 : 0 : uno::Reference< io::XInputStream > OStorageHelper::GetInputStreamFromURL(
226 : : const ::rtl::OUString& aURL,
227 : : const uno::Reference< uno::XComponentContext >& context )
228 : : throw ( uno::Exception )
229 : : {
230 [ # # ][ # # ]: 0 : uno::Reference< io::XInputStream > xInputStream = ucb::SimpleFileAccess::create(context)->openFileRead( aURL );
231 [ # # ]: 0 : if ( !xInputStream.is() )
232 [ # # ]: 0 : throw uno::RuntimeException();
233 : :
234 : 0 : return xInputStream;
235 : : }
236 : :
237 : : // ----------------------------------------------------------------------
238 : 12 : void OStorageHelper::SetCommonStorageEncryptionData(
239 : : const uno::Reference< embed::XStorage >& xStorage,
240 : : const uno::Sequence< beans::NamedValue >& aEncryptionData )
241 : : throw ( uno::Exception )
242 : : {
243 [ + - ]: 12 : uno::Reference< embed::XEncryptionProtectedSource2 > xEncrSet( xStorage, uno::UNO_QUERY );
244 [ - + ]: 12 : if ( !xEncrSet.is() )
245 [ # # ]: 0 : throw io::IOException(); // TODO
246 : :
247 [ + - ][ + - ]: 12 : xEncrSet->setEncryptionData( aEncryptionData );
248 : 12 : }
249 : :
250 : : // ----------------------------------------------------------------------
251 : 1887 : sal_Int32 OStorageHelper::GetXStorageFormat(
252 : : const uno::Reference< embed::XStorage >& xStorage )
253 : : throw ( uno::Exception )
254 : : {
255 [ + - ]: 1887 : uno::Reference< beans::XPropertySet > xStorProps( xStorage, uno::UNO_QUERY_THROW );
256 : :
257 : 1887 : ::rtl::OUString aMediaType;
258 [ + - ][ + - ]: 1887 : xStorProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" )) ) >>= aMediaType;
[ + - ]
259 : :
260 : 1887 : sal_Int32 nResult = 0;
261 : :
262 : : // TODO/LATER: the filter configuration could be used to detect it later, or batter a special service
263 [ + + ][ + + : 15036 : if (
+ - + - +
+ + + + +
+ - - + ]
264 : 1887 : aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_WRITER_ASCII ) ||
265 : 1881 : aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_WRITER_WEB_ASCII ) ||
266 : 1881 : aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_WRITER_GLOBAL_ASCII) ||
267 : 1881 : aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_DRAW_ASCII ) ||
268 : 1879 : aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_IMPRESS_ASCII ) ||
269 : 1877 : aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_CALC_ASCII ) ||
270 : 1875 : aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_CHART_ASCII ) ||
271 : 1875 : aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_MATH_ASCII )
272 : : )
273 : : {
274 : 12 : nResult = SOFFICE_FILEFORMAT_60;
275 : : }
276 : : else
277 [ + + ][ + + : 9333 : if (
+ - + - +
+ + + + +
+ - + - +
- + - + -
+ + + - +
- + - + -
- + ]
278 : 1875 : aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII ) ||
279 : 537 : aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_WEB_ASCII ) ||
280 : 537 : aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_ASCII ) ||
281 : 537 : aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_ASCII ) ||
282 : 535 : aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII) ||
283 : 530 : aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII ) ||
284 : 437 : aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_CHART_ASCII ) ||
285 : 437 : aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_ASCII ) ||
286 : 437 : aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_DATABASE_ASCII ) ||
287 : 437 : aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_REPORT_ASCII ) ||
288 : 437 : aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_REPORT_CHART_ASCII ) ||
289 : 437 : aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_TEMPLATE_ASCII ) ||
290 : 432 : aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_TEMPLATE_ASCII ) ||
291 : 432 : aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE_ASCII) ||
292 : 432 : aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_TEMPLATE_ASCII ) ||
293 : 432 : aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_CHART_TEMPLATE_ASCII ) ||
294 : 432 : aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_TEMPLATE_ASCII )
295 : : )
296 : : {
297 : 1443 : nResult = SOFFICE_FILEFORMAT_8;
298 : : }
299 : : else
300 : : {
301 : : // the mediatype is not known
302 [ + - ]: 432 : throw beans::IllegalTypeException();
303 : : }
304 : :
305 : 1887 : return nResult;
306 : : }
307 : :
308 : : // ----------------------------------------------------------------------
309 : 0 : uno::Reference< embed::XStorage > OStorageHelper::GetStorageOfFormatFromURL(
310 : : const ::rtl::OUString& aFormat,
311 : : const ::rtl::OUString& aURL,
312 : : sal_Int32 nStorageMode,
313 : : const uno::Reference< lang::XMultiServiceFactory >& xFactory,
314 : : sal_Bool bRepairStorage )
315 : : throw ( uno::Exception )
316 : : {
317 [ # # ]: 0 : uno::Sequence< beans::PropertyValue > aProps( 1 );
318 [ # # ][ # # ]: 0 : aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) );
319 [ # # ][ # # ]: 0 : aProps[0].Value <<= aFormat;
320 [ # # ]: 0 : if ( bRepairStorage )
321 : : {
322 [ # # ]: 0 : aProps.realloc( 2 );
323 [ # # ][ # # ]: 0 : aProps[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RepairPackage" ) );
324 [ # # ][ # # ]: 0 : aProps[1].Value <<= bRepairStorage;
325 : : }
326 : :
327 [ # # ]: 0 : uno::Sequence< uno::Any > aArgs( 3 );
328 [ # # ][ # # ]: 0 : aArgs[0] <<= aURL;
329 [ # # ][ # # ]: 0 : aArgs[1] <<= nStorageMode;
330 [ # # ][ # # ]: 0 : aArgs[2] <<= aProps;
331 : :
332 [ # # ][ # # ]: 0 : uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ),
333 [ # # ][ # # ]: 0 : uno::UNO_QUERY );
334 [ # # ]: 0 : if ( !xTempStorage.is() )
335 [ # # ]: 0 : throw uno::RuntimeException();
336 : :
337 [ # # ][ # # ]: 0 : return xTempStorage;
338 : : }
339 : :
340 : : // ----------------------------------------------------------------------
341 : 1644 : uno::Reference< embed::XStorage > OStorageHelper::GetStorageOfFormatFromInputStream(
342 : : const ::rtl::OUString& aFormat,
343 : : const uno::Reference < io::XInputStream >& xStream,
344 : : const uno::Reference< lang::XMultiServiceFactory >& xFactory,
345 : : sal_Bool bRepairStorage )
346 : : throw ( uno::Exception )
347 : : {
348 [ + - ]: 1644 : uno::Sequence< beans::PropertyValue > aProps( 1 );
349 [ + - ][ + - ]: 1644 : aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) );
350 [ + - ][ + - ]: 1644 : aProps[0].Value <<= aFormat;
351 [ - + ]: 1644 : if ( bRepairStorage )
352 : : {
353 [ # # ]: 0 : aProps.realloc( 2 );
354 [ # # ][ # # ]: 0 : aProps[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RepairPackage" ) );
355 [ # # ][ # # ]: 0 : aProps[1].Value <<= bRepairStorage;
356 : : }
357 : :
358 [ + - ]: 1644 : uno::Sequence< uno::Any > aArgs( 3 );
359 [ + - ][ + - ]: 1644 : aArgs[0] <<= xStream;
360 [ + - ][ + - ]: 1644 : aArgs[1] <<= embed::ElementModes::READ;
361 [ + - ][ + - ]: 1644 : aArgs[2] <<= aProps;
362 : :
363 [ + + ][ + - ]: 3123 : uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ),
364 [ + + ][ + - ]: 1479 : uno::UNO_QUERY );
365 [ - + ]: 1329 : if ( !xTempStorage.is() )
366 [ # # ]: 0 : throw uno::RuntimeException();
367 : :
368 [ + - ][ + - ]: 1644 : return xTempStorage;
369 : : }
370 : :
371 : : // ----------------------------------------------------------------------
372 : 57 : uno::Reference< embed::XStorage > OStorageHelper::GetStorageOfFormatFromStream(
373 : : const ::rtl::OUString& aFormat,
374 : : const uno::Reference < io::XStream >& xStream,
375 : : sal_Int32 nStorageMode,
376 : : const uno::Reference< lang::XMultiServiceFactory >& xFactory,
377 : : sal_Bool bRepairStorage )
378 : : throw ( uno::Exception )
379 : : {
380 [ + - ]: 57 : uno::Sequence< beans::PropertyValue > aProps( 1 );
381 [ + - ][ + - ]: 57 : aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) );
382 [ + - ][ + - ]: 57 : aProps[0].Value <<= aFormat;
383 [ + - ]: 57 : if ( bRepairStorage )
384 : : {
385 [ + - ]: 57 : aProps.realloc( 2 );
386 [ + - ][ + - ]: 57 : aProps[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RepairPackage" ) );
387 [ + - ][ + - ]: 57 : aProps[1].Value <<= bRepairStorage;
388 : : }
389 : :
390 [ + - ]: 57 : uno::Sequence< uno::Any > aArgs( 3 );
391 [ + - ][ + - ]: 57 : aArgs[0] <<= xStream;
392 [ + - ][ + - ]: 57 : aArgs[1] <<= nStorageMode;
393 [ + - ][ + - ]: 57 : aArgs[2] <<= aProps;
394 : :
395 [ + - ][ + - ]: 114 : uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ),
396 [ + - ][ + - ]: 57 : uno::UNO_QUERY );
397 [ - + ]: 57 : if ( !xTempStorage.is() )
398 [ # # ]: 0 : throw uno::RuntimeException();
399 : :
400 [ + - ][ + - ]: 57 : return xTempStorage;
401 : : }
402 : :
403 : : // ----------------------------------------------------------------------
404 : 6 : uno::Sequence< beans::NamedValue > OStorageHelper::CreatePackageEncryptionData( const ::rtl::OUString& aPassword, const uno::Reference< lang::XMultiServiceFactory >& xSF )
405 : : {
406 : : // TODO/LATER: Should not the method be part of DocPasswordHelper?
407 : 6 : uno::Sequence< beans::NamedValue > aEncryptionData;
408 [ + - ]: 6 : if ( !aPassword.isEmpty() )
409 : : {
410 : 6 : sal_Int32 nSha1Ind = 0;
411 : : // generate SHA256 start key
412 : : try
413 : : {
414 [ - + ][ + - ]: 6 : uno::Reference< lang::XMultiServiceFactory > xFactory = xSF.is() ? xSF : ::comphelper::getProcessServiceFactory();
415 [ - + ]: 6 : if ( !xFactory.is() )
416 [ # # ]: 0 : throw uno::RuntimeException();
417 : :
418 [ + - ][ + - ]: 6 : uno::Reference< xml::crypto::XDigestContextSupplier > xDigestContextSupplier( xFactory->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.crypto.NSSInitializer" ) ) ), uno::UNO_QUERY_THROW );
[ + - ][ + - ]
419 [ + - ][ + - ]: 6 : uno::Reference< xml::crypto::XDigestContext > xDigestContext( xDigestContextSupplier->getDigestContext( xml::crypto::DigestID::SHA256, uno::Sequence< beans::NamedValue >() ), uno::UNO_SET_THROW );
[ + - ][ + - ]
[ + - ]
420 : :
421 [ + - ]: 6 : ::rtl::OString aUTF8Password( ::rtl::OUStringToOString( aPassword, RTL_TEXTENCODING_UTF8 ) );
422 [ + - ][ + - ]: 6 : xDigestContext->updateDigest( uno::Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aUTF8Password.getStr() ), aUTF8Password.getLength() ) );
[ + - ][ + - ]
423 [ + - ][ + - ]: 6 : uno::Sequence< sal_Int8 > aDigest = xDigestContext->finalizeDigestAndDispose();
424 : :
425 [ + - ]: 6 : aEncryptionData.realloc( ++nSha1Ind );
426 [ + - ][ + - ]: 6 : aEncryptionData[0].Name = PACKAGE_ENCRYPTIONDATA_SHA256UTF8;
427 [ + - ][ + - ]: 6 : aEncryptionData[0].Value <<= aDigest;
[ # # ][ + - ]
428 : : }
429 [ # # ]: 0 : catch ( uno::Exception& )
430 : : {
431 : : OSL_ENSURE( false, "Can not create SHA256 digest!" );
432 : : }
433 : :
434 : : // MS_1252 encoding was used for SO60 document format password encoding,
435 : : // this encoding supports only a minor subset of nonascii characters,
436 : : // but for compatibility reasons it has to be used for old document formats
437 [ + - ]: 6 : aEncryptionData.realloc( nSha1Ind + 2 );
438 [ + - ][ + - ]: 6 : aEncryptionData[nSha1Ind].Name = PACKAGE_ENCRYPTIONDATA_SHA1UTF8;
439 [ + - ][ + - ]: 6 : aEncryptionData[nSha1Ind + 1].Name = PACKAGE_ENCRYPTIONDATA_SHA1MS1252;
440 : :
441 : 6 : rtl_TextEncoding pEncoding[2] = { RTL_TEXTENCODING_UTF8, RTL_TEXTENCODING_MS_1252 };
442 : :
443 [ + + ]: 18 : for ( sal_Int32 nInd = 0; nInd < 2; nInd++ )
444 : : {
445 [ + - ]: 12 : ::rtl::OString aByteStrPass = ::rtl::OUStringToOString( aPassword, pEncoding[nInd] );
446 : :
447 : : sal_uInt8 pBuffer[RTL_DIGEST_LENGTH_SHA1];
448 : 12 : rtlDigestError nError = rtl_digest_SHA1( aByteStrPass.getStr(),
449 : 12 : aByteStrPass.getLength(),
450 : : pBuffer,
451 : 12 : RTL_DIGEST_LENGTH_SHA1 );
452 : :
453 [ - + ]: 12 : if ( nError != rtl_Digest_E_None )
454 : : {
455 [ # # ]: 0 : aEncryptionData.realloc( nSha1Ind );
456 : : break;
457 : : }
458 : :
459 [ + - ][ + - ]: 24 : aEncryptionData[nSha1Ind+nInd].Value <<= uno::Sequence< sal_Int8 >( (sal_Int8*)pBuffer, RTL_DIGEST_LENGTH_SHA1 );
[ + - ][ + - ]
[ + - ]
460 : 12 : }
461 : : }
462 : :
463 : 6 : return aEncryptionData;
464 : : }
465 : :
466 : : // ----------------------------------------------------------------------
467 : 338794 : sal_Bool OStorageHelper::IsValidZipEntryFileName( const ::rtl::OUString& aName, sal_Bool bSlashAllowed )
468 : : {
469 : 338794 : return IsValidZipEntryFileName( aName.getStr(), aName.getLength(), bSlashAllowed );
470 : : }
471 : :
472 : : // ----------------------------------------------------------------------
473 : 338794 : sal_Bool OStorageHelper::IsValidZipEntryFileName(
474 : : const sal_Unicode *pChar, sal_Int32 nLength, sal_Bool bSlashAllowed )
475 : : {
476 [ + + ]: 7486161 : for ( sal_Int32 i = 0; i < nLength; i++ )
477 : : {
478 [ + + + ]: 7147369 : switch ( pChar[i] )
479 : : {
480 : : case '\\':
481 : : case '?':
482 : : case '<':
483 : : case '>':
484 : : case '\"':
485 : : case '|':
486 : : case ':':
487 : 2 : return sal_False;
488 : : case '/':
489 [ - + ]: 384592 : if ( !bSlashAllowed )
490 : 0 : return sal_False;
491 : 384592 : break;
492 : : default:
493 [ + - ][ - + ]: 6762775 : if ( pChar[i] < 32 || (pChar[i] >= 0xD800 && pChar[i] <= 0xDFFF) )
[ # # ]
494 : 0 : return sal_False;
495 : : }
496 : : }
497 : 338794 : return sal_True;
498 : : }
499 : :
500 : : // ----------------------------------------------------------------------
501 : 832 : sal_Bool OStorageHelper::PathHasSegment( const ::rtl::OUString& aPath, const ::rtl::OUString& aSegment )
502 : : {
503 : 832 : sal_Bool bResult = sal_False;
504 : 832 : const sal_Int32 nPathLen = aPath.getLength();
505 : 832 : const sal_Int32 nSegLen = aSegment.getLength();
506 : :
507 [ + - ][ + - ]: 832 : if ( !aSegment.isEmpty() && nPathLen >= nSegLen )
[ + - ]
508 : : {
509 [ + - ]: 832 : ::rtl::OUString aEndSegment( RTL_CONSTASCII_USTRINGPARAM( "/" ) );
510 : 832 : aEndSegment += aSegment;
511 : :
512 : 832 : ::rtl::OUString aInternalSegment( aEndSegment );
513 [ + - ]: 832 : aInternalSegment += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) );
514 : :
515 [ - + ]: 832 : if ( aPath.indexOf( aInternalSegment ) >= 0 )
516 : 0 : bResult = sal_True;
517 : :
518 [ + - ][ - + ]: 832 : if ( !bResult && !aPath.compareTo( aSegment, nSegLen ) )
[ - + ]
519 : : {
520 [ # # ][ # # ]: 0 : if ( nPathLen == nSegLen || aPath.getStr()[nSegLen] == (sal_Unicode)'/' )
[ # # ]
521 : 0 : bResult = sal_True;
522 : : }
523 : :
524 [ + - ][ + - ]: 832 : if ( !bResult && nPathLen > nSegLen && aPath.copy( nPathLen - nSegLen - 1, nSegLen + 1 ).equals( aEndSegment ) )
[ - + ][ + - ]
[ - + ]
525 : 832 : bResult = sal_True;
526 : : }
527 : :
528 : 832 : return bResult;
529 : : }
530 : :
531 : 612 : class LifecycleProxy::Impl
532 : : : public std::vector< uno::Reference< embed::XStorage > > {};
533 : 306 : LifecycleProxy::LifecycleProxy()
534 [ + - ]: 306 : : m_pBadness( new Impl() ) { }
535 : 306 : LifecycleProxy::~LifecycleProxy() { }
536 : :
537 : 0 : void LifecycleProxy::commitStorages()
538 : : {
539 [ # # # # ]: 0 : for (Impl::reverse_iterator iter = m_pBadness->rbegin();
[ # # ]
540 : 0 : iter != m_pBadness->rend(); ++iter) // reverse order (outwards)
541 : : {
542 [ # # ]: 0 : uno::Reference<embed::XTransactedObject> const xTransaction(*iter,
543 [ # # ]: 0 : uno::UNO_QUERY);
544 [ # # ]: 0 : if (xTransaction.is())
545 : : {
546 [ # # ][ # # ]: 0 : xTransaction->commit();
547 : : }
548 : 0 : }
549 : 0 : }
550 : :
551 : 0 : static void splitPath( std::vector<rtl::OUString> &rElems,
552 : : const ::rtl::OUString& rPath )
553 : : {
554 [ # # ]: 0 : for (sal_Int32 i = 0; i >= 0;)
555 [ # # ]: 0 : rElems.push_back( rPath.getToken( 0, '/', i ) );
556 : 0 : }
557 : :
558 : 0 : static uno::Reference< embed::XStorage > LookupStorageAtPath(
559 : : const uno::Reference< embed::XStorage > &xParentStorage,
560 : : std::vector<rtl::OUString> &rElems, sal_uInt32 nOpenMode,
561 : : LifecycleProxy &rNastiness )
562 : : {
563 : 0 : uno::Reference< embed::XStorage > xStorage( xParentStorage );
564 [ # # ]: 0 : rNastiness.m_pBadness->push_back( xStorage );
565 [ # # ][ # # ]: 0 : for( size_t i = 0; i < rElems.size() && xStorage.is(); i++ )
[ # # ]
566 : : {
567 [ # # ][ # # ]: 0 : xStorage = xStorage->openStorageElement( rElems[i], nOpenMode );
[ # # ]
568 [ # # ]: 0 : rNastiness.m_pBadness->push_back( xStorage );
569 : : }
570 : 0 : return xStorage;
571 : : }
572 : :
573 : 0 : uno::Reference< embed::XStorage > OStorageHelper::GetStorageAtPath(
574 : : const uno::Reference< embed::XStorage > &xStorage,
575 : : const ::rtl::OUString& rPath, sal_uInt32 nOpenMode,
576 : : LifecycleProxy &rNastiness )
577 : : {
578 [ # # ]: 0 : std::vector<rtl::OUString> aElems;
579 [ # # ]: 0 : splitPath( aElems, rPath );
580 [ # # ]: 0 : return LookupStorageAtPath( xStorage, aElems, nOpenMode, rNastiness );
581 : : }
582 : :
583 : 0 : uno::Reference< io::XStream > OStorageHelper::GetStreamAtPath(
584 : : const uno::Reference< embed::XStorage > &xParentStorage,
585 : : const ::rtl::OUString& rPath, sal_uInt32 nOpenMode,
586 : : LifecycleProxy &rNastiness )
587 : : {
588 [ # # ]: 0 : std::vector<rtl::OUString> aElems;
589 [ # # ]: 0 : splitPath( aElems, rPath );
590 [ # # ]: 0 : rtl::OUString aName( aElems.back() );
591 [ # # ]: 0 : aElems.pop_back();
592 : 0 : sal_uInt32 nStorageMode = nOpenMode & ~embed::ElementModes::TRUNCATE;
593 : : uno::Reference< embed::XStorage > xStorage(
594 : : LookupStorageAtPath( xParentStorage, aElems, nStorageMode, rNastiness ),
595 [ # # ][ # # ]: 0 : uno::UNO_QUERY_THROW );
596 [ # # ][ # # ]: 0 : return xStorage->openStreamElement( aName, nOpenMode );
597 : : }
598 : :
599 : 0 : uno::Reference< io::XStream > OStorageHelper::GetStreamAtPackageURL(
600 : : uno::Reference< embed::XStorage > const& xParentStorage,
601 : : const ::rtl::OUString& rURL, sal_uInt32 const nOpenMode,
602 : : LifecycleProxy & rNastiness)
603 : : {
604 : : static char const s_PkgScheme[] = "vnd.sun.star.Package:";
605 [ # # ]: 0 : if (0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength(
606 : : rURL.getStr(), rURL.getLength(),
607 : 0 : s_PkgScheme, SAL_N_ELEMENTS(s_PkgScheme) - 1))
608 : : {
609 : 0 : ::rtl::OUString const path(rURL.copy(SAL_N_ELEMENTS(s_PkgScheme)-1));
610 [ # # ]: 0 : return GetStreamAtPath(xParentStorage, path, nOpenMode, rNastiness);
611 : : }
612 : 0 : return 0;
613 : : }
614 : :
615 : : }
616 : :
617 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|