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);
150 q_dbus_message_iter_next(&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);
265 q_dbus_message_iter_next(&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);
291 q_dbus_message_iter_next(&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;
310 q_dbus_message_iter_recurse(&iterator, &sub);
311 q_dbus_message_iter_next(&iterator);
312 int len;
313 char* data;
314 q_dbus_message_iter_get_fixed_array(&sub,&data,&len);
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
360 q_dbus_message_iter_recurse(&iterator, &d->iterator);
361 q_dbus_message_iter_next(&iterator);
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
398 q_dbus_message_iter_next(&iterator);
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()
QDBusDemarshaller * endMap()
QDBusDemarshaller * beginMap()
QDBusDemarshaller * parent
QDBusArgument::ElementType currentType()
#define DBUS_TYPE_SIGNATURE
#define DBUS_TYPE_OBJECT_PATH
#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
#define DBUS_TYPE_STRING
#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