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 #include <config_fuzzers.h>
20
21 #include <connectivity/DriversConfig.hxx>
22 #include <o3tl/string_view.hxx>
23 #include <tools/wldcrd.hxx>
24 #include <comphelper/sequence.hxx>
25 #include <utility>
26
27 using namespace connectivity;
28 using namespace utl;
29 using namespace ::com::sun::star;
30
31 namespace
32 {
lcl_convert(const uno::Sequence<OUString> & _aSource,uno::Any & _rDest)33 void lcl_convert(const uno::Sequence< OUString >& _aSource,uno::Any& _rDest)
34 {
35 uno::Sequence<uno::Any> aRet(_aSource.getLength());
36 std::transform(_aSource.begin(), _aSource.end(), aRet.getArray(),
37 [](auto& str) { return uno::Any(str); });
38 _rDest <<= aRet;
39 }
lcl_fillValues(const::utl::OConfigurationNode & _aURLPatternNode,const OUString & _sNode,::comphelper::NamedValueCollection & _rValues)40 void lcl_fillValues(const ::utl::OConfigurationNode& _aURLPatternNode,const OUString& _sNode,::comphelper::NamedValueCollection& _rValues)
41 {
42 const ::utl::OConfigurationNode aPropertiesNode = _aURLPatternNode.openNode(_sNode);
43 if ( !aPropertiesNode.isValid() )
44 return;
45
46 uno::Sequence< OUString > aStringSeq;
47 for (auto& prop : aPropertiesNode.getNodeNames())
48 {
49 uno::Any aValue = aPropertiesNode.getNodeValue(prop + "/Value");
50 if ( aValue >>= aStringSeq )
51 {
52 lcl_convert(aStringSeq,aValue);
53 }
54 _rValues.put(prop, aValue);
55 } // for (;pPropertiesIter != pPropertiesEnd ; ++pPropertiesIter,++pNamedIter)
56 }
lcl_readURLPatternNode(const::utl::OConfigurationTreeRoot & _aInstalled,const OUString & _sEntry,TInstalledDriver & _rInstalledDriver)57 void lcl_readURLPatternNode(const ::utl::OConfigurationTreeRoot& _aInstalled,const OUString& _sEntry,TInstalledDriver& _rInstalledDriver)
58 {
59 const ::utl::OConfigurationNode aURLPatternNode = _aInstalled.openNode(_sEntry);
60 if ( !aURLPatternNode.isValid() )
61 return;
62
63 OUString sParentURLPattern;
64 aURLPatternNode.getNodeValue(u"ParentURLPattern"_ustr) >>= sParentURLPattern;
65 if ( !sParentURLPattern.isEmpty() )
66 lcl_readURLPatternNode(_aInstalled,sParentURLPattern,_rInstalledDriver);
67
68 OUString sDriverFactory;
69 aURLPatternNode.getNodeValue(u"Driver"_ustr) >>= sDriverFactory;
70 if ( !sDriverFactory.isEmpty() )
71 _rInstalledDriver.sDriverFactory = sDriverFactory;
72
73 OUString sDriverTypeDisplayName;
74 aURLPatternNode.getNodeValue(u"DriverTypeDisplayName"_ustr) >>= sDriverTypeDisplayName;
75 OSL_ENSURE(!sDriverTypeDisplayName.isEmpty(),"No valid DriverTypeDisplayName property!");
76 if ( !sDriverTypeDisplayName.isEmpty() )
77 _rInstalledDriver.sDriverTypeDisplayName = sDriverTypeDisplayName;
78
79 lcl_fillValues(aURLPatternNode,u"Properties"_ustr,_rInstalledDriver.aProperties);
80 lcl_fillValues(aURLPatternNode,u"Features"_ustr,_rInstalledDriver.aFeatures);
81 lcl_fillValues(aURLPatternNode,u"MetaData"_ustr,_rInstalledDriver.aMetaData);
82 }
83 }
84
DriversConfigImpl()85 DriversConfigImpl::DriversConfigImpl()
86 {
87 }
88
getInstalledDrivers(const uno::Reference<uno::XComponentContext> & _rxORB) const89 const TInstalledDrivers& DriversConfigImpl::getInstalledDrivers(const uno::Reference< uno::XComponentContext >& _rxORB) const
90 {
91 if ( m_aDrivers.empty() )
92 {
93 if ( !m_aInstalled.isValid() )
94 {
95 m_aInstalled = ::utl::OConfigurationTreeRoot::createWithComponentContext(_rxORB,
96 u"org.openoffice.Office.DataAccess.Drivers/Installed"_ustr, -1, ::utl::OConfigurationTreeRoot::CM_READONLY);
97 }
98
99 if ( m_aInstalled.isValid() )
100 {
101 for (auto& pattern : m_aInstalled.getNodeNames())
102 {
103 TInstalledDriver aInstalledDriver;
104 lcl_readURLPatternNode(m_aInstalled, pattern, aInstalledDriver);
105 if ( !aInstalledDriver.sDriverFactory.isEmpty() )
106 m_aDrivers.emplace(pattern, aInstalledDriver);
107 }
108 } // if ( m_aInstalled.isValid() )
109 }
110 return m_aDrivers;
111 }
112
DriversConfig(uno::Reference<uno::XComponentContext> _xORB)113 DriversConfig::DriversConfig(uno::Reference< uno::XComponentContext > _xORB)
114 :m_xORB(std::move(_xORB))
115 {
116 }
117
118
~DriversConfig()119 DriversConfig::~DriversConfig()
120 {
121 }
122
123
DriversConfig(const DriversConfig & _rhs)124 DriversConfig::DriversConfig( const DriversConfig& _rhs )
125 {
126 *this = _rhs;
127 }
128
129
operator =(const DriversConfig & _rhs)130 DriversConfig& DriversConfig::operator=( const DriversConfig& _rhs )
131 {
132 if ( this != &_rhs )
133 {
134 m_aNode = _rhs.m_aNode;
135 }
136 return *this;
137 }
138
139
getDriverFactoryName(std::u16string_view _sURL) const140 OUString DriversConfig::getDriverFactoryName(std::u16string_view _sURL) const
141 {
142 #if ENABLE_FUZZERS
143 if (o3tl::starts_with(_sURL, u"sdbc:dbase:"))
144 return "com.sun.star.comp.sdbc.dbase.ODriver";
145 #endif
146
147 const TInstalledDrivers& rDrivers = m_aNode->getInstalledDrivers(m_xORB);
148 OUString sRet;
149 OUString sOldPattern;
150 for(const auto& [rPattern, rDriver] : rDrivers)
151 {
152 WildCard aWildCard(rPattern);
153 if ( sOldPattern.getLength() < rPattern.getLength() && aWildCard.Matches(_sURL) )
154 {
155 sRet = rDriver.sDriverFactory;
156 sOldPattern = rPattern;
157 }
158 }
159
160 return sRet;
161 }
162
getDriverTypeDisplayName(std::u16string_view _sURL) const163 OUString DriversConfig::getDriverTypeDisplayName(std::u16string_view _sURL) const
164 {
165 const TInstalledDrivers& rDrivers = m_aNode->getInstalledDrivers(m_xORB);
166 OUString sRet;
167 OUString sOldPattern;
168 for(const auto& [rPattern, rDriver] : rDrivers)
169 {
170 WildCard aWildCard(rPattern);
171 if ( sOldPattern.getLength() < rPattern.getLength() && aWildCard.Matches(_sURL) )
172 {
173 sRet = rDriver.sDriverTypeDisplayName;
174 sOldPattern = rPattern;
175 }
176 }
177
178 return sRet;
179 }
180
getProperties(std::u16string_view _sURL) const181 const ::comphelper::NamedValueCollection& DriversConfig::getProperties(std::u16string_view _sURL)
182 const
183 {
184 return impl_get(_sURL,1);
185 }
186
getFeatures(std::u16string_view _sURL) const187 const ::comphelper::NamedValueCollection& DriversConfig::getFeatures(std::u16string_view _sURL)
188 const
189 {
190 return impl_get(_sURL,0);
191 }
192
getMetaData(std::u16string_view _sURL) const193 const ::comphelper::NamedValueCollection& DriversConfig::getMetaData(std::u16string_view _sURL)
194 const
195 {
196 return impl_get(_sURL,2);
197 }
198
impl_get(std::u16string_view _sURL,sal_Int32 _nProps) const199 const ::comphelper::NamedValueCollection& DriversConfig::impl_get(std::u16string_view _sURL,sal_Int32 _nProps) const
200 {
201 const TInstalledDrivers& rDrivers = m_aNode->getInstalledDrivers(m_xORB);
202 const ::comphelper::NamedValueCollection* pRet = nullptr;
203 OUString sOldPattern;
204 for(const auto& [rPattern, rDriver] : rDrivers)
205 {
206 WildCard aWildCard(rPattern);
207 if ( sOldPattern.getLength() < rPattern.getLength() && aWildCard.Matches(_sURL) )
208 {
209 switch(_nProps)
210 {
211 case 0:
212 pRet = &rDriver.aFeatures;
213 break;
214 case 1:
215 pRet = &rDriver.aProperties;
216 break;
217 case 2:
218 pRet = &rDriver.aMetaData;
219 break;
220 }
221 sOldPattern = rPattern;
222 }
223 } // for(;aIter != aEnd;++aIter)
224 if ( pRet == nullptr )
225 {
226 static const ::comphelper::NamedValueCollection s_sEmpty;
227 pRet = &s_sEmpty;
228 }
229 return *pRet;
230 }
231
getURLs() const232 uno::Sequence< OUString > DriversConfig::getURLs() const
233 {
234 const TInstalledDrivers& rDrivers = m_aNode->getInstalledDrivers(m_xORB);
235 return comphelper::mapKeysToSequence(rDrivers);
236 }
237
238 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
239