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
qdbusdemarshaller.cpp
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:critical reason:data-parser
4
7
8#include <memory>
9
10#include <stdlib.h>
11
12QT_BEGIN_NAMESPACE
13
14template <typename T>
15static inline T qIterGet(DBusMessageIter *it)
16{
17 // Use a union of expected and largest type q_dbus_message_iter_get_basic
18 // will return to ensure reading the wrong basic type does not result in
19 // stack overwrite
20 union {
21 // The value to be extracted
22 T t;
23 // Largest type that q_dbus_message_iter_get_basic will return
24 // according to dbus_message_iter_get_basic API documentation
25 dbus_uint64_t maxValue;
26 // A pointer to ensure no stack overwrite in case there is a platform
27 // where sizeof(void*) > sizeof(dbus_uint64_t)
28 void* ptr;
29 } value;
30
31 // Initialize the value in case a narrower type is extracted to it.
32 // Note that the result of extracting a narrower type in place of a wider
33 // one and vice-versa will be platform-dependent.
34 value.t = T();
35
36 q_dbus_message_iter_get_basic(it, &value);
37 q_dbus_message_iter_next(it);
38 return value.t;
39}
40
44
46{
47 char *sig = q_dbus_message_iter_get_signature(&iterator);
48 QString retval = QString::fromUtf8(sig);
49 q_dbus_free(sig);
50
51 return retval;
52}
53
55{
56 return qIterGet<uchar>(&iterator);
57}
58
60{
61 return bool(qIterGet<dbus_bool_t>(&iterator));
62}
63
65{
66 return qIterGet<dbus_uint16_t>(&iterator);
67}
68
70{
71 return qIterGet<dbus_int16_t>(&iterator);
72}
73
75{
76 return qIterGet<dbus_int32_t>(&iterator);
77}
78
80{
81 return qIterGet<dbus_uint32_t>(&iterator);
82}
83
85{
86 return qIterGet<qlonglong>(&iterator);
87}
88
90{
91 return qIterGet<qulonglong>(&iterator);
92}
93
95{
96 return qIterGet<double>(&iterator);
97}
98
99inline QString QDBusDemarshaller::toStringUnchecked()
100{
101 return QString::fromUtf8(qIterGet<char *>(&iterator));
102}
103
105{
107 return toStringUnchecked();
108 else
109 return QString();
110}
111
112inline QDBusObjectPath QDBusDemarshaller::toObjectPathUnchecked()
113 {
114 return QDBusObjectPath(QString::fromUtf8(qIterGet<char *>(&iterator)));
115 }
116
118{
120 return toObjectPathUnchecked();
121 else
122 return QDBusObjectPath();
123}
124
125inline QDBusSignature QDBusDemarshaller::toSignatureUnchecked()
126 {
127 return QDBusSignature(QString::fromUtf8(qIterGet<char *>(&iterator)));
128 }
129
131{
133 return toSignatureUnchecked();
134 else
135 return QDBusSignature();
136}
137
138inline QDBusUnixFileDescriptor QDBusDemarshaller::toUnixFileDescriptor()
139{
140 QDBusUnixFileDescriptor fd;
141 fd.giveFileDescriptor(qIterGet<dbus_int32_t>(&iterator));
142 return fd;
143}
144
146{
147 QDBusDemarshaller sub(capabilities);
148 sub.message = q_dbus_message_ref(message);
149 q_dbus_message_iter_recurse(&iterator, &sub.iterator);
151
152 return QDBusVariant( sub.toVariantInternal() );
153}
154
155QDBusArgument::ElementType QDBusDemarshaller::currentType()
156{
157 switch (q_dbus_message_iter_get_arg_type(&iterator)) {
158 case DBUS_TYPE_BYTE:
159 case DBUS_TYPE_INT16:
160 case DBUS_TYPE_UINT16:
161 case DBUS_TYPE_INT32:
162 case DBUS_TYPE_UINT32:
163 case DBUS_TYPE_INT64:
164 case DBUS_TYPE_UINT64:
166 case DBUS_TYPE_DOUBLE:
167 case DBUS_TYPE_STRING:
170 return QDBusArgument::BasicType;
171
173 return QDBusArgument::VariantType;
174
175 case DBUS_TYPE_ARRAY:
176 switch (q_dbus_message_iter_get_element_type(&iterator)) {
177 case DBUS_TYPE_BYTE:
178 case DBUS_TYPE_STRING:
179 // QByteArray and QStringList
180 return QDBusArgument::BasicType;
182 return QDBusArgument::MapType;
183 default:
184 return QDBusArgument::ArrayType;
185 }
186
187 case DBUS_TYPE_STRUCT:
188 return QDBusArgument::StructureType;
190 return QDBusArgument::MapEntryType;
191
193 return capabilities & QDBusConnection::UnixFileDescriptorPassing ?
194 QDBusArgument::BasicType : QDBusArgument::UnknownType;
195
197 return QDBusArgument::UnknownType;
198
199// default:
200// qWarning("QDBusDemarshaller: Found unknown D-Bus type %d '%c'",
201// q_dbus_message_iter_get_arg_type(&iterator),
202// q_dbus_message_iter_get_arg_type(&iterator));
203 }
204 return QDBusArgument::UnknownType;
205}
206
208{
209 switch (q_dbus_message_iter_get_arg_type(&iterator)) {
210 case DBUS_TYPE_BYTE:
211 return QVariant::fromValue(toByte());
212 case DBUS_TYPE_INT16:
213 return QVariant::fromValue(toShort());
214 case DBUS_TYPE_UINT16:
215 return QVariant::fromValue(toUShort());
216 case DBUS_TYPE_INT32:
217 return toInt();
218 case DBUS_TYPE_UINT32:
219 return toUInt();
220 case DBUS_TYPE_DOUBLE:
221 return toDouble();
223 return toBool();
224 case DBUS_TYPE_INT64:
225 return toLongLong();
226 case DBUS_TYPE_UINT64:
227 return toULongLong();
228 case DBUS_TYPE_STRING:
229 return toStringUnchecked();
231 return QVariant::fromValue(toObjectPathUnchecked());
233 return QVariant::fromValue(toSignatureUnchecked());
235 return QVariant::fromValue(toVariant());
236
237 case DBUS_TYPE_ARRAY:
238 switch (q_dbus_message_iter_get_element_type(&iterator)) {
239 case DBUS_TYPE_BYTE:
240 // QByteArray
241 return toByteArrayUnchecked();
242 case DBUS_TYPE_STRING:
243 return toStringListUnchecked();
245 return QVariant::fromValue(duplicate());
246
247 default:
248 return QVariant::fromValue(duplicate());
249 }
250
251 case DBUS_TYPE_STRUCT:
252 return QVariant::fromValue(duplicate());
253
255 if (capabilities & QDBusConnection::UnixFileDescriptorPassing)
256 return QVariant::fromValue(toUnixFileDescriptor());
257 Q_FALLTHROUGH();
258
259 default:
260// qWarning("QDBusDemarshaller: Found unknown D-Bus type %d '%c'",
261// q_dbus_message_iter_get_arg_type(&iterator),
262// q_dbus_message_iter_get_arg_type(&iterator));
263 char *ptr = nullptr;
264 ptr += q_dbus_message_iter_get_arg_type(&iterator);
266
267 // I hope you never dereference this pointer!
268 return QVariant::fromValue<void *>(ptr);
269 };
270}
271
273{
274 const int type = q_dbus_message_iter_get_arg_type(&iterator);
275 switch (type) {
276 case DBUS_TYPE_STRING: //FALLTHROUGH
277 case DBUS_TYPE_OBJECT_PATH: //FALLTHROUGH
279 return true;
280 default:
281 return false;
282 }
283}
284
285QStringList QDBusDemarshaller::toStringListUnchecked()
286{
287 QStringList list;
288
289 QDBusDemarshaller sub(capabilities);
290 q_dbus_message_iter_recurse(&iterator, &sub.iterator);
292 while (!sub.atEnd())
293 list.append(sub.toStringUnchecked());
294
295 return list;
296}
297
299{
300 if (q_dbus_message_iter_get_arg_type(&iterator) == DBUS_TYPE_ARRAY
301 && q_dbus_message_iter_get_element_type(&iterator) == DBUS_TYPE_STRING)
302 return toStringListUnchecked();
303 else
304 return QStringList();
305}
306
307QByteArray QDBusDemarshaller::toByteArrayUnchecked()
308{
309 DBusMessageIter sub;
312 int len;
313 char* data;
315 return QByteArray(data,len);
316}
317
319{
320 if (q_dbus_message_iter_get_arg_type(&iterator) == DBUS_TYPE_ARRAY
321 && q_dbus_message_iter_get_element_type(&iterator) == DBUS_TYPE_BYTE) {
322 return toByteArrayUnchecked();
323 }
324 return QByteArray();
325}
326
328{
329 // dbus_message_iter_has_next is broken if the list has one single element
330 return q_dbus_message_iter_get_arg_type(&iterator) == DBUS_TYPE_INVALID;
331}
332
337
342
347
352
354{
355 QDBusDemarshaller *d = new QDBusDemarshaller(capabilities);
356 d->parent = this;
357 d->message = q_dbus_message_ref(message);
358
359 // recurse
362 return d;
363}
364
369
374
376{
377 return endCommon();
378}
379
384
386{
387 QDBusDemarshaller *retval = parent;
388 delete this;
389 return retval;
390}
391
393{
394 std::unique_ptr<QDBusDemarshaller> d(new QDBusDemarshaller(capabilities));
395 d->iterator = iterator;
396 d->message = q_dbus_message_ref(message);
397
399 return QDBusArgumentPrivate::create(d.release());
400}
401
402QT_END_NAMESPACE
QDBusDemarshaller * beginArray()
QDBusArgument duplicate()
QDBusDemarshaller * endArray()
QDBusDemarshaller * endStructure()
QDBusDemarshaller * endMapEntry()
QDBusSignature toSignature()
QDBusUnixFileDescriptor toUnixFileDescriptor()
QDBusObjectPath toObjectPath()
QDBusDemarshaller * beginStructure()
QDBusDemarshaller * endCommon()
QDBusDemarshaller * beginMapEntry()
QDBusDemarshaller * beginCommon()
DBusMessageIter iterator
QDBusDemarshaller * endMap()
QDBusDemarshaller * beginMap()
QDBusDemarshaller * parent
QDBusArgument::ElementType currentType()
quint32 dbus_uint32_t
#define DBUS_TYPE_SIGNATURE
#define DBUS_TYPE_OBJECT_PATH
qint16 dbus_int16_t
#define DBUS_TYPE_BYTE
#define DBUS_TYPE_INT16
#define DBUS_TYPE_VARIANT
#define DBUS_TYPE_INT32
#define DBUS_TYPE_UNIX_FD
#define DBUS_TYPE_BOOLEAN
quint16 dbus_uint16_t
dbus_uint32_t dbus_bool_t
#define DBUS_TYPE_STRING
qint32 dbus_int32_t
#define DBUS_TYPE_ARRAY
#define DBUS_TYPE_INVALID
#define DBUS_TYPE_INT64
#define DBUS_TYPE_DOUBLE
#define DBUS_TYPE_UINT64
#define DBUS_TYPE_DICT_ENTRY
#define DBUS_TYPE_UINT16
#define DBUS_TYPE_STRUCT
#define DBUS_TYPE_UINT32
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return dbus_message_iter_recurse
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void dbus_message_iter_get_fixed_array
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return dbus_message_iter_next