Coverage Report

Created: 2025-07-16 07:53

/usr/include/QtCore/qfile.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright (C) 2020 The Qt Company Ltd.
2
// Copyright (C) 2016 Intel Corporation.
3
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
// Qt-Security score:significant reason:default
5
6
#ifndef QFILE_H
7
#define QFILE_H
8
9
#include <QtCore/qfiledevice.h>
10
#include <QtCore/qstring.h>
11
#include <stdio.h>
12
13
#if QT_CONFIG(cxx17_filesystem)
14
#include <filesystem>
15
#elif defined(Q_QDOC)
16
namespace std {
17
    namespace filesystem {
18
        class path {
19
        };
20
    };
21
};
22
#endif
23
24
#ifdef open
25
#error qfile.h must be included before any header file that defines open
26
#endif
27
28
QT_BEGIN_NAMESPACE
29
30
#if defined(Q_OS_WIN) || defined(Q_QDOC)
31
32
#if QT_DEPRECATED_SINCE(6,6)
33
QT_DEPRECATED_VERSION_X_6_6("Use QNtfsPermissionCheckGuard RAII class instead.")
34
Q_CORE_EXPORT extern int qt_ntfs_permission_lookup;      // defined in qfilesystemengine_win.cpp
35
#endif
36
37
Q_CORE_EXPORT bool qEnableNtfsPermissionChecks() noexcept;
38
Q_CORE_EXPORT bool qDisableNtfsPermissionChecks() noexcept;
39
Q_CORE_EXPORT bool qAreNtfsPermissionChecksEnabled() noexcept;
40
41
class QNtfsPermissionCheckGuard
42
{
43
    Q_DISABLE_COPY_MOVE(QNtfsPermissionCheckGuard)
44
public:
45
    Q_NODISCARD_CTOR
46
    QNtfsPermissionCheckGuard()
47
    {
48
        qEnableNtfsPermissionChecks();
49
    }
50
51
    ~QNtfsPermissionCheckGuard()
52
    {
53
        qDisableNtfsPermissionChecks();
54
    }
55
};
56
#endif // Q_OS_WIN
57
58
#if QT_CONFIG(cxx17_filesystem)
59
namespace QtPrivate {
60
inline QString fromFilesystemPath(const std::filesystem::path &path)
61
0
{
62
0
    // we could use QAnyStringView, but this allows us to statically determine
63
0
    // the correct toString() call
64
0
    using View = std::conditional_t<sizeof(std::filesystem::path::value_type) == sizeof(char16_t),
65
0
            QStringView, QUtf8StringView>;
66
0
    return View(path.native()).toString();
67
0
}
68
69
inline std::filesystem::path toFilesystemPath(const QString &path)
70
0
{
71
0
    if constexpr (sizeof(std::filesystem::path::value_type) == sizeof(char16_t))
72
0
        return std::u16string_view(QStringView(path));
73
0
    else
74
0
        return path.toStdString();
75
0
}
76
77
// Both std::filesystem::path and QString (without QT_NO_CAST_FROM_ASCII) can be implicitly
78
// constructed from string literals so we force the std::fs::path parameter to only
79
// accept std::fs::path with no implicit conversions.
80
template<typename T>
81
using ForceFilesystemPath = typename std::enable_if_t<std::is_same_v<std::filesystem::path, T>, int>;
82
}
83
#endif // QT_CONFIG(cxx17_filesystem)
84
85
class QTemporaryFile;
86
class QFilePrivate;
87
88
// ### Qt 7: remove this, and make constructors always explicit.
89
#if (QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)) || defined(QT_EXPLICIT_QFILE_CONSTRUCTION_FROM_PATH)
90
#  define QFILE_MAYBE_EXPLICIT explicit
91
#else
92
#  define QFILE_MAYBE_EXPLICIT Q_IMPLICIT
93
#endif
94
95
class Q_CORE_EXPORT QFile : public QFileDevice
96
{
97
#ifndef QT_NO_QOBJECT
98
    Q_OBJECT
99
#endif
100
    Q_DECLARE_PRIVATE(QFile)
101
102
public:
103
    QFile();
104
    QFILE_MAYBE_EXPLICIT QFile(const QString &name);
105
#ifdef Q_QDOC
106
    QFILE_MAYBE_EXPLICIT QFile(const std::filesystem::path &name);
107
#elif QT_CONFIG(cxx17_filesystem)
108
    template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
109
    QFILE_MAYBE_EXPLICIT QFile(const T &name) : QFile(QtPrivate::fromFilesystemPath(name))
110
    {
111
    }
112
#endif // QT_CONFIG(cxx17_filesystem)
113
114
#ifndef QT_NO_QOBJECT
115
    explicit QFile(QObject *parent);
116
    QFile(const QString &name, QObject *parent);
117
118
#ifdef Q_QDOC
119
    QFile(const std::filesystem::path &path, QObject *parent);
120
#elif QT_CONFIG(cxx17_filesystem)
121
    template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
122
    QFile(const T &path, QObject *parent) : QFile(QtPrivate::fromFilesystemPath(path), parent)
123
    {
124
    }
125
#endif // QT_CONFIG(cxx17_filesystem)
126
#endif // !QT_NO_QOBJECT
127
    ~QFile();
128
129
    QString fileName() const override;
130
#if QT_CONFIG(cxx17_filesystem) || defined(Q_QDOC)
131
    std::filesystem::path filesystemFileName() const
132
0
    { return QtPrivate::toFilesystemPath(fileName()); }
133
#endif
134
    void setFileName(const QString &name);
135
#ifdef Q_QDOC
136
    void setFileName(const std::filesystem::path &name);
137
#elif QT_CONFIG(cxx17_filesystem)
138
    template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
139
    void setFileName(const T &name)
140
    {
141
        setFileName(QtPrivate::fromFilesystemPath(name));
142
    }
143
#endif // QT_CONFIG(cxx17_filesystem)
144
145
#if defined(Q_OS_DARWIN)
146
    // Mac always expects filenames in UTF-8... and decomposed...
147
    static inline QByteArray encodeName(const QString &fileName)
148
    {
149
        return fileName.normalized(QString::NormalizationForm_D).toUtf8();
150
    }
151
    static QString decodeName(const QByteArray &localFileName)
152
    {
153
        // note: duplicated in qglobal.cpp (qEnvironmentVariable)
154
        return QString::fromUtf8(localFileName).normalized(QString::NormalizationForm_C);
155
    }
156
    static inline QString decodeName(const char *localFileName)
157
    {
158
        return QString::fromUtf8(localFileName).normalized(QString::NormalizationForm_C);
159
    }
160
#else
161
    static inline QByteArray encodeName(const QString &fileName)
162
    {
163
        return fileName.toLocal8Bit();
164
    }
165
    static QString decodeName(const QByteArray &localFileName)
166
    {
167
        return QString::fromLocal8Bit(localFileName);
168
    }
169
    static inline QString decodeName(const char *localFileName)
170
    {
171
        return QString::fromLocal8Bit(localFileName);
172
    }
173
#endif
174
175
    bool exists() const;
176
    static bool exists(const QString &fileName);
177
#ifdef Q_QDOC
178
    static bool exists(const std::filesystem::path &fileName);
179
#elif QT_CONFIG(cxx17_filesystem)
180
    template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
181
    static bool exists(const T &fileName)
182
    {
183
        return exists(QtPrivate::fromFilesystemPath(fileName));
184
    }
185
#endif // QT_CONFIG(cxx17_filesystem)
186
187
    QString symLinkTarget() const;
188
    static QString symLinkTarget(const QString &fileName);
189
#ifdef Q_QDOC
190
    std::filesystem::path filesystemSymLinkTarget() const;
191
    static std::filesystem::path filesystemSymLinkTarget(const std::filesystem::path &fileName);
192
#elif QT_CONFIG(cxx17_filesystem)
193
    std::filesystem::path filesystemSymLinkTarget() const
194
0
    {
195
0
        return QtPrivate::toFilesystemPath(symLinkTarget());
196
0
    }
197
    template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
198
    static std::filesystem::path filesystemSymLinkTarget(const T &fileName)
199
    {
200
        return QtPrivate::toFilesystemPath(symLinkTarget(QtPrivate::fromFilesystemPath(fileName)));
201
    }
202
#endif // QT_CONFIG(cxx17_filesystem)
203
204
    bool remove();
205
    static bool remove(const QString &fileName);
206
#ifdef Q_QDOC
207
    static bool remove(const std::filesystem::path &fileName);
208
#elif QT_CONFIG(cxx17_filesystem)
209
    template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
210
    static bool remove(const T &fileName)
211
    {
212
        return remove(QtPrivate::fromFilesystemPath(fileName));
213
    }
214
#endif // QT_CONFIG(cxx17_filesystem)
215
216
    static bool supportsMoveToTrash() Q_DECL_PURE_FUNCTION;
217
    bool moveToTrash();
218
    static bool moveToTrash(const QString &fileName, QString *pathInTrash = nullptr);
219
#ifdef Q_QDOC
220
    static bool moveToTrash(const std::filesystem::path &fileName, QString *pathInTrash = nullptr);
221
#elif QT_CONFIG(cxx17_filesystem)
222
    template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
223
    static bool moveToTrash(const T &fileName, QString *pathInTrash = nullptr)
224
    {
225
        return moveToTrash(QtPrivate::fromFilesystemPath(fileName), pathInTrash);
226
    }
227
#endif // QT_CONFIG(cxx17_filesystem)
228
229
    bool rename(const QString &newName);
230
    static bool rename(const QString &oldName, const QString &newName);
231
#ifdef Q_QDOC
232
    bool rename(const std::filesystem::path &newName);
233
    static bool rename(const std::filesystem::path &oldName,
234
                       const std::filesystem::path &newName);
235
#elif QT_CONFIG(cxx17_filesystem)
236
    template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
237
    bool rename(const T &newName)
238
    {
239
        return rename(QtPrivate::fromFilesystemPath(newName));
240
    }
241
    template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
242
    static bool rename(const T &oldName, const T &newName)
243
    {
244
        return rename(QtPrivate::fromFilesystemPath(oldName),
245
                      QtPrivate::fromFilesystemPath(newName));
246
    }
247
#endif // QT_CONFIG(cxx17_filesystem)
248
249
    bool link(const QString &newName);
250
    static bool link(const QString &fileName, const QString &newName);
251
#ifdef Q_QDOC
252
    bool link(const std::filesystem::path &newName);
253
    static bool link(const std::filesystem::path &fileName,
254
                     const std::filesystem::path &newName);
255
#elif QT_CONFIG(cxx17_filesystem)
256
    template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
257
    bool link(const T &newName)
258
    {
259
        return link(QtPrivate::fromFilesystemPath(newName));
260
    }
261
    template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
262
    static bool link(const T &fileName, const T &newName)
263
    {
264
        return link(QtPrivate::fromFilesystemPath(fileName),
265
                    QtPrivate::fromFilesystemPath(newName));
266
    }
267
#endif // QT_CONFIG(cxx17_filesystem)
268
269
#if QT_CONFIG(temporaryfile)
270
    bool copy(const QString &newName);
271
    static bool copy(const QString &fileName, const QString &newName);
272
#endif
273
#ifdef Q_QDOC
274
    bool copy(const std::filesystem::path &newName);
275
    static bool copy(const std::filesystem::path &fileName,
276
                     const std::filesystem::path &newName);
277
#elif QT_CONFIG(cxx17_filesystem) && QT_CONFIG(temporaryfile)
278
    template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
279
    bool copy(const T &newName)
280
    {
281
        return copy(QtPrivate::fromFilesystemPath(newName));
282
    }
283
    template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
284
    static bool copy(const T &fileName, const T &newName)
285
    {
286
        return copy(QtPrivate::fromFilesystemPath(fileName),
287
                    QtPrivate::fromFilesystemPath(newName));
288
    }
289
#endif // QT_CONFIG(cxx17_filesystem)
290
291
    QFILE_MAYBE_NODISCARD bool open(OpenMode flags) override;
292
    QFILE_MAYBE_NODISCARD bool open(OpenMode flags, Permissions permissions);
293
    QFILE_MAYBE_NODISCARD bool open(FILE *f, OpenMode ioFlags, FileHandleFlags handleFlags=DontCloseHandle);
294
    QFILE_MAYBE_NODISCARD bool open(int fd, OpenMode ioFlags, FileHandleFlags handleFlags=DontCloseHandle);
295
296
    qint64 size() const override;
297
298
    bool resize(qint64 sz) override;
299
    static bool resize(const QString &filename, qint64 sz);
300
301
    Permissions permissions() const override;
302
    static Permissions permissions(const QString &filename);
303
    bool setPermissions(Permissions permissionSpec) override;
304
    static bool setPermissions(const QString &filename, Permissions permissionSpec);
305
#ifdef Q_QDOC
306
    static Permissions permissions(const std::filesystem::path &filename);
307
    static bool setPermissions(const std::filesystem::path &filename, Permissions permissionSpec);
308
#elif QT_CONFIG(cxx17_filesystem)
309
    template<typename T,  QtPrivate::ForceFilesystemPath<T> = 0>
310
    static Permissions permissions(const T &filename)
311
    {
312
        return permissions(QtPrivate::fromFilesystemPath(filename));
313
    }
314
    template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
315
    static bool setPermissions(const T &filename, Permissions permissionSpec)
316
    {
317
        return setPermissions(QtPrivate::fromFilesystemPath(filename), permissionSpec);
318
    }
319
#endif // QT_CONFIG(cxx17_filesystem)
320
321
protected:
322
#ifdef QT_NO_QOBJECT
323
    QFile(QFilePrivate &dd);
324
#else
325
    QFile(QFilePrivate &dd, QObject *parent = nullptr);
326
#endif
327
328
private:
329
    friend class QTemporaryFile;
330
    Q_DISABLE_COPY(QFile)
331
};
332
333
QT_END_NAMESPACE
334
335
#endif // QFILE_H