Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qqmlpreviewfileloader.cpp
Go to the documentation of this file.
1// Copyright (C) 2018 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant
4
7
8#include <QtQml/qqmlfile.h>
9
10#include <QtCore/qlibraryinfo.h>
11#include <QtCore/qstandardpaths.h>
12
14
15QQmlPreviewFileLoader::QQmlPreviewFileLoader(QQmlPreviewServiceImpl *service) : m_service(service)
16{
17 // Exclude some resource paths used by Qt itself. There is no point in loading those from the
18 // client as the client will not have the files (or even worse, it may have different ones).
19 m_blacklist.blacklist(":/qt-project.org");
20 m_blacklist.blacklist(":/QtQuick/Controls/Styles");
21 m_blacklist.blacklist(":/ExtrasImports/QtQuick/Controls/Styles");
22
23 // Target specific configuration should not replaced with files from the host.
24 m_blacklist.blacklist("/etc");
25
26 for (int loc = QLibraryInfo::PrefixPath; loc < QLibraryInfo::TestsPath; ++loc) {
27 m_blacklist.blacklist(QLibraryInfo::path(
28 static_cast<QLibraryInfo::LibraryPath>(loc)));
29 }
30 m_blacklist.blacklist(QLibraryInfo::path(QLibraryInfo::SettingsPath));
31
32 static const QStandardPaths::StandardLocation blackListLocations[] = {
33 QStandardPaths::CacheLocation,
34 QStandardPaths::GenericDataLocation,
35 QStandardPaths::ConfigLocation,
36 QStandardPaths::GenericCacheLocation,
37 QStandardPaths::GenericConfigLocation,
38 QStandardPaths::AppDataLocation,
39 QStandardPaths::AppConfigLocation
40 };
41
42 for (auto locationType : blackListLocations) {
43 const QStringList locations = QStandardPaths::standardLocations(locationType);
44 for (const QString &location : locations)
45 m_blacklist.blacklist(location);
46 }
47
48 m_blacklist.whitelist(QLibraryInfo::path(QLibraryInfo::TestsPath));
49
50 connect(this, &QQmlPreviewFileLoader::request, service, &QQmlPreviewServiceImpl::forwardRequest,
51 Qt::DirectConnection);
52 connect(service, &QQmlPreviewServiceImpl::directory, this, &QQmlPreviewFileLoader::directory);
53 connect(service, &QQmlPreviewServiceImpl::file, this, &QQmlPreviewFileLoader::file);
54 connect(service, &QQmlPreviewServiceImpl::error, this, &QQmlPreviewFileLoader::error);
55 connect(service, &QQmlPreviewServiceImpl::clearCache, this, &QQmlPreviewFileLoader::clearCache);
56 moveToThread(&m_thread);
57 m_thread.start();
58}
59
60QQmlPreviewFileLoader::~QQmlPreviewFileLoader() {
61 m_thread.quit();
62 m_thread.wait();
63}
64
66{
67 QMutexLocker locker(&m_contentMutex);
68 m_path = path;
69
70 auto fileIterator = m_fileCache.constFind(path);
71 if (fileIterator != m_fileCache.constEnd()) {
72 m_result = File;
73 m_contents = *fileIterator;
74 m_entries.clear();
75 return m_result;
76 }
77
78 auto dirIterator = m_directoryCache.constFind(path);
79 if (dirIterator != m_directoryCache.constEnd()) {
80 m_result = Directory;
81 m_contents.clear();
82 m_entries = *dirIterator;
83 return m_result;
84 }
85
86 m_result = Unknown;
87 m_entries.clear();
88 m_contents.clear();
89 emit request(path);
90 m_waitCondition.wait(&m_contentMutex);
91 return m_result;
92}
93
95{
96 QMutexLocker locker(&m_contentMutex);
97 return m_contents;
98}
99
101{
102 QMutexLocker locker(&m_contentMutex);
103 return m_entries;
104}
105
106void QQmlPreviewFileLoader::whitelist(const QUrl &url)
107{
108 const QString path = QQmlFile::urlToLocalFileOrQrc(url);
109 if (!path.isEmpty()) {
110 QMutexLocker locker(&m_contentMutex);
111 m_blacklist.whitelist(path);
112 }
113}
114
115bool QQmlPreviewFileLoader::isBlacklisted(const QString &path)
116{
117 QMutexLocker locker(&m_contentMutex);
118 return m_blacklist.isBlacklisted(path);
119}
120
121void QQmlPreviewFileLoader::file(const QString &path, const QByteArray &contents)
122{
123 QMutexLocker locker(&m_contentMutex);
124 m_blacklist.whitelist(path);
125 m_fileCache[path] = contents;
126 if (path == m_path) {
127 m_contents = contents;
128 m_result = File;
129 m_waitCondition.wakeOne();
130 }
131}
132
133void QQmlPreviewFileLoader::directory(const QString &path, const QStringList &entries)
134{
135 QMutexLocker locker(&m_contentMutex);
136 m_blacklist.whitelist(path);
137 m_directoryCache[path] = entries;
138 if (path == m_path) {
139 m_entries = entries;
140 m_result = Directory;
141 m_waitCondition.wakeOne();
142 }
143}
144
145void QQmlPreviewFileLoader::error(const QString &path)
146{
147 QMutexLocker locker(&m_contentMutex);
148 m_blacklist.blacklist(path);
149 if (path == m_path) {
150 m_result = Fallback;
151 m_waitCondition.wakeOne();
152 }
153}
154
155void QQmlPreviewFileLoader::clearCache()
156{
157 QMutexLocker locker(&m_contentMutex);
158 m_fileCache.clear();
159 m_directoryCache.clear();
160}
161
162QT_END_NAMESPACE
163
164#include "moc_qqmlpreviewfileloader.cpp"
Result load(const QString &file)
bool isBlacklisted(const QString &file)
void whitelist(const QUrl &url)
Combined button and popup list for selecting options.