Make DirStub serialization consistent on all architectures

Thanks elRepo.io developers to detect and report this bug with detail
https://gitlab.com/elRepo.io/elRepo.io-android/-/issues/52
This commit is contained in:
Gioacchino Mazzurco 2021-11-05 12:02:56 +01:00
parent b805cce58d
commit a9fe1ba6de
No known key found for this signature in database
GPG Key ID: A1FBCA3872E87051
2 changed files with 20 additions and 39 deletions

View File

@ -3,7 +3,9 @@
* * * *
* libretroshare: retroshare core library * * libretroshare: retroshare core library *
* * * *
* Copyright 2004-2006 by Robert Fernie <retroshare@lunamutt.com> * * Copyright (C) 2004-2006 Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2018-2021 Gioacchino Mazzurco <gio@eigenlab.org> *
* Copyright (C) 2020-2021 Asociación Civil Altermundi <info@altermundi.net> *
* * * *
* This program is free software: you can redistribute it and/or modify * * This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as * * it under the terms of the GNU Lesser General Public License as *
@ -135,17 +137,10 @@ struct PeerBandwidthLimits : RsSerializable
} }
}; };
//class SearchRequest // unused stuff.
//{
// public:
// int searchId;
// RsCertId toId; /* all zeros for everyone! */
// std::list<Condition> tests;
//};
/********************** For FileCache Interface *****************/ /********************** For FileCache Interface *****************/
/* G10h4ck: Having this kind of stuff on public headers is pretty dangerous for
* name space pollution, a C++11 enum class should be used instad ASAP */
#define DIR_TYPE_UNKNOWN 0x00 #define DIR_TYPE_UNKNOWN 0x00
#define DIR_TYPE_ROOT 0x01 #define DIR_TYPE_ROOT 0x01
#define DIR_TYPE_PERSON 0x02 #define DIR_TYPE_PERSON 0x02
@ -258,6 +253,9 @@ struct DirStub : RsSerializable
uint8_t type; uint8_t type;
std::string name; std::string name;
/* G10h4ck do we still need to keep this as void* instead of uint64_t for
* retroshare-gui sake? */
void* ref; void* ref;
/// @see RsSerializable /// @see RsSerializable
@ -267,29 +265,12 @@ struct DirStub : RsSerializable
RS_SERIAL_PROCESS(type); RS_SERIAL_PROCESS(type);
RS_SERIAL_PROCESS(name); RS_SERIAL_PROCESS(name);
#if defined(__GNUC__) && !defined(__clang__) /* Enforce serialization as uint64_t because void* changes size (usually
# pragma GCC diagnostic ignored "-Wstrict-aliasing" * 4 bytes on 32bit arch and 8 bytes on 64bit archs) depending on
#endif // defined(__GNUC__) && !defined(__clang__) * architectures and make JSON API behave inconsistenly. */
// (Cyril) We have to do this because on some systems (MacOS) uintptr_t is unsigned long which is not well defined. It is always uint64_t handle = reinterpret_cast<uint64_t>(ref);
// preferable to force type serialization to the correct size rather than letting the compiler choose for us.
// /!\ This structure cannot be sent over the network. The serialization would be inconsistent.
if(sizeof(ref) == 4)
{
std::uint32_t& handle(reinterpret_cast<std::uint32_t&>(ref));
RS_SERIAL_PROCESS(handle); RS_SERIAL_PROCESS(handle);
} ref = reinterpret_cast<void*>(handle);
else if(sizeof(ref) == 8)
{
std::uint64_t& handle(reinterpret_cast<std::uint64_t&>(ref));
RS_SERIAL_PROCESS(handle);
}
else
std::cerr << __PRETTY_FUNCTION__ << ": cannot serialize raw pointer of size " << sizeof(ref) << std::endl;
#if defined(__GNUC__) && !defined(__clang__)
# pragma GCC diagnostic pop
#endif // defined(__GNUC__) && !defined(__clang__)
} }
}; };
@ -330,9 +311,9 @@ struct DirDetails : RsSerializable
void serial_process(RsGenericSerializer::SerializeJob j, void serial_process(RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx) override RsGenericSerializer::SerializeContext& ctx) override
{ {
/* Enforce serialization as uint64_t because void* changes size /* Enforce serialization as uint64_t because void* changes size (usually
* depending (usually 4 bytes on 32bit arch and 8 bytes on 64bit archs) * 4 bytes on 32bit arch and 8 bytes on 64bit archs) depending on
*/ * architectures and make JSON API behave inconsistenly. */
uint64_t handle = reinterpret_cast<uint64_t>(ref); uint64_t handle = reinterpret_cast<uint64_t>(ref);
RS_SERIAL_PROCESS(handle); RS_SERIAL_PROCESS(handle);
ref = reinterpret_cast<void*>(handle); ref = reinterpret_cast<void*>(handle);