Coverage Report

Created: 2026-11-06 11:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/embeddedobj/source/commonembedding/xfactory.cxx
Line
Count
Source
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/EntryInitModes.hpp>
22
#include <com/sun/star/beans/XPropertySet.hpp>
23
#include <com/sun/star/beans/NamedValue.hpp>
24
#include <com/sun/star/container/XNameAccess.hpp>
25
#include <com/sun/star/io/IOException.hpp>
26
#include <com/sun/star/lang/NoSupportException.hpp>
27
#include <cppuhelper/supportsservice.hxx>
28
#include <cppuhelper/weak.hxx>
29
#include <comphelper/documentconstants.hxx>
30
#include <officecfg/Office/Common.hxx>
31
32
#include "xfactory.hxx"
33
#include <commonembobj.hxx>
34
#include <specialobject.hxx>
35
36
37
using namespace ::com::sun::star;
38
39
40
uno::Reference< uno::XInterface > SAL_CALL OOoEmbeddedObjectFactory::createInstanceInitFromEntry(
41
                                                                    const uno::Reference< embed::XStorage >& xStorage,
42
                                                                    const OUString& sEntName,
43
                                                                    const uno::Sequence< beans::PropertyValue >& aMediaDescr,
44
                                                                    const uno::Sequence< beans::PropertyValue >& lObjArgs )
45
0
{
46
0
    if ( officecfg::Office::Common::Security::Scripting::DisableActiveContent::get() )
47
0
        throw lang::NoSupportException(u"Active embedded content is disabled!"_ustr);
48
0
    if ( !xStorage.is() )
49
0
        throw lang::IllegalArgumentException( u"No parent storage is provided!"_ustr,
50
0
                                            static_cast< ::cppu::OWeakObject* >(this),
51
0
                                            1 );
52
53
0
    if ( sEntName.isEmpty() )
54
0
        throw lang::IllegalArgumentException( u"Empty element name is provided!"_ustr,
55
0
                                            static_cast< ::cppu::OWeakObject* >(this),
56
0
                                            2 );
57
58
0
    uno::Reference< container::XNameAccess > xNameAccess( xStorage, uno::UNO_QUERY_THROW );
59
60
    // detect entry existence
61
0
    if ( !xNameAccess->hasByName( sEntName ) )
62
0
        throw container::NoSuchElementException();
63
64
0
    uno::Reference< uno::XInterface > xResult;
65
0
    if ( !xStorage->isStorageElement( sEntName ) )
66
0
    {
67
        // the object must be OOo embedded object, if it is not an exception must be thrown
68
0
        throw io::IOException(); // TODO:
69
0
    }
70
    // the object must be based on storage
71
0
    uno::Reference< embed::XStorage > xSubStorage =
72
0
            xStorage->openStorageElement( sEntName, embed::ElementModes::READ );
73
74
0
    uno::Reference< beans::XPropertySet > xPropSet( xSubStorage, uno::UNO_QUERY_THROW );
75
76
0
    OUString aMediaType;
77
0
    try {
78
0
        uno::Any aAny = xPropSet->getPropertyValue(u"MediaType"_ustr);
79
0
        aAny >>= aMediaType;
80
0
    }
81
0
    catch ( const uno::Exception& )
82
0
    {
83
0
    }
84
85
0
    try {
86
0
        if ( xSubStorage.is() )
87
0
            xSubStorage->dispose();
88
0
    }
89
0
    catch ( const uno::Exception& )
90
0
    {
91
0
    }
92
0
    xSubStorage.clear();
93
94
0
    uno::Sequence< beans::NamedValue > aObject = m_aConfigHelper.GetObjectPropsByMediaType( aMediaType );
95
96
    // If the sequence is empty, fall back to the FileFormatVersion=6200 filter, Base only has that.
97
0
    if (!aObject.hasElements() && aMediaType == MIMETYPE_OASIS_OPENDOCUMENT_DATABASE)
98
0
        aObject = m_aConfigHelper.GetObjectPropsByMediaType(MIMETYPE_VND_SUN_XML_BASE);
99
100
0
    if ( !aObject.hasElements() )
101
0
        throw io::IOException(); // unexpected mimetype of the storage
102
103
0
    xResult.set(static_cast< ::cppu::OWeakObject* > ( new OCommonEmbeddedObject(
104
0
                                            m_xContext,
105
0
                                            aObject ) ),
106
0
                uno::UNO_QUERY );
107
108
0
    uno::Reference< embed::XEmbedPersist > xPersist( xResult, uno::UNO_QUERY_THROW );
109
110
0
    xPersist->setPersistentEntry( xStorage,
111
0
                                    sEntName,
112
0
                                    embed::EntryInitModes::DEFAULT_INIT,
113
0
                                    aMediaDescr,
114
0
                                    lObjArgs );
115
116
0
    return xResult;
117
0
}
118
119
uno::Reference< uno::XInterface > SAL_CALL OOoEmbeddedObjectFactory::createInstanceInitFromMediaDescriptor(
120
        const uno::Reference< embed::XStorage >& xStorage,
121
        const OUString& sEntName,
122
        const uno::Sequence< beans::PropertyValue >& aMediaDescr,
123
        const uno::Sequence< beans::PropertyValue >& lObjArgs )
124
0
{
125
0
    if ( officecfg::Office::Common::Security::Scripting::DisableActiveContent::get() )
126
0
        throw lang::NoSupportException(u"Active embedded content is disabled!"_ustr);
127
0
    if ( !xStorage.is() )
128
0
        throw lang::IllegalArgumentException( u"No parent storage is provided!"_ustr,
129
0
                                            static_cast< ::cppu::OWeakObject* >(this),
130
0
                                            1 );
131
132
0
    if ( sEntName.isEmpty() )
133
0
        throw lang::IllegalArgumentException( u"Empty element name is provided!"_ustr,
134
0
                                            static_cast< ::cppu::OWeakObject* >(this),
135
0
                                            2 );
136
137
0
    uno::Sequence< beans::PropertyValue > aTempMedDescr( aMediaDescr );
138
139
    // check if there is FilterName
140
0
    OUString aFilterName = m_aConfigHelper.UpdateMediaDescriptorWithFilterName( aTempMedDescr, false );
141
142
0
    uno::Reference< uno::XInterface > xResult;
143
144
    // find document service name
145
0
    if ( aFilterName.isEmpty() )
146
0
    {
147
        // the object must be OOo embedded object, if it is not an exception must be thrown
148
0
        throw io::IOException(); // TODO:
149
0
    }
150
0
    uno::Sequence< beans::NamedValue > aObject = m_aConfigHelper.GetObjectPropsByFilter( aFilterName );
151
0
    if ( !aObject.hasElements() )
152
0
        throw io::IOException(); // unexpected mimetype of the storage
153
154
155
0
    xResult.set(static_cast< ::cppu::OWeakObject* > ( new OCommonEmbeddedObject(
156
0
                                        m_xContext,
157
0
                                        aObject ) ),
158
0
                uno::UNO_QUERY );
159
160
0
    uno::Reference< embed::XEmbedPersist > xPersist( xResult, uno::UNO_QUERY_THROW );
161
162
0
    xPersist->setPersistentEntry( xStorage,
163
0
                                    sEntName,
164
0
                                    embed::EntryInitModes::MEDIA_DESCRIPTOR_INIT,
165
0
                                    aTempMedDescr,
166
0
                                    lObjArgs );
167
168
0
    return xResult;
169
0
}
170
171
uno::Reference< uno::XInterface > SAL_CALL OOoEmbeddedObjectFactory::createInstanceInitNew(
172
                                            const uno::Sequence< sal_Int8 >& aClassID,
173
                                            const OUString& /*aClassName*/,
174
                                            const uno::Reference< embed::XStorage >& xStorage,
175
                                            const OUString& sEntName,
176
                                            const uno::Sequence< beans::PropertyValue >& lObjArgs )
