Coverage Report

Created: 2026-09-28 10:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/desktop/source/deployment/misc/dp_dependencies.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 <config_folders.h>
21
22
#include <sal/config.h>
23
24
#include <com/sun/star/uno/Reference.hxx>
25
#include <com/sun/star/uno/Sequence.hxx>
26
#include <com/sun/star/xml/dom/XElement.hpp>
27
#include <com/sun/star/xml/dom/XNodeList.hpp>
28
#include <osl/diagnose.h>
29
#include <rtl/bootstrap.hxx>
30
#include <rtl/ustring.hxx>
31
#include <sal/types.h>
32
#include <unotools/configmgr.hxx>
33
34
#include <strings.hrc>
35
#include <dp_shared.hxx>
36
37
#include <dp_dependencies.hxx>
38
#include <dp_descriptioninfoset.hxx>
39
#include <dp_version.hxx>
40
41
namespace {
42
43
char const namespaceLibreOffice[] =
44
    "http://libreoffice.org/extensions/description/2011";
45
46
constexpr OUString namespaceOpenOfficeOrg =
47
    u"http://openoffice.org/extensions/description/2006"_ustr;
48
49
char const minimalVersionLibreOffice[] = "LibreOffice-minimal-version";
50
char const maximalVersionLibreOffice[] = "LibreOffice-maximal-version";
51
52
constexpr OUString minimalVersionOpenOfficeOrg =
53
    u"OpenOffice.org-minimal-version"_ustr;
54
55
char const maximalVersionOpenOfficeOrg[] =
56
    "OpenOffice.org-maximal-version";
57
58
0
OUString getLibreOfficeMajorMinorMicro() {
59
0
    return utl::ConfigManager::getAboutBoxProductVersion();
60
0
}
61
62
0
OUString getReferenceOpenOfficeOrgMajorMinor() {
63
#ifdef ANDROID
64
    // just hardcode the version
65
    OUString v("4.1");
66
#else
67
0
    OUString v(
68
0
            u"${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("version")
69
0
            ":Version:ReferenceOOoMajorMinor}"_ustr);
70
0
    rtl::Bootstrap::expandMacros(v); //TODO: check for failure
71
0
#endif
72
0
    return v;
73
0
}
74
75
bool satisfiesMinimalVersion(
76
    std::u16string_view actual, std::u16string_view specified)
77
0
{
78
0
    return dp_misc::compareVersions(actual, specified) != dp_misc::LESS;
79
0
}
80
81
bool satisfiesMaximalVersion(
82
    std::u16string_view actual, std::u16string_view specified)
83
0
{
84
0
    return dp_misc::compareVersions(actual, specified) != dp_misc::GREATER;
85
0
}
86
87
OUString produceErrorText(
88
    OUString const & reason, OUString const & version)
89
0
{
90
0
    return reason.replaceFirst("%VERSION",
91
0
        (version.isEmpty()
92
0
         ?  DpResId(RID_DEPLOYMENT_DEPENDENCIES_UNKNOWN)
93
0
         : version));
94
0
}
95
96
}
97
98
namespace dp_misc::Dependencies {
99
100
css::uno::Sequence< css::uno::Reference< css::xml::dom::XElement > >
101
0
check(dp_misc::DescriptionInfoset const & infoset) {
102
0
    css::uno::Reference< css::xml::dom::XNodeList > deps(
103
0
        infoset.getDependencies());
104
0
    sal_Int32 n = deps->getLength();
105
0
    css::uno::Sequence< css::uno::Reference< css::xml::dom::XElement > >
106
0
        unsatisfied(n);
107
0
    auto unsatisfiedRange = asNonConstRange(unsatisfied);
108
0
    sal_Int32 unsat = 0;
109
    // check first if minimalVersionLibreOffice is specified -- in that case ignore the legacy OOo dependencies
110
0
    bool bIgnoreOoo = false;
111
0
    for (sal_Int32 i = 0; i < n; ++i) {
112
0
        css::uno::Reference< css::xml::dom::XElement > e(
113
0
            deps->item(i), css::uno::UNO_QUERY_THROW);
114
0
        if ( e->getNamespaceURI() == namespaceLibreOffice && e->getTagName() == minimalVersionLibreOffice)
115
0
        {
116
0
            bIgnoreOoo = true;
117
0
            break;
118
0
        }
119
0
    }
120
0
    for (sal_Int32 i = 0; i < n; ++i) {
121
0
        css::uno::Reference< css::xml::dom::XElement > e(
122
0
            deps->item(i), css::uno::UNO_QUERY_THROW);
123
0
        bool sat = false;
124
0
        if ( e->getNamespaceURI() == namespaceOpenOfficeOrg && e->getTagName() == minimalVersionOpenOfficeOrg )
125
0
        {
126
0
            sat = bIgnoreOoo || satisfiesMinimalVersion(
127
0
                getReferenceOpenOfficeOrgMajorMinor(),
128
0
                e->getAttribute(u"value"_ustr));
129
0
        } else if ( e->getNamespaceURI() == namespaceOpenOfficeOrg && e->getTagName() == maximalVersionOpenOfficeOrg )
130
0
        {
131
0
            sat = bIgnoreOoo || satisfiesMaximalVersion(
132
0
                getReferenceOpenOfficeOrgMajorMinor(),
133
0
                e->getAttribute(u"value"_ustr));
134
0
        } else if (e->getNamespaceURI() == namespaceLibreOffice && e->getTagName() == minimalVersionLibreOffice )
135
0
        {
136
0
            sat = satisfiesMinimalVersion(
137
0
                getLibreOfficeMajorMinorMicro(),
138
0
                e->getAttribute(u"value"_ustr));
139
0
        } else if (e->getNamespaceURI() == namespaceLibreOffice && e->getTagName() == maximalVersionLibreOffice )
140
0
        {
141
0
            sat = satisfiesMaximalVersion(getLibreOfficeMajorMinorMicro(), e->getAttribute(u"value"_ustr));
142
0
        } else if (e->hasAttributeNS(namespaceOpenOfficeOrg,
143
0
                       minimalVersionOpenOfficeOrg))
144
0
        {
145
0
            sat = satisfiesMinimalVersion(
146
0
                getReferenceOpenOfficeOrgMajorMinor(),
147
0
                e->getAttributeNS(namespaceOpenOfficeOrg,
148
0
                    minimalVersionOpenOfficeOrg));
149
0
        }
150
0
        if (!sat) {
151
0
            unsatisfiedRange[unsat++] = std::move(e);
152
0
        }
153
0
    }
154
0
    unsatisfied.realloc(unsat);
155
0
    return unsatisfied;
156
0
}
157
158
OUString getErrorText(
159
    css::uno::Reference< css::xml::dom::XElement > const & dependency)
160
0
{
161
0
    OSL_ASSERT(dependency.is());
162
0
    if ( dependency->getNamespaceURI() == namespaceOpenOfficeOrg && dependency->getTagName() == minimalVersionOpenOfficeOrg )
163
0
    {
164
0
        return produceErrorText(
165
0
                DpResId(RID_DEPLOYMENT_DEPENDENCIES_OOO_MIN),
166
0
            dependency->getAttribute(u"value"_ustr));
167
0
    } else if (dependency->getNamespaceURI() == namespaceOpenOfficeOrg && dependency->getTagName() == maximalVersionOpenOfficeOrg )
168
0
    {
169
0
        return produceErrorText(
170
0
                DpResId(RID_DEPLOYMENT_DEPENDENCIES_OOO_MAX),
171
0
            dependency->getAttribute(u"value"_ustr));
172
0
    } else if (dependency->getNamespaceURI() == namespaceLibreOffice && dependency->getTagName() == minimalVersionLibreOffice )
173
0
    {
174
0
        return produceErrorText(
175
0
                DpResId(RID_DEPLOYMENT_DEPENDENCIES_LO_MIN),
176
0
            dependency->getAttribute(u"value"_ustr));
177
0
    } else if (dependency->getNamespaceURI() == namespaceLibreOffice && dependency->getTagName() == maximalVersionLibreOffice )
178
0
    {
179
0
        return produceErrorText(
180
0
                DpResId(RID_DEPLOYMENT_DEPENDENCIES_LO_MAX),
181
0
            dependency->getAttribute(u"value"_ustr));
182
0
    } else if (dependency->hasAttributeNS(namespaceOpenOfficeOrg,
183
0
                   minimalVersionOpenOfficeOrg))
184
0
    {
185
0
        return produceErrorText(
186
0
                DpResId(RID_DEPLOYMENT_DEPENDENCIES_OOO_MIN),
187
0
            dependency->getAttributeNS(namespaceOpenOfficeOrg,
188
0
                minimalVersionOpenOfficeOrg));
189
0
    } else {
190
0
        return DpResId(RID_DEPLOYMENT_DEPENDENCIES_UNKNOWN);
191
0
    }
192
0
}
193
194
}
195
196
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */