1 /***************************************************************************
2 * Copyright (C) 2005-2019 by the Quassel Project *
3 * devel@quassel-irc.org *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) version 3. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
21 #include "serializers.h"
26 bool toVariant(QDataStream& stream, Quassel::Features features, QVariant& data)
29 if (!Serializers::deserialize(stream, features, content)) {
32 data = QVariant::fromValue<T>(content);
38 bool checkStreamValid(QDataStream &stream)
40 if (stream.status() != QDataStream::Ok) {
41 qWarning() << "Peer sent corrupt data";
48 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, QVariantList &data)
51 if (!deserialize(stream, features, size))
53 if (size > 4 * 1024 * 1024) {
54 qWarning() << "Peer sent too large QVariantList: " << size;
57 for (uint32_t i = 0; i < size; i++) {
59 if (!deserialize(stream, features, element))
63 return checkStreamValid(stream);
66 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, QVariantMap &data)
69 if (!deserialize(stream, features, size))
71 if (size > 4 * 1024 * 1024) {
72 qWarning() << "Peer sent too large QVariantMap: " << size;
75 for (uint32_t i = 0; i < size; i++) {
78 if (!deserialize(stream, features, key))
80 if (!deserialize(stream, features, value))
84 return checkStreamValid(stream);
87 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, QVariant &data)
89 Types::VariantType type;
91 if (!deserialize(stream, features, type))
93 if (!deserialize(stream, features, isNull))
95 if (type == Types::VariantType::UserType) {
97 if (!deserialize(stream, features, name))
99 while (name.length() > 0 && name.at(name.length() - 1) == 0)
101 if (!deserialize(stream, features, data, Types::fromName(name)))
104 if (!deserialize(stream, features, data, type))
107 return checkStreamValid(stream);
110 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, QVariant &data, Types::VariantType type)
113 case Types::VariantType::Void:
115 case Types::VariantType::Bool:
116 return toVariant<bool>(stream, features, data);
117 case Types::VariantType::Int:
118 return toVariant<int32_t>(stream, features, data);
119 case Types::VariantType::UInt:
120 return toVariant<uint32_t>(stream, features, data);
121 case Types::VariantType::QChar:
122 return toVariant<QChar>(stream, features, data);
123 case Types::VariantType::QVariantMap:
124 return toVariant<QVariantMap>(stream, features, data);
125 case Types::VariantType::QVariantList:
126 return toVariant<QVariantList>(stream, features, data);
127 case Types::VariantType::QString:
128 return toVariant<QString>(stream, features, data);
129 case Types::VariantType::QStringList:
130 return toVariant<QStringList>(stream, features, data);
131 case Types::VariantType::QByteArray:
132 return toVariant<QByteArray>(stream, features, data);
133 case Types::VariantType::QDate:
134 return toVariant<QDate>(stream, features, data);
135 case Types::VariantType::QTime:
136 return toVariant<QTime>(stream, features, data);
137 case Types::VariantType::QDateTime:
138 return toVariant<QDateTime>(stream, features, data);
139 case Types::VariantType::Long:
140 return toVariant<qlonglong>(stream, features, data);
141 case Types::VariantType::Short:
142 return toVariant<int16_t>(stream, features, data);
143 case Types::VariantType::Char:
144 return toVariant<int8_t>(stream, features, data);
145 case Types::VariantType::ULong:
146 return toVariant<qulonglong>(stream, features, data);
147 case Types::VariantType::UShort:
148 return toVariant<uint16_t>(stream, features, data);
149 case Types::VariantType::UChar:
150 return toVariant<uint8_t>(stream, features, data);
151 case Types::VariantType::QVariant:
152 return toVariant<QVariant>(stream, features, data);
154 qWarning() << "Usertype should have been caught earlier already";
159 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, QVariant &data, Types::QuasselType type)
162 case Types::QuasselType::BufferId:
163 return toVariant<BufferId>(stream, features, data);
164 case Types::QuasselType::BufferInfo:
165 return toVariant<BufferInfo>(stream, features, data);
166 case Types::QuasselType::Identity:
167 return toVariant<Identity>(stream, features, data);
168 case Types::QuasselType::IdentityId:
169 return toVariant<IdentityId>(stream, features, data);
170 case Types::QuasselType::Message:
171 return toVariant<Message>(stream, features, data);
172 case Types::QuasselType::MsgId:
173 return toVariant<MsgId>(stream, features, data);
174 case Types::QuasselType::NetworkId:
175 return toVariant<NetworkId>(stream, features, data);
176 case Types::QuasselType::NetworkInfo:
177 return toVariant<NetworkInfo>(stream, features, data);
178 case Types::QuasselType::Network_Server:
179 return toVariant<Network::Server>(stream, features, data);
180 case Types::QuasselType::PeerPtr:
181 return toVariant<PeerPtr>(stream, features, data);
183 qWarning() << "Invalid QType";
188 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, Types::VariantType &data)
191 if (!deserialize(stream, features, raw))
193 data = static_cast<Types::VariantType>(raw);
194 return checkStreamValid(stream);
197 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, QStringList &data)
200 if (!deserialize(stream, features, size))
202 for (uint32_t i = 0; i < size; i++) {
204 if (!deserialize(stream, features, element))
208 return checkStreamValid(stream);
211 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, Network::Server &server)
214 QVariantMap serverMap;
215 if (!deserialize(stream, features, serverMap))
217 server.host = serverMap["Host"].toString();
218 server.port = serverMap["Port"].toUInt();
219 server.password = serverMap["Password"].toString();
220 server.useSsl = serverMap["UseSSL"].toBool();
221 server.sslVerify = serverMap["sslVerify"].toBool();
222 server.sslVersion = serverMap["sslVersion"].toInt();
223 server.useProxy = serverMap["UseProxy"].toBool();
224 server.proxyType = serverMap["ProxyType"].toInt();
225 server.proxyHost = serverMap["ProxyHost"].toString();
226 server.proxyPort = serverMap["ProxyPort"].toUInt();
227 server.proxyUser = serverMap["ProxyUser"].toString();
228 server.proxyPass = serverMap["ProxyPass"].toString();
229 return checkStreamValid(stream);
232 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, Identity &data)
236 if (!deserialize(stream, features, raw))
238 data.fromVariantMap(raw);
239 return checkStreamValid(stream);
242 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, NetworkInfo &info)
246 if (!deserialize(stream, features, i))
248 info.networkId = i["NetworkId"].value<NetworkId>();
249 info.networkName = i["NetworkName"].toString();
250 info.identity = i["Identity"].value<IdentityId>();
251 info.codecForServer = i["CodecForServer"].toByteArray();
252 info.codecForEncoding = i["CodecForEncoding"].toByteArray();
253 info.codecForDecoding = i["CodecForDecoding"].toByteArray();
254 info.serverList = fromVariantList<Network::Server>(i["ServerList"].toList());
255 info.useRandomServer = i["UseRandomServer"].toBool();
256 info.perform = i["Perform"].toStringList();
257 info.useAutoIdentify = i["UseAutoIdentify"].toBool();
258 info.autoIdentifyService = i["AutoIdentifyService"].toString();
259 info.autoIdentifyPassword = i["AutoIdentifyPassword"].toString();
260 info.useSasl = i["UseSasl"].toBool();
261 info.saslAccount = i["SaslAccount"].toString();
262 info.saslPassword = i["SaslPassword"].toString();
263 info.useAutoReconnect = i["UseAutoReconnect"].toBool();
264 info.autoReconnectInterval = i["AutoReconnectInterval"].toUInt();
265 info.autoReconnectRetries = i["AutoReconnectRetries"].toInt();
266 info.unlimitedReconnectRetries = i["UnlimitedReconnectRetries"].toBool();
267 info.rejoinChannels = i["RejoinChannels"].toBool();
268 // Custom rate limiting
269 info.useCustomMessageRate = i["UseCustomMessageRate"].toBool();
270 info.messageRateBurstSize = i["MessageRateBurstSize"].toUInt();
271 info.messageRateDelay = i["MessageRateDelay"].toUInt();
272 info.unlimitedMessageRate = i["UnlimitedMessageRate"].toBool();
273 return checkStreamValid(stream);
276 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, PeerPtr &data)
280 return checkStreamValid(stream);
283 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, QByteArray &data)
288 if (!deserialize(stream, features, length))
290 // -1 - or 0xffffffff - is used for an empty byte array
291 if (length == 0xffffffff) {
295 // 64 MB should be enough
296 if (length > 64 * 1024 * 1024) {
297 qWarning() << "Peer sent too large QByteArray: " << length;
301 const uint32_t Step = 1024 * 1024;
302 uint32_t allocated = 0;
304 int blockSize = std::min(Step, length - allocated);
305 data.resize(allocated + blockSize);
306 if (stream.readRawData(data.data() + allocated, blockSize) != blockSize) {
308 qWarning() << "BufferUnderFlow while reading QByteArray";
311 allocated += blockSize;
312 } while (allocated < length);
313 return checkStreamValid(stream);
316 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, QString &data)
320 // read size of string
321 if (!deserialize(stream, features, bytes))
330 if (bytes == 0xffffffff) {
335 // 64 MB should be enough
336 if (bytes > 64 * 1024 * 1024) {
337 qWarning() << "Peer sent too large QString: " << bytes;
343 qWarning() << "Read corrupted data: UTF-6 String with odd length: " << bytes;
346 const uint32_t step = 1024 * 1024;
347 uint32_t length = bytes / 2;
348 uint32_t allocated = 0;
349 while (allocated < length) {
350 int blockSize = std::min(step, length - allocated);
351 data.resize(allocated + blockSize);
352 if (stream.readRawData(reinterpret_cast<char *>(data.data()) + allocated * 2, blockSize * 2) != blockSize * 2) {
354 qWarning() << "BufferUnderFlow while reading QString";
357 allocated += blockSize;
359 if ((stream.byteOrder() == QDataStream::BigEndian) != (QSysInfo::ByteOrder == QSysInfo::BigEndian)) {
360 uint16_t *rawData = reinterpret_cast<uint16_t *>(data.data());
362 *rawData = qbswap(*rawData);
366 return checkStreamValid(stream);
369 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, QChar &data)
373 return checkStreamValid(stream);
376 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, QDate &data)
380 return checkStreamValid(stream);
383 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, QTime &data)
387 return checkStreamValid(stream);
390 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, QDateTime &data)
394 return checkStreamValid(stream);
397 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, int32_t &data)
401 return checkStreamValid(stream);
404 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, uint32_t &data)
408 return checkStreamValid(stream);
411 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, int16_t &data)
415 return checkStreamValid(stream);
418 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, uint16_t &data)
422 return checkStreamValid(stream);
425 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, int8_t &data)
429 return checkStreamValid(stream);
432 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, uint8_t &data)
436 return checkStreamValid(stream);
439 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, qlonglong &data)
443 return checkStreamValid(stream);
446 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, qulonglong &data)
450 return checkStreamValid(stream);
453 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, bool &data)
457 return checkStreamValid(stream);
460 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, BufferInfo &data)
464 return checkStreamValid(stream);
467 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, Message &data)
471 return checkStreamValid(stream);
474 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, NetworkId &data)
478 return checkStreamValid(stream);
481 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, IdentityId &data)
485 return checkStreamValid(stream);
488 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, BufferId &data)
492 return checkStreamValid(stream);
495 bool Serializers::deserialize(QDataStream &stream, const Quassel::Features &features, MsgId &data)
499 return checkStreamValid(stream);
502 Serializers::Types::VariantType Serializers::Types::variantType(Serializers::Types::QuasselType type)
505 case QuasselType::BufferId:
506 return VariantType::UserType;
507 case QuasselType::BufferInfo:
508 return VariantType::UserType;
509 case QuasselType::Identity:
510 return VariantType::UserType;
511 case QuasselType::IdentityId:
512 return VariantType::UserType;
513 case QuasselType::Message:
514 return VariantType::UserType;
515 case QuasselType::MsgId:
516 return VariantType::UserType;
517 case QuasselType::NetworkId:
518 return VariantType::UserType;
519 case QuasselType::NetworkInfo:
520 return VariantType::UserType;
521 case QuasselType::Network_Server:
522 return VariantType::UserType;
523 case QuasselType::PeerPtr:
524 return VariantType::Long;
526 return VariantType::UserType;
530 QString Serializers::Types::toName(Serializers::Types::QuasselType type)
533 case QuasselType::BufferId:
534 return QString("BufferId");
535 case QuasselType::BufferInfo:
536 return QString("BufferInfo");
537 case QuasselType::Identity:
538 return QString("Identity");
539 case QuasselType::IdentityId:
540 return QString("IdentityId");
541 case QuasselType::Message:
542 return QString("Message");
543 case QuasselType::MsgId:
544 return QString("MsgId");
545 case QuasselType::NetworkId:
546 return QString("NetworkId");
547 case QuasselType::NetworkInfo:
548 return QString("NetworkInfo");
549 case QuasselType::Network_Server:
550 return QString("Network::Server");
551 case QuasselType::PeerPtr:
552 return QString("PeerPtr");
554 return QString("Invalid Type");
558 Serializers::Types::QuasselType Serializers::Types::fromName(::QByteArray &name)
560 if (qstrcmp(name, "BufferId") == 0) return QuasselType::BufferId;
561 else if (qstrcmp(name, "BufferInfo") == 0) return QuasselType::BufferInfo;
562 else if (qstrcmp(name, "Identity") == 0) return QuasselType::Identity;
563 else if (qstrcmp(name, "IdentityId") == 0) return QuasselType::IdentityId;
564 else if (qstrcmp(name, "Message") == 0) return QuasselType::Message;
565 else if (qstrcmp(name, "MsgId") == 0) return QuasselType::MsgId;
566 else if (qstrcmp(name, "NetworkId") == 0) return QuasselType::NetworkId;
567 else if (qstrcmp(name, "NetworkInfo") == 0) return QuasselType::NetworkInfo;
568 else if (qstrcmp(name, "Network::Server") == 0) return QuasselType::Network_Server;
569 else if (qstrcmp(name, "PeerPtr") == 0) return QuasselType::PeerPtr;
571 qWarning() << "Type name is not valid: " << name;
572 return QuasselType::Invalid;