177
0
{
178
0
    if ( officecfg::Office::Common::Security::Scripting::DisableActiveContent::get() )
179
0
        throw lang::NoSupportException(u"Active embedded content is disabled!"_ustr);
180
0
    uno::Reference< uno::XInterface > xResult;
181
182
0
    if ( !xStorage.is() )
183
0
        throw lang::IllegalArgumentException( u"No parent storage is provided!"_ustr,
184
0
                                            uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
185
0
                                            3 );
186
187
0
    if ( sEntName.isEmpty() )
188
0
        throw lang::IllegalArgumentException( u"Empty element name is provided!"_ustr,
189
0
                                            uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
190
0
                                            4 );
191
192
0
    uno::Sequence< beans::NamedValue > aObject = m_aConfigHelper.GetObjectPropsByClassID( aClassID );
193
0
    if ( !aObject.hasElements() )
194
0
        throw io::IOException(); // unexpected mimetype of the storage
195
196
0
    xResult.set( static_cast< ::cppu::OWeakObject* > ( new OCommonEmbeddedObject(
197
0
                                             m_xContext,
198
0
                                             aObject ) ),
199
0
                 uno::UNO_QUERY );
200
201
202
0
    uno::Reference< embed::XEmbedPersist > xPersist( xResult, uno::UNO_QUERY_THROW );
203
204
0
    xPersist->setPersistentEntry( xStorage,
205
0
                                    sEntName,
206
0
                                    embed::EntryInitModes::TRUNCATE_INIT,
207
0
                                    uno::Sequence< beans::PropertyValue >(),
208
0
                                    lObjArgs );
209
210
0
    return xResult;
211
0
}
212
213
uno::Reference< uno::XInterface > SAL_CALL OOoEmbeddedObjectFactory::createInstanceUserInit(
214
            const uno::Sequence< sal_Int8 >& aClassID,
215
            const OUString& /*aClassName*/,
216
            const uno::Reference< embed::XStorage >& xStorage,
217
            const OUString& sEntName,
218
            sal_Int32 nEntryConnectionMode,
219
            const uno::Sequence< beans::PropertyValue >& lArguments,
220
            const uno::Sequence< beans::PropertyValue >& lObjArgs )
221
0
{
222
    // the initialization is completely controlled by user
223
0
    if ( officecfg::Office::Common::Security::Scripting::DisableActiveContent::get() )
224
0
        throw lang::NoSupportException(u"Active embedded content is disabled!"_ustr);
225
0
    if ( !xStorage.is() )
226
0
        throw lang::IllegalArgumentException( u"No parent storage is provided!"_ustr,
227
0
                                            uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
228
0
                                            1 );
229
230
0
    if ( sEntName.isEmpty() )
231
0
        throw lang::IllegalArgumentException( u"Empty element name is provided!"_ustr,
232
0
                                            uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
233
0
                                            2 );
234
235
0
    uno::Sequence< beans::NamedValue > aObject = m_aConfigHelper.GetObjectPropsByClassID( aClassID );
236
0
    if ( !aObject.hasElements() )
237
0
        throw io::IOException(); // unexpected mimetype of the storage
238
239
0
    uno::Sequence< beans::PropertyValue > aTempMedDescr( lArguments );
240
0
    if ( nEntryConnectionMode == embed::EntryInitModes::MEDIA_DESCRIPTOR_INIT )
241
0
    {
242
0
        OUString aFilterName = m_aConfigHelper.UpdateMediaDescriptorWithFilterName( aTempMedDescr, aObject );
243
0
        if ( aFilterName.isEmpty() )
244
        // the object must be OOo embedded object, if it is not an exception must be thrown
245
0
            throw io::IOException(); // TODO:
246
0
    }
247
248
0
    uno::Reference< uno::XInterface > xResult(
249
0
                    static_cast< ::cppu::OWeakObject* > ( new OCommonEmbeddedObject(
250
0
                                                m_xContext,
251
0
                                                aObject ) ),
252
0
                    uno::UNO_QUERY );
253
254
0
    uno::Reference< embed::XEmbedPersist > xPersist( xResult, uno::UNO_QUERY_THROW );
255
0
    xPersist->setPersistentEntry( xStorage,
256
0
                                  sEntName,
257
0
                                  nEntryConnectionMode,
258
0
                                  aTempMedDescr,
259
0
                                  lObjArgs );
260
261
0
    return xResult;
262
0
}
263
264
uno::Reference< uno::XInterface > SAL_CALL OOoEmbeddedObjectFactory::createInstanceLink(
265
                                            const uno::Reference< embed::XStorage >& /*xStorage*/,
266
                                            const OUString& /*sEntName*/,
267
                                            const uno::Sequence< beans::PropertyValue >& aMediaDescr,
268
                                            const uno::Sequence< beans::PropertyValue >& lObjArgs )
269
0
{
270
0
    if ( officecfg::Office::Common::Security::Scripting::DisableActiveContent::get() )
271
0
        throw lang::NoSupportException(u"Active embedded content is disabled!"_ustr);
272
0
    uno::Reference< uno::XInterface > xResult;
273
274
0
    uno::Sequence< beans::PropertyValue > aTempMedDescr( aMediaDescr );
275
276
    // check if there is URL, URL must exist
277
0
    OUString aURL;
278
0
    for (beans::PropertyValue const& prop : aTempMedDescr)
279
0
        if ( prop.Name == "URL" )
280
0
            prop.Value >>= aURL;
281
282
0
    if ( aURL.isEmpty() )
283
0
        throw lang::IllegalArgumentException( u"No URL for the link is provided!"_ustr,
284
0
                                        uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
285
0
                                        3 );
286
287
0
    OUString aFilterName = m_aConfigHelper.UpdateMediaDescriptorWithFilterName( aTempMedDescr, false );
288
289
0
    if ( aFilterName.isEmpty() )
290
0
    {
291
        // the object must be OOo embedded object, if it is not an exception must be thrown
292
0
        throw io::IOException(); // TODO:
293
0
    }
294
0
    uno::Sequence< beans::NamedValue > aObject = m_aConfigHelper.GetObjectPropsByFilter( aFilterName );
295
0
    if ( !aObject.hasElements() )
296
0
        throw io::IOException(); // unexpected mimetype of the storage
297
298
299
0
    xResult.set(static_cast< ::cppu::OWeakObject* > ( new OCommonEmbeddedObject(
300
0
                                        m_xContext,
301
0
                                        aObject,
302
0
                                        aTempMedDescr,
303
0
                                        lObjArgs ) ),
304
0
                uno::UNO_QUERY );
305
306
0
    return xResult;
307
0
}
308
309
uno::Reference< uno::XInterface > SAL_CALL OOoEmbeddedObjectFactory::createInstanceLinkUserInit(
310
                                                const uno::Sequence< sal_Int8 >& aClassID,
311
                                                const OUString& /*aClassName*/,
312
                                                const uno::Reference< embed::XStorage >& xStorage,
313
                                                const OUString& sEntName,
314
                                                const uno::Sequence< beans::PropertyValue >& lArguments,
315
                                                const uno::Sequence< beans::PropertyValue >& lObjArgs )
316
0
{
317
0
    if ( officecfg::Office::Common::Security::Scripting::DisableActiveContent::get() )
318
0
        throw lang::NoSupportException(u"Active embedded content is disabled!"_ustr);
319
0
    uno::Reference< uno::XInterface > xResult;
320
321
    // the initialization is completely controlled by user
322
0
    if ( !xStorage.is() )
323
0
        throw lang::IllegalArgumentException( u"No parent storage is provided!"_ustr,
324
0
                                            uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
325
0
                                            1 );
326
327
0
    if ( sEntName.isEmpty() )
328
0
        throw lang::IllegalArgumentException( u"Empty element name is provided!"_ustr,
329
0
                                            uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
330
0
                                            2 );
331
332
0
    uno::Sequence< beans::PropertyValue > aTempMedDescr( lArguments );
333
334
0
    OUString aURL;
335
0
    for (beans::PropertyValue const& prop : aTempMedDescr)
336
0
        if ( prop.Name == "URL" )
337
0
            prop.Value >>= aURL;
338
339
0
    if ( aURL.isEmpty() )
340
0
        throw lang::IllegalArgumentException( u"No URL for the link is provided!"_ustr,
341
0
                                        uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
342
0
                                        3 );
343
344
0
    uno::Sequence< beans::NamedValue > aObject = m_aConfigHelper.GetObjectPropsByClassID( aClassID );
345
0
    if ( !aObject.hasElements() )
346
0
        throw io::IOException(); // unexpected mimetype of the storage
347
348
0
    OUString aFilterName = m_aConfigHelper.UpdateMediaDescriptorWithFilterName( aTempMedDescr, aObject );
349
350
0
    if ( aFilterName.isEmpty() )
351
0
    {
352
        // the object must be OOo embedded object, if it is not an exception must be thrown
353
0
        throw io::IOException(); // TODO:
354
0
    }
355
356
0
    xResult.set(static_cast< ::cppu::OWeakObject* > ( new OCommonEmbeddedObject(
357
0
                                        m_xContext,
358
0
                                        aObject,
359
0
                                        aTempMedDescr,
360
0
                                        lObjArgs ) ),
361
0
                uno::UNO_QUERY );
362
363
0
    return xResult;
364
0
}
365
366
OUString SAL_CALL OOoEmbeddedObjectFactory::getImplementationName()
367
0
{
368
0
    return u"com.sun.star.comp.embed.OOoEmbeddedObjectFactory"_ustr;
369
0
}
370
371
sal_Bool SAL_CALL OOoEmbeddedObjectFactory::supportsService( const OUString& ServiceName )
372
0
{
373
0
    return cppu::supportsService(this, ServiceName);
374
0
}
375
376
uno::Sequence< OUString > SAL_CALL OOoEmbeddedObjectFactory::getSupportedServiceNames()
377
0
{
378
0
    return { u"com.sun.star.embed.OOoEmbeddedObjectFactory"_ustr, u"com.sun.star.comp.embed.OOoEmbeddedObjectFactory"_ustr };
379
0
}
380
381
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
382
embeddedobj_OOoEmbeddedObjectFactory_get_implementation(
383
    css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
384
0
{
385
0
    return cppu::acquire(new OOoEmbeddedObjectFactory(context));
386
0
}
387
388
389
uno::Reference< uno::XInterface > SAL_CALL OOoSpecialEmbeddedObjectFactory::createInstanceUserInit(
390
            const uno::Sequence< sal_Int8 >& aClassID,
391
            const OUString& /*aClassName*/,
392
            const uno::Reference< embed::XStorage >& /*xStorage*/,
393
            const OUString& /*sEntName*/,
394
            sal_Int32 /*nEntryConnectionMode*/,
395
            const uno::Sequence< beans::PropertyValue >& /*lArguments*/,
396
            const uno::Sequence< beans::PropertyValue >& /*lObjArgs*/ )
397
0
{
398
0
    if ( officecfg::Office::Common::Security::Scripting::DisableActiveContent::get() )
399
0
        throw lang::NoSupportException(u"Active embedded content is disabled!"_ustr);
400
0
    uno::Sequence< beans::NamedValue > aObject = m_aConfigHelper.GetObjectPropsByClassID( aClassID );
401
0
    if ( !aObject.hasElements() )
402
0
        throw io::IOException(); // unexpected mimetype of the storage
403
404
0
    uno::Reference< uno::XInterface > xResult(
405
0
                    static_cast< ::cppu::OWeakObject* > ( new OSpecialEmbeddedObject(
406
0
                                                m_xContext,
407
0
                                                aObject ) ),
408
0
                    uno::UNO_QUERY );
409
0
    return xResult;
410
0
}
411
412
OUString SAL_CALL OOoSpecialEmbeddedObjectFactory::getImplementationName()
413
0
{
414
0
    return u"com.sun.star.comp.embed.OOoSpecialEmbeddedObjectFactory"_ustr;
415
0
}
416
417
sal_Bool SAL_CALL OOoSpecialEmbeddedObjectFactory::supportsService( const OUString& ServiceName )
418
0
{
419
0
    return cppu::supportsService(this, ServiceName);
420
0
}
421
422
uno::Sequence< OUString > SAL_CALL OOoSpecialEmbeddedObjectFactory::getSupportedServiceNames()
423
0
{
424
0
    return { u"com.sun.star.embed.OOoSpecialEmbeddedObjectFactory"_ustr, u"com.sun.star.comp.embed.OOoSpecialEmbeddedObjectFactory"_ustr };
425
0
}
426
427
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
428
embeddedobj_OOoSpecialEmbeddedObjectFactory_get_implementation(
429
    css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
430
0
{
431
0
    return cppu::acquire(new OOoSpecialEmbeddedObjectFactory(context));
432
0
}
433
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */