1// Copyright (C) 2022 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:critical reason:data-parser
4
5#ifndef QSTRINGCONVERTER_BASE_H
6#define QSTRINGCONVERTER_BASE_H
7
8#if 0
9// QStringConverter(Base) class are handled in qstringconverter
10#pragma qt_sync_stop_processing
11#endif
12
13#include <optional>
14
15#include <QtCore/qglobal.h> // QT_{BEGIN,END}_NAMESPACE
16#include <QtCore/qflags.h> // Q_DECLARE_FLAGS
17#include <QtCore/qcontainerfwd.h>
18#include <QtCore/qstringfwd.h>
19
20#include <cstring>
21
22QT_BEGIN_NAMESPACE
23
24class QByteArrayView;
25class QChar;
26class QByteArrayView;
27class QStringView;
28
29#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(Q_QDOC) && !defined(QT_BOOTSTRAPPED)
30class QStringConverterBase
31#else
32class QStringConverter
33#endif
34{
35public:
36 enum class Flag {
37 Default = 0,
38 Stateless = 0x1,
39 ConvertInvalidToNull = 0x2,
40 WriteBom = 0x4,
41 ConvertInitialBom = 0x8,
42 UsesIcu = 0x10,
43 };
44 Q_DECLARE_FLAGS(Flags, Flag)
45
46 struct State {
47 constexpr State(Flags f = Flag::Default) noexcept
48 : flags(f), state_data{0, 0, 0, 0} {}
49 ~State() { clear(); }
50
51 State(State &&other) noexcept
52 : flags(other.flags),
53 remainingChars(other.remainingChars),
54 invalidChars(other.invalidChars),
55 state_data{other.state_data[0], other.state_data[1],
56 other.state_data[2], other.state_data[3]},
57 clearFn(other.clearFn)
58 { other.clearFn = nullptr; }
59 State &operator=(State &&other) noexcept
60 {
61 clear();
62 flags = other.flags;
63 remainingChars = other.remainingChars;
64 invalidChars = other.invalidChars;
65 std::memmove(dest: state_data, src: other.state_data, n: sizeof state_data); // self-assignment-safe
66 clearFn = other.clearFn;
67 other.clearFn = nullptr;
68 return *this;
69 }
70 Q_CORE_EXPORT void clear() noexcept;
71 Q_CORE_EXPORT void reset() noexcept;
72
73 Flags flags;
74 int internalState = 0;
75 qsizetype remainingChars = 0;
76 qsizetype invalidChars = 0;
77
78 union {
79 uint state_data[4];
80 void *d[2];
81 };
82 using ClearDataFn = void (*)(State *) noexcept;
83 ClearDataFn clearFn = nullptr;
84 private:
85 Q_DISABLE_COPY(State)
86 };
87
88#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(Q_QDOC) && !defined(QT_BOOTSTRAPPED)
89protected:
90 QStringConverterBase() = default;
91 ~QStringConverterBase() = default;
92 QStringConverterBase(QStringConverterBase &&) = default;
93 QStringConverterBase &operator=(QStringConverterBase &&) = default;
94};
95
96class QStringConverter : public QStringConverterBase
97{
98public:
99#endif // Qt 6 compat for QStringConverterBase
100
101 enum Encoding {
102 Utf8,
103#ifndef QT_BOOTSTRAPPED
104 Utf16,
105 Utf16LE,
106 Utf16BE,
107 Utf32,
108 Utf32LE,
109 Utf32BE,
110#endif
111 Latin1,
112 System,
113 LastEncoding = System
114 };
115
116protected:
117
118 struct Interface
119 {
120 using DecoderFn = QChar * (*)(QChar *out, QByteArrayView in, State *state);
121 using LengthFn = qsizetype (*)(qsizetype inLength);
122 using EncoderFn = char * (*)(char *out, QStringView in, State *state);
123 const char *name = nullptr;
124 DecoderFn toUtf16 = nullptr;
125 LengthFn toUtf16Len = nullptr;
126 EncoderFn fromUtf16 = nullptr;
127 LengthFn fromUtf16Len = nullptr;
128 };
129
130 constexpr QStringConverter() noexcept
131 : iface(nullptr)
132 {}
133 constexpr explicit QStringConverter(Encoding encoding, Flags f)
134 : iface(&encodingInterfaces[qsizetype(encoding)]), state(f)
135 {}
136 constexpr explicit QStringConverter(const Interface *i) noexcept
137 : iface(i)
138 {}
139#if QT_CORE_REMOVED_SINCE(6, 8)
140 Q_CORE_EXPORT explicit QStringConverter(const char *name, Flags f);
141#endif
142 Q_CORE_EXPORT explicit QStringConverter(QAnyStringView name, Flags f);
143
144
145 ~QStringConverter() = default;
146
147public:
148 QStringConverter(QStringConverter &&) = default;
149 QStringConverter &operator=(QStringConverter &&) = default;
150
151 bool isValid() const noexcept { return iface != nullptr; }
152
153 void resetState() noexcept
154 {
155 state.reset();
156 }
157 bool hasError() const noexcept { return state.invalidChars != 0; }
158
159 Q_CORE_EXPORT const char *name() const noexcept;
160
161#if QT_CORE_REMOVED_SINCE(6, 8)
162 Q_CORE_EXPORT static std::optional<Encoding> encodingForName(const char *name) noexcept;
163#endif
164 Q_CORE_EXPORT static std::optional<Encoding> encodingForName(QAnyStringView name) noexcept;
165 Q_DECL_PURE_FUNCTION Q_CORE_EXPORT static const char *nameForEncoding(Encoding e) noexcept;
166 Q_CORE_EXPORT static std::optional<Encoding>
167 encodingForData(QByteArrayView data, char16_t expectedFirstCharacter = 0) noexcept;
168 Q_CORE_EXPORT static std::optional<Encoding> encodingForHtml(QByteArrayView data);
169
170 Q_CORE_EXPORT static QStringList availableCodecs();
171
172protected:
173 const Interface *iface;
174 State state;
175private:
176 Q_CORE_EXPORT static const Interface encodingInterfaces[Encoding::LastEncoding + 1];
177};
178
179Q_DECLARE_OPERATORS_FOR_FLAGS(QStringConverter::Flags)
180
181QT_END_NAMESPACE
182
183#endif
184

source code of qtbase/src/corelib/text/qstringconverter_base.h