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
qmimemagicrule_p.h
Go to the documentation of this file.
1// Copyright (C) 2016 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 reason:default
4
5#ifndef QMIMEMAGICRULE_P_H
6#define QMIMEMAGICRULE_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QtCore/private/qglobal_p.h>
20
22
23#include <QtCore/qbytearray.h>
24#include <QtCore/qscopedpointer.h>
25#include <QtCore/qlist.h>
26#if QT_CONFIG(regularexpression)
27#include <QtCore/qregularexpression.h>
28#include <QtCore/qstring.h>
29
30#include <optional>
31#endif
32
33QT_BEGIN_NAMESPACE
34
35// The data that magic rules are matched against
36class QMimeMagicData
37{
38public:
39 explicit QMimeMagicData(const QByteArray &data) : m_data(data) {}
40 QMimeMagicData(QByteArray &&) = delete; // would dangle
41
42 const QByteArray &bytes() const { return m_data; }
43#if QT_CONFIG(regularexpression)
44 // The first \a size bytes, at most bytes().size(), decoded as Latin-1
45 QStringView decodedLatin1(qsizetype size) const
46 {
47 size = qMin(size, m_data.size());
48 // Shared by all the regex rules, and only as long as they need: the data can be huge
49 if (m_latin1.size() < size)
50 m_latin1 = QString::fromLatin1(QByteArrayView(m_data).first(size));
51 return QStringView(m_latin1).first(size);
52 }
53#endif
54
55private:
56 const QByteArray &m_data;
57#if QT_CONFIG(regularexpression)
58 mutable QString m_latin1;
59#endif
60};
61
63{
64public:
65 // Regex is an extension used by the tika database, not in the shared-mime-info spec
67 // Only Qt's own database may use Regex: elsewhere it wouldn't work with a mime.cache
68 enum class RegexRules { Rejected, Allowed };
69 // Maximum nesting depth of magic rules that is followed, both for <match>
70 // elements in XML and for matchlets in mime.cache. The deepest nesting in
71 // the shared-mime-info database is 5, so this leaves ample headroom while
72 // keeping recursion bounded for corrupt or hostile input.
73 static constexpr int MaxRecursionDepth = 50;
74
75 QMimeMagicRule(const QString &typeStr, const QByteArray &value, const QString &offsets,
76 const QByteArray &mask, RegexRules regexRules, QString *errorString);
77
78 void swap(QMimeMagicRule &other) noexcept
79 {
80 qSwap(m_type, other.m_type);
81 qSwap(m_value, other.m_value);
82 qSwap(m_startPos, other.m_startPos);
83 qSwap(m_endPos, other.m_endPos);
84 qSwap(m_mask, other.m_mask);
85 qSwap(m_pattern, other.m_pattern);
86 qSwap(m_number, other.m_number);
87 qSwap(m_numberMask, other.m_numberMask);
88#if QT_CONFIG(regularexpression)
89 qSwap(m_regExp, other.m_regExp);
90#endif
91 qSwap(m_matchFunction, other.m_matchFunction);
92 }
93
94 bool operator==(const QMimeMagicRule &other) const;
95
96 Type type() const { return m_type; }
97 QByteArray value() const { return m_value; }
98 int startPos() const { return m_startPos; }
99 int endPos() const { return m_endPos; }
100 QByteArray mask() const;
101
102 bool isValid() const { return m_matchFunction != nullptr; }
103
104 bool matches(const QMimeMagicData &data, int depth = MaxRecursionDepth) const;
105
107
108 static Type type(const QByteArray &type);
109 static QByteArray typeName(Type type);
110
111 static bool matchSubstring(const char *dataPtr, qsizetype dataSize, quint64 rangeStart,
112 quint64 rangeLength, quint64 valueLength, const char *valueData,
113 const char *mask);
114
115private:
116 Type m_type;
117 QByteArray m_value;
118 int m_startPos;
119 int m_endPos;
120 QByteArray m_mask;
121
122 QByteArray m_pattern;
123 quint32 m_number;
124 quint32 m_numberMask;
125#if QT_CONFIG(regularexpression)
126 std::optional<QRegularExpression> m_regExp; // only for Regex rules: it allocates
127#endif
128
129 typedef bool (QMimeMagicRule::*MatchFunction)(const QMimeMagicData &data) const;
130 MatchFunction m_matchFunction;
131
132private:
133 // match functions
134 bool matchString(const QMimeMagicData &magicData) const;
135 template <typename T>
136 bool matchNumber(const QMimeMagicData &magicData) const;
137 bool matchRegExp(const QMimeMagicData &magicData) const;
138};
139Q_DECLARE_SHARED(QMimeMagicRule)
140
141QT_END_NAMESPACE
142
143#endif // QMIMEMAGICRULE_H
int startPos() const
static QByteArray typeName(Type type)
QByteArray mask() const
QList< QMimeMagicRule > m_subMatches
static Type type(const QByteArray &type)
void swap(QMimeMagicRule &other) noexcept
bool isValid() const
static constexpr int MaxRecursionDepth
static bool matchSubstring(const char *dataPtr, qsizetype dataSize, quint64 rangeStart, quint64 rangeLength, quint64 valueLength, const char *valueData, const char *mask)
bool matches(const QMimeMagicData &data, int depth=MaxRecursionDepth) const
Type type() const
bool operator==(const QMimeMagicRule &other) const
int endPos() const
QByteArray value() const
QMimeMagicRule(const QString &typeStr, const QByteArray &value, const QString &offsets, const QByteArray &mask, RegexRules regexRules, QString *errorString)
Combined button and popup list for selecting options.
QT_REQUIRE_CONFIG(mimetype)
static QByteArray makePattern(const QByteArray &value)
static constexpr qsizetype RegExpLookAhead
static constexpr auto magicRuleTypes