ipc_message_utils.h 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef IPC_IPC_MESSAGE_UTILS_H_
  5. #define IPC_IPC_MESSAGE_UTILS_H_
  6. #include <limits.h>
  7. #include <stddef.h>
  8. #include <stdint.h>
  9. #include <map>
  10. #include <memory>
  11. #include <set>
  12. #include <string>
  13. #include <tuple>
  14. #include <unordered_map>
  15. #include <vector>
  16. #include "base/check.h"
  17. #include "base/compiler_specific.h"
  18. #include "base/component_export.h"
  19. #include "base/containers/flat_map.h"
  20. #include "base/containers/stack_container.h"
  21. #include "base/files/file.h"
  22. #include "base/memory/platform_shared_memory_region.h"
  23. #include "base/memory/read_only_shared_memory_region.h"
  24. #include "base/memory/unsafe_shared_memory_region.h"
  25. #include "base/memory/writable_shared_memory_region.h"
  26. #include "base/numerics/safe_conversions.h"
  27. #include "base/pickle.h"
  28. #include "base/types/id_type.h"
  29. #include "base/values.h"
  30. #include "build/build_config.h"
  31. #include "ipc/ipc_buildflags.h"
  32. #include "ipc/ipc_param_traits.h"
  33. #include "third_party/abseil-cpp/absl/types/optional.h"
  34. #if BUILDFLAG(IS_ANDROID)
  35. #include "base/android/scoped_hardware_buffer_handle.h"
  36. #endif
  37. #if BUILDFLAG(IS_FUCHSIA)
  38. #include <lib/zx/channel.h>
  39. #include <lib/zx/vmo.h>
  40. #endif
  41. #if BUILDFLAG(IS_WIN)
  42. #include "base/strings/string_util_win.h"
  43. #endif
  44. #if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
  45. #include "ipc/ipc_message.h"
  46. #endif
  47. namespace base {
  48. class FilePath;
  49. class Time;
  50. class TimeDelta;
  51. class TimeTicks;
  52. class UnguessableToken;
  53. struct FileDescriptor;
  54. } // namespace base
  55. namespace IPC {
  56. class Message;
  57. struct ChannelHandle;
  58. #if BUILDFLAG(IS_WIN)
  59. class PlatformFileForTransit;
  60. #endif
  61. // -----------------------------------------------------------------------------
  62. // How we send IPC message logs across channels.
  63. struct COMPONENT_EXPORT(IPC) LogData {
  64. LogData();
  65. LogData(const LogData& other);
  66. ~LogData();
  67. std::string channel;
  68. int32_t routing_id;
  69. uint32_t type; // "User-defined" message type, from ipc_message.h.
  70. std::string flags;
  71. int64_t sent; // Time that the message was sent (i.e. at Send()).
  72. int64_t receive; // Time before it was dispatched (i.e. before calling
  73. // OnMessageReceived).
  74. int64_t dispatch; // Time after it was dispatched (i.e. after calling
  75. // OnMessageReceived).
  76. std::string message_name;
  77. std::string params;
  78. };
  79. //-----------------------------------------------------------------------------
  80. // A dummy struct to place first just to allow leading commas for all
  81. // members in the macro-generated constructor initializer lists.
  82. struct NoParams {
  83. };
  84. // Specializations are checked by 'IPC checker' part of find-bad-constructs
  85. // Clang plugin (see WriteParam() below for the details).
  86. template <typename... Ts>
  87. struct CheckedTuple {
  88. typedef std::tuple<Ts...> Tuple;
  89. };
  90. // This function is checked by 'IPC checker' part of find-bad-constructs
  91. // Clang plugin to make it's not called on the following types:
  92. // 1. long / unsigned long (but not typedefs to)
  93. // 2. intmax_t, uintmax_t, intptr_t, uintptr_t, wint_t,
  94. // size_t, rsize_t, ssize_t, ptrdiff_t, dev_t, off_t, clock_t,
  95. // time_t, suseconds_t (including typedefs to)
  96. // 3. Any template referencing types above (e.g. std::vector<size_t>)
  97. template <class P>
  98. inline void WriteParam(base::Pickle* m, const P& p) {
  99. typedef typename SimilarTypeTraits<P>::Type Type;
  100. ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
  101. }
  102. template <class P>
  103. [[nodiscard]] inline bool ReadParam(const base::Pickle* m,
  104. base::PickleIterator* iter,
  105. P* p) {
  106. typedef typename SimilarTypeTraits<P>::Type Type;
  107. return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
  108. }
  109. template <class P>
  110. inline void LogParam(const P& p, std::string* l) {
  111. typedef typename SimilarTypeTraits<P>::Type Type;
  112. ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
  113. }
  114. // Primitive ParamTraits -------------------------------------------------------
  115. template <>
  116. struct ParamTraits<bool> {
  117. typedef bool param_type;
  118. static void Write(base::Pickle* m, const param_type& p) { m->WriteBool(p); }
  119. static bool Read(const base::Pickle* m,
  120. base::PickleIterator* iter,
  121. param_type* r) {
  122. return iter->ReadBool(r);
  123. }
  124. COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
  125. };
  126. template <>
  127. struct COMPONENT_EXPORT(IPC) ParamTraits<signed char> {
  128. typedef signed char param_type;
  129. static void Write(base::Pickle* m, const param_type& p);
  130. static bool Read(const base::Pickle* m,
  131. base::PickleIterator* iter,
  132. param_type* r);
  133. static void Log(const param_type& p, std::string* l);
  134. };
  135. template <>
  136. struct COMPONENT_EXPORT(IPC) ParamTraits<unsigned char> {
  137. typedef unsigned char param_type;
  138. static void Write(base::Pickle* m, const param_type& p);
  139. static bool Read(const base::Pickle* m,
  140. base::PickleIterator* iter,
  141. param_type* r);
  142. static void Log(const param_type& p, std::string* l);
  143. };
  144. template <>
  145. struct COMPONENT_EXPORT(IPC) ParamTraits<unsigned short> {
  146. typedef unsigned short param_type;
  147. static void Write(base::Pickle* m, const param_type& p);
  148. static bool Read(const base::Pickle* m,
  149. base::PickleIterator* iter,
  150. param_type* r);
  151. static void Log(const param_type& p, std::string* l);
  152. };
  153. template <>
  154. struct ParamTraits<int> {
  155. typedef int param_type;
  156. static void Write(base::Pickle* m, const param_type& p) { m->WriteInt(p); }
  157. static bool Read(const base::Pickle* m,
  158. base::PickleIterator* iter,
  159. param_type* r) {
  160. return iter->ReadInt(r);
  161. }
  162. COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
  163. };
  164. template <>
  165. struct ParamTraits<unsigned int> {
  166. typedef unsigned int param_type;
  167. static void Write(base::Pickle* m, const param_type& p) {
  168. m->WriteInt(static_cast<int>(p));
  169. }
  170. static bool Read(const base::Pickle* m,
  171. base::PickleIterator* iter,
  172. param_type* r) {
  173. return iter->ReadInt(reinterpret_cast<int*>(r));
  174. }
  175. COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
  176. };
  177. // long isn't safe to send over IPC because it's 4 bytes on 32 bit builds but
  178. // 8 bytes on 64 bit builds. So if a 32 bit and 64 bit process have a channel
  179. // that would cause problem.
  180. // We need to keep this on for a few configs:
  181. // 1) Windows because DWORD is typedef'd to it, which is fine because we have
  182. // very few IPCs that cross this boundary.
  183. // 2) We also need to keep it for Linux for two reasons: int64_t is typedef'd
  184. // to long, and gfx::PluginWindow is long and is used in one GPU IPC.
  185. // 3) Android 64 bit and Fuchsia also have int64_t typedef'd to long.
  186. // Since we want to support Android 32<>64 bit IPC, as long as we don't have
  187. // these traits for 32 bit ARM then that'll catch any errors.
  188. #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
  189. BUILDFLAG(IS_FUCHSIA) || \
  190. (BUILDFLAG(IS_ANDROID) && defined(ARCH_CPU_64_BITS))
  191. template <>
  192. struct ParamTraits<long> {
  193. typedef long param_type;
  194. static void Write(base::Pickle* m, const param_type& p) {
  195. m->WriteLong(p);
  196. }
  197. static bool Read(const base::Pickle* m,
  198. base::PickleIterator* iter,
  199. param_type* r) {
  200. return iter->ReadLong(r);
  201. }
  202. COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
  203. };
  204. template <>
  205. struct ParamTraits<unsigned long> {
  206. typedef unsigned long param_type;
  207. static void Write(base::Pickle* m, const param_type& p) {
  208. m->WriteLong(p);
  209. }
  210. static bool Read(const base::Pickle* m,
  211. base::PickleIterator* iter,
  212. param_type* r) {
  213. return iter->ReadLong(reinterpret_cast<long*>(r));
  214. }
  215. COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
  216. };
  217. #endif
  218. template <>
  219. struct ParamTraits<long long> {
  220. typedef long long param_type;
  221. static void Write(base::Pickle* m, const param_type& p) {
  222. m->WriteInt64(static_cast<int64_t>(p));
  223. }
  224. static bool Read(const base::Pickle* m,
  225. base::PickleIterator* iter,
  226. param_type* r) {
  227. return iter->ReadInt64(reinterpret_cast<int64_t*>(r));
  228. }
  229. COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
  230. };
  231. template <>
  232. struct ParamTraits<unsigned long long> {
  233. typedef unsigned long long param_type;
  234. static void Write(base::Pickle* m, const param_type& p) {
  235. m->WriteInt64(static_cast<int64_t>(p));
  236. }
  237. static bool Read(const base::Pickle* m,
  238. base::PickleIterator* iter,
  239. param_type* r) {
  240. return iter->ReadInt64(reinterpret_cast<int64_t*>(r));
  241. }
  242. COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
  243. };
  244. // Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
  245. // should be sure to check the sanity of these values after receiving them over
  246. // IPC.
  247. template <>
  248. struct COMPONENT_EXPORT(IPC) ParamTraits<float> {
  249. typedef float param_type;
  250. static void Write(base::Pickle* m, const param_type& p) { m->WriteFloat(p); }
  251. static bool Read(const base::Pickle* m,
  252. base::PickleIterator* iter,
  253. param_type* r) {
  254. return iter->ReadFloat(r);
  255. }
  256. static void Log(const param_type& p, std::string* l);
  257. };
  258. template <>
  259. struct COMPONENT_EXPORT(IPC) ParamTraits<double> {
  260. typedef double param_type;
  261. static void Write(base::Pickle* m, const param_type& p);
  262. static bool Read(const base::Pickle* m,
  263. base::PickleIterator* iter,
  264. param_type* r);
  265. static void Log(const param_type& p, std::string* l);
  266. };
  267. template <class P, size_t Size>
  268. struct ParamTraits<P[Size]> {
  269. using param_type = P[Size];
  270. static void Write(base::Pickle* m, const param_type& p) {
  271. for (const P& element : p)
  272. WriteParam(m, element);
  273. }
  274. static bool Read(const base::Pickle* m,
  275. base::PickleIterator* iter,
  276. param_type* r) {
  277. for (P& element : *r) {
  278. if (!ReadParam(m, iter, &element))
  279. return false;
  280. }
  281. return true;
  282. }
  283. static void Log(const param_type& p, std::string* l) {
  284. l->append("[");
  285. for (const P& element : p) {
  286. if (&element != &p[0])
  287. l->append(" ");
  288. LogParam(element, l);
  289. }
  290. l->append("]");
  291. }
  292. };
  293. // STL ParamTraits -------------------------------------------------------------
  294. template <>
  295. struct ParamTraits<std::string> {
  296. typedef std::string param_type;
  297. static void Write(base::Pickle* m, const param_type& p) { m->WriteString(p); }
  298. static bool Read(const base::Pickle* m,
  299. base::PickleIterator* iter,
  300. param_type* r) {
  301. return iter->ReadString(r);
  302. }
  303. COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
  304. };
  305. template <>
  306. struct ParamTraits<std::u16string> {
  307. typedef std::u16string param_type;
  308. static void Write(base::Pickle* m, const param_type& p) {
  309. m->WriteString16(p);
  310. }
  311. static bool Read(const base::Pickle* m,
  312. base::PickleIterator* iter,
  313. param_type* r) {
  314. return iter->ReadString16(r);
  315. }
  316. COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
  317. };
  318. #if BUILDFLAG(IS_WIN)
  319. template <>
  320. struct COMPONENT_EXPORT(IPC) ParamTraits<std::wstring> {
  321. typedef std::wstring param_type;
  322. static void Write(base::Pickle* m, const param_type& p) {
  323. m->WriteString16(base::AsStringPiece16(p));
  324. }
  325. static bool Read(const base::Pickle* m,
  326. base::PickleIterator* iter,
  327. param_type* r);
  328. static void Log(const param_type& p, std::string* l);
  329. };
  330. #endif
  331. template <>
  332. struct COMPONENT_EXPORT(IPC) ParamTraits<std::vector<char>> {
  333. typedef std::vector<char> param_type;
  334. static void Write(base::Pickle* m, const param_type& p);
  335. static bool Read(const base::Pickle*,
  336. base::PickleIterator* iter,
  337. param_type* r);
  338. static void Log(const param_type& p, std::string* l);
  339. };
  340. template <>
  341. struct COMPONENT_EXPORT(IPC) ParamTraits<std::vector<unsigned char>> {
  342. typedef std::vector<unsigned char> param_type;
  343. static void Write(base::Pickle* m, const param_type& p);
  344. static bool Read(const base::Pickle* m,
  345. base::PickleIterator* iter,
  346. param_type* r);
  347. static void Log(const param_type& p, std::string* l);
  348. };
  349. template <>
  350. struct COMPONENT_EXPORT(IPC) ParamTraits<std::vector<bool>> {
  351. typedef std::vector<bool> param_type;
  352. static void Write(base::Pickle* m, const param_type& p);
  353. static bool Read(const base::Pickle* m,
  354. base::PickleIterator* iter,
  355. param_type* r);
  356. static void Log(const param_type& p, std::string* l);
  357. };
  358. template <class P>
  359. struct ParamTraits<std::vector<P>> {
  360. typedef std::vector<P> param_type;
  361. static void Write(base::Pickle* m, const param_type& p) {
  362. WriteParam(m, base::checked_cast<int>(p.size()));
  363. for (size_t i = 0; i < p.size(); i++)
  364. WriteParam(m, p[i]);
  365. }
  366. static bool Read(const base::Pickle* m,
  367. base::PickleIterator* iter,
  368. param_type* r) {
  369. size_t size;
  370. // ReadLength() checks for < 0 itself.
  371. if (!iter->ReadLength(&size))
  372. return false;
  373. // Resizing beforehand is not safe, see BUG 1006367 for details.
  374. if (size > INT_MAX / sizeof(P))
  375. return false;
  376. r->resize(size);
  377. for (size_t i = 0; i < size; i++) {
  378. if (!ReadParam(m, iter, &(*r)[i]))
  379. return false;
  380. }
  381. return true;
  382. }
  383. static void Log(const param_type& p, std::string* l) {
  384. for (size_t i = 0; i < p.size(); ++i) {
  385. if (i != 0)
  386. l->append(" ");
  387. LogParam((p[i]), l);
  388. }
  389. }
  390. };
  391. template <class P>
  392. struct ParamTraits<std::set<P> > {
  393. typedef std::set<P> param_type;
  394. static void Write(base::Pickle* m, const param_type& p) {
  395. WriteParam(m, base::checked_cast<int>(p.size()));
  396. typename param_type::const_iterator iter;
  397. for (iter = p.begin(); iter != p.end(); ++iter)
  398. WriteParam(m, *iter);
  399. }
  400. static bool Read(const base::Pickle* m,
  401. base::PickleIterator* iter,
  402. param_type* r) {
  403. size_t size;
  404. if (!iter->ReadLength(&size))
  405. return false;
  406. for (size_t i = 0; i < size; ++i) {
  407. P item;
  408. if (!ReadParam(m, iter, &item))
  409. return false;
  410. r->insert(item);
  411. }
  412. return true;
  413. }
  414. static void Log(const param_type& p, std::string* l) {
  415. l->append("<std::set>");
  416. }
  417. };
  418. template <class K, class V, class C, class A>
  419. struct ParamTraits<std::map<K, V, C, A> > {
  420. typedef std::map<K, V, C, A> param_type;
  421. static void Write(base::Pickle* m, const param_type& p) {
  422. WriteParam(m, base::checked_cast<int>(p.size()));
  423. for (const auto& iter : p) {
  424. WriteParam(m, iter.first);
  425. WriteParam(m, iter.second);
  426. }
  427. }
  428. static bool Read(const base::Pickle* m,
  429. base::PickleIterator* iter,
  430. param_type* r) {
  431. int size;
  432. if (!ReadParam(m, iter, &size) || size < 0)
  433. return false;
  434. for (int i = 0; i < size; ++i) {
  435. K k;
  436. if (!ReadParam(m, iter, &k))
  437. return false;
  438. V& value = (*r)[k];
  439. if (!ReadParam(m, iter, &value))
  440. return false;
  441. }
  442. return true;
  443. }
  444. static void Log(const param_type& p, std::string* l) {
  445. l->append("<std::map>");
  446. }
  447. };
  448. template <class K, class V, class C, class A>
  449. struct ParamTraits<std::unordered_map<K, V, C, A>> {
  450. typedef std::unordered_map<K, V, C, A> param_type;
  451. static void Write(base::Pickle* m, const param_type& p) {
  452. WriteParam(m, base::checked_cast<int>(p.size()));
  453. for (const auto& iter : p) {
  454. WriteParam(m, iter.first);
  455. WriteParam(m, iter.second);
  456. }
  457. }
  458. static bool Read(const base::Pickle* m,
  459. base::PickleIterator* iter,
  460. param_type* r) {
  461. int size;
  462. if (!ReadParam(m, iter, &size) || size < 0)
  463. return false;
  464. for (int i = 0; i < size; ++i) {
  465. K k;
  466. if (!ReadParam(m, iter, &k))
  467. return false;
  468. V& value = (*r)[k];
  469. if (!ReadParam(m, iter, &value))
  470. return false;
  471. }
  472. return true;
  473. }
  474. static void Log(const param_type& p, std::string* l) {
  475. l->append("<std::unordered_map>");
  476. }
  477. };
  478. template <class A, class B>
  479. struct ParamTraits<std::pair<A, B> > {
  480. typedef std::pair<A, B> param_type;
  481. static void Write(base::Pickle* m, const param_type& p) {
  482. WriteParam(m, p.first);
  483. WriteParam(m, p.second);
  484. }
  485. static bool Read(const base::Pickle* m,
  486. base::PickleIterator* iter,
  487. param_type* r) {
  488. return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
  489. }
  490. static void Log(const param_type& p, std::string* l) {
  491. l->append("(");
  492. LogParam(p.first, l);
  493. l->append(", ");
  494. LogParam(p.second, l);
  495. l->append(")");
  496. }
  497. };
  498. // Base ParamTraits ------------------------------------------------------------
  499. template <>
  500. struct COMPONENT_EXPORT(IPC) ParamTraits<base::DictionaryValue> {
  501. typedef base::DictionaryValue param_type;
  502. static void Write(base::Pickle* m, const param_type& p);
  503. static bool Read(const base::Pickle* m,
  504. base::PickleIterator* iter,
  505. param_type* r);
  506. static void Log(const param_type& p, std::string* l);
  507. };
  508. template <>
  509. struct COMPONENT_EXPORT(IPC) ParamTraits<base::Value::Dict> {
  510. typedef base::Value::Dict param_type;
  511. static void Write(base::Pickle* m, const param_type& p);
  512. static bool Read(const base::Pickle* m,
  513. base::PickleIterator* iter,
  514. param_type* r);
  515. static void Log(const param_type& p, std::string* l);
  516. };
  517. #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
  518. // FileDescriptors may be serialised over IPC channels on POSIX. On the
  519. // receiving side, the FileDescriptor is a valid duplicate of the file
  520. // descriptor which was transmitted: *it is not just a copy of the integer like
  521. // HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
  522. // this case, the receiving end will see a value of -1. *Zero is a valid file
  523. // descriptor*.
  524. //
  525. // The received file descriptor will have the |auto_close| flag set to true. The
  526. // code which handles the message is responsible for taking ownership of it.
  527. // File descriptors are OS resources and must be closed when no longer needed.
  528. //
  529. // When sending a file descriptor, the file descriptor must be valid at the time
  530. // of transmission. Since transmission is not synchronous, one should consider
  531. // dup()ing any file descriptors to be transmitted and setting the |auto_close|
  532. // flag, which causes the file descriptor to be closed after writing.
  533. template <>
  534. struct COMPONENT_EXPORT(IPC) ParamTraits<base::FileDescriptor> {
  535. typedef base::FileDescriptor param_type;
  536. static void Write(base::Pickle* m, const param_type& p);
  537. static bool Read(const base::Pickle* m,
  538. base::PickleIterator* iter,
  539. param_type* r);
  540. static void Log(const param_type& p, std::string* l);
  541. };
  542. template <>
  543. struct COMPONENT_EXPORT(IPC) ParamTraits<base::ScopedFD> {
  544. typedef base::ScopedFD param_type;
  545. static void Write(base::Pickle* m, const param_type& p);
  546. static bool Read(const base::Pickle* m,
  547. base::PickleIterator* iter,
  548. param_type* r);
  549. static void Log(const param_type& p, std::string* l);
  550. };
  551. #endif // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
  552. #if BUILDFLAG(IS_WIN)
  553. template <>
  554. struct COMPONENT_EXPORT(IPC) ParamTraits<base::win::ScopedHandle> {
  555. using param_type = base::win::ScopedHandle;
  556. static void Write(base::Pickle* m, const param_type& p);
  557. static bool Read(const base::Pickle* m,
  558. base::PickleIterator* iter,
  559. param_type* r);
  560. static void Log(const param_type& p, std::string* l);
  561. };
  562. #endif
  563. #if BUILDFLAG(IS_FUCHSIA)
  564. template <>
  565. struct COMPONENT_EXPORT(IPC) ParamTraits<zx::vmo> {
  566. typedef zx::vmo param_type;
  567. static void Write(base::Pickle* m, const param_type& p);
  568. static bool Read(const base::Pickle* m,
  569. base::PickleIterator* iter,
  570. param_type* r);
  571. static void Log(const param_type& p, std::string* l);
  572. };
  573. template <>
  574. struct COMPONENT_EXPORT(IPC) ParamTraits<zx::channel> {
  575. typedef zx::channel param_type;
  576. static void Write(base::Pickle* m, const param_type& p);
  577. static bool Read(const base::Pickle* m,
  578. base::PickleIterator* iter,
  579. param_type* r);
  580. static void Log(const param_type& p, std::string* l);
  581. };
  582. #endif // BUILDFLAG(IS_FUCHSIA)
  583. #if BUILDFLAG(IS_ANDROID)
  584. template <>
  585. struct COMPONENT_EXPORT(IPC)
  586. ParamTraits<base::android::ScopedHardwareBufferHandle> {
  587. typedef base::android::ScopedHardwareBufferHandle param_type;
  588. static void Write(base::Pickle* m, const param_type& p);
  589. static bool Read(const base::Pickle* m,
  590. base::PickleIterator* iter,
  591. param_type* r);
  592. static void Log(const param_type& p, std::string* l);
  593. };
  594. #endif
  595. template <>
  596. struct COMPONENT_EXPORT(IPC) ParamTraits<base::ReadOnlySharedMemoryRegion> {
  597. typedef base::ReadOnlySharedMemoryRegion param_type;
  598. static void Write(base::Pickle* m, const param_type& p);
  599. static bool Read(const base::Pickle* m,
  600. base::PickleIterator* iter,
  601. param_type* r);
  602. static void Log(const param_type& p, std::string* l);
  603. };
  604. template <>
  605. struct COMPONENT_EXPORT(IPC) ParamTraits<base::WritableSharedMemoryRegion> {
  606. typedef base::WritableSharedMemoryRegion param_type;
  607. static void Write(base::Pickle* m, const param_type& p);
  608. static bool Read(const base::Pickle* m,
  609. base::PickleIterator* iter,
  610. param_type* r);
  611. static void Log(const param_type& p, std::string* l);
  612. };
  613. template <>
  614. struct COMPONENT_EXPORT(IPC) ParamTraits<base::UnsafeSharedMemoryRegion> {
  615. typedef base::UnsafeSharedMemoryRegion param_type;
  616. static void Write(base::Pickle* m, const param_type& p);
  617. static bool Read(const base::Pickle* m,
  618. base::PickleIterator* iter,
  619. param_type* r);
  620. static void Log(const param_type& p, std::string* l);
  621. };
  622. template <>
  623. struct COMPONENT_EXPORT(IPC)
  624. ParamTraits<base::subtle::PlatformSharedMemoryRegion> {
  625. typedef base::subtle::PlatformSharedMemoryRegion param_type;
  626. static void Write(base::Pickle* m, const param_type& p);
  627. static bool Read(const base::Pickle* m,
  628. base::PickleIterator* iter,
  629. param_type* r);
  630. static void Log(const param_type& p, std::string* l);
  631. };
  632. template <>
  633. struct COMPONENT_EXPORT(IPC)
  634. ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode> {
  635. typedef base::subtle::PlatformSharedMemoryRegion::Mode param_type;
  636. static void Write(base::Pickle* m, const param_type& p);
  637. static bool Read(const base::Pickle* m,
  638. base::PickleIterator* iter,
  639. param_type* r);
  640. static void Log(const param_type& p, std::string* l);
  641. };
  642. #if BUILDFLAG(IS_WIN)
  643. template <>
  644. struct COMPONENT_EXPORT(IPC) ParamTraits<PlatformFileForTransit> {
  645. typedef PlatformFileForTransit param_type;
  646. static void Write(base::Pickle* m, const param_type& p);
  647. static bool Read(const base::Pickle* m,
  648. base::PickleIterator* iter,
  649. param_type* r);
  650. static void Log(const param_type& p, std::string* l);
  651. };
  652. #endif // BUILDFLAG(IS_WIN)
  653. template <>
  654. struct COMPONENT_EXPORT(IPC) ParamTraits<base::FilePath> {
  655. typedef base::FilePath param_type;
  656. static void Write(base::Pickle* m, const param_type& p);
  657. static bool Read(const base::Pickle* m,
  658. base::PickleIterator* iter,
  659. param_type* r);
  660. static void Log(const param_type& p, std::string* l);
  661. };
  662. template <>
  663. struct COMPONENT_EXPORT(IPC) ParamTraits<base::ListValue> {
  664. typedef base::ListValue param_type;
  665. static void Write(base::Pickle* m, const param_type& p);
  666. static bool Read(const base::Pickle* m,
  667. base::PickleIterator* iter,
  668. param_type* r);
  669. static void Log(const param_type& p, std::string* l);
  670. };
  671. template <>
  672. struct COMPONENT_EXPORT(IPC) ParamTraits<base::Value::List> {
  673. typedef base::Value::List param_type;
  674. static void Write(base::Pickle* m, const param_type& p);
  675. static bool Read(const base::Pickle* m,
  676. base::PickleIterator* iter,
  677. param_type* r);
  678. static void Log(const param_type& p, std::string* l);
  679. };
  680. template <>
  681. struct COMPONENT_EXPORT(IPC) ParamTraits<base::Value> {
  682. typedef base::Value param_type;
  683. static void Write(base::Pickle* m, const param_type& p);
  684. static bool Read(const base::Pickle* m,
  685. base::PickleIterator* iter,
  686. param_type* r);
  687. static void Log(const param_type& p, std::string* l);
  688. };
  689. template <>
  690. struct COMPONENT_EXPORT(IPC) ParamTraits<base::File::Info> {
  691. typedef base::File::Info param_type;
  692. static void Write(base::Pickle* m, const param_type& p);
  693. static bool Read(const base::Pickle* m,
  694. base::PickleIterator* iter,
  695. param_type* r);
  696. static void Log(const param_type& p, std::string* l);
  697. };
  698. template <>
  699. struct SimilarTypeTraits<base::File::Error> {
  700. typedef int Type;
  701. };
  702. #if BUILDFLAG(IS_WIN)
  703. template <>
  704. struct SimilarTypeTraits<HWND> {
  705. typedef HANDLE Type;
  706. };
  707. #endif // BUILDFLAG(IS_WIN)
  708. template <>
  709. struct COMPONENT_EXPORT(IPC) ParamTraits<base::Time> {
  710. typedef base::Time param_type;
  711. static void Write(base::Pickle* m, const param_type& p);
  712. static bool Read(const base::Pickle* m,
  713. base::PickleIterator* iter,
  714. param_type* r);
  715. static void Log(const param_type& p, std::string* l);
  716. };
  717. template <>
  718. struct COMPONENT_EXPORT(IPC) ParamTraits<base::TimeDelta> {
  719. typedef base::TimeDelta param_type;
  720. static void Write(base::Pickle* m, const param_type& p);
  721. static bool Read(const base::Pickle* m,
  722. base::PickleIterator* iter,
  723. param_type* r);
  724. static void Log(const param_type& p, std::string* l);
  725. };
  726. template <>
  727. struct COMPONENT_EXPORT(IPC) ParamTraits<base::TimeTicks> {
  728. typedef base::TimeTicks param_type;
  729. static void Write(base::Pickle* m, const param_type& p);
  730. static bool Read(const base::Pickle* m,
  731. base::PickleIterator* iter,
  732. param_type* r);
  733. static void Log(const param_type& p, std::string* l);
  734. };
  735. template <>
  736. struct COMPONENT_EXPORT(IPC) ParamTraits<base::UnguessableToken> {
  737. typedef base::UnguessableToken param_type;
  738. static void Write(base::Pickle* m, const param_type& p);
  739. static bool Read(const base::Pickle* m,
  740. base::PickleIterator* iter,
  741. param_type* r);
  742. static void Log(const param_type& p, std::string* l);
  743. };
  744. template <>
  745. struct ParamTraits<std::tuple<>> {
  746. typedef std::tuple<> param_type;
  747. static void Write(base::Pickle* m, const param_type& p) {}
  748. static bool Read(const base::Pickle* m,
  749. base::PickleIterator* iter,
  750. param_type* r) {
  751. return true;
  752. }
  753. static void Log(const param_type& p, std::string* l) {
  754. }
  755. };
  756. template <typename T, int index, int count>
  757. struct TupleParamTraitsHelper {
  758. using Next = TupleParamTraitsHelper<T, index + 1, count>;
  759. static void Write(base::Pickle* m, const T& p) {
  760. WriteParam(m, std::get<index>(p));
  761. Next::Write(m, p);
  762. }
  763. static bool Read(const base::Pickle* m, base::PickleIterator* iter, T* r) {
  764. return ReadParam(m, iter, &std::get<index>(*r)) && Next::Read(m, iter, r);
  765. }
  766. static void Log(const T& p, std::string* l) {
  767. LogParam(std::get<index>(p), l);
  768. if (index < count - 1)
  769. l->append(", ");
  770. Next::Log(p, l);
  771. }
  772. };
  773. template <typename T, int index>
  774. struct TupleParamTraitsHelper<T, index, index> {
  775. static void Write(base::Pickle* m, const T& p) {}
  776. static bool Read(const base::Pickle* m, base::PickleIterator* iter, T* r) {
  777. return true;
  778. }
  779. static void Log(const T& p, std::string* l) {}
  780. };
  781. template <typename... Args>
  782. struct ParamTraits<std::tuple<Args...>> {
  783. using param_type = std::tuple<Args...>;
  784. using Helper =
  785. TupleParamTraitsHelper<param_type, 0, std::tuple_size<param_type>::value>;
  786. static void Write(base::Pickle* m, const param_type& p) {
  787. Helper::Write(m, p);
  788. }
  789. static bool Read(const base::Pickle* m,
  790. base::PickleIterator* iter,
  791. param_type* r) {
  792. return Helper::Read(m, iter, r);
  793. }
  794. static void Log(const param_type& p, std::string* l) { Helper::Log(p, l); }
  795. };
  796. template <class P, size_t stack_capacity>
  797. struct ParamTraits<base::StackVector<P, stack_capacity> > {
  798. typedef base::StackVector<P, stack_capacity> param_type;
  799. static void Write(base::Pickle* m, const param_type& p) {
  800. WriteParam(m, base::checked_cast<int>(p->size()));
  801. for (size_t i = 0; i < p->size(); i++)
  802. WriteParam(m, p[i]);
  803. }
  804. static bool Read(const base::Pickle* m,
  805. base::PickleIterator* iter,
  806. param_type* r) {
  807. size_t size;
  808. if (!iter->ReadLength(&size))
  809. return false;
  810. // Sanity check for the vector size.
  811. if (size > INT_MAX / sizeof(P))
  812. return false;
  813. P value;
  814. for (size_t i = 0; i < size; i++) {
  815. if (!ReadParam(m, iter, &value))
  816. return false;
  817. (*r)->push_back(value);
  818. }
  819. return true;
  820. }
  821. static void Log(const param_type& p, std::string* l) {
  822. for (size_t i = 0; i < p->size(); ++i) {
  823. if (i != 0)
  824. l->append(" ");
  825. LogParam((p[i]), l);
  826. }
  827. }
  828. };
  829. template <class Key, class Mapped, class Compare>
  830. struct ParamTraits<base::flat_map<Key, Mapped, Compare>> {
  831. using param_type = base::flat_map<Key, Mapped, Compare>;
  832. static void Write(base::Pickle* m, const param_type& p) {
  833. DCHECK(base::IsValueInRangeForNumericType<int>(p.size()));
  834. WriteParam(m, base::checked_cast<int>(p.size()));
  835. for (const auto& iter : p) {
  836. WriteParam(m, iter.first);
  837. WriteParam(m, iter.second);
  838. }
  839. }
  840. static bool Read(const base::Pickle* m,
  841. base::PickleIterator* iter,
  842. param_type* r) {
  843. size_t size;
  844. if (!iter->ReadLength(&size))
  845. return false;
  846. // Construct by creating in a vector and moving into the flat_map. Properly
  847. // serialized flat_maps will be in-order so this will be O(n). Incorrectly
  848. // serialized ones will still be handled properly.
  849. std::vector<typename param_type::value_type> vect;
  850. vect.resize(size);
  851. for (size_t i = 0; i < size; ++i) {
  852. if (!ReadParam(m, iter, &vect[i].first))
  853. return false;
  854. if (!ReadParam(m, iter, &vect[i].second))
  855. return false;
  856. }
  857. *r = param_type(std::move(vect));
  858. return true;
  859. }
  860. static void Log(const param_type& p, std::string* l) {
  861. l->append("<base::flat_map>");
  862. }
  863. };
  864. template <class P>
  865. struct ParamTraits<std::unique_ptr<P>> {
  866. typedef std::unique_ptr<P> param_type;
  867. static void Write(base::Pickle* m, const param_type& p) {
  868. bool valid = !!p;
  869. WriteParam(m, valid);
  870. if (valid)
  871. WriteParam(m, *p);
  872. }
  873. static bool Read(const base::Pickle* m,
  874. base::PickleIterator* iter,
  875. param_type* r) {
  876. bool valid = false;
  877. if (!ReadParam(m, iter, &valid))
  878. return false;
  879. if (!valid) {
  880. r->reset();
  881. return true;
  882. }
  883. param_type temp(new P());
  884. if (!ReadParam(m, iter, temp.get()))
  885. return false;
  886. r->swap(temp);
  887. return true;
  888. }
  889. static void Log(const param_type& p, std::string* l) {
  890. if (p)
  891. LogParam(*p, l);
  892. else
  893. l->append("NULL");
  894. }
  895. };
  896. // absl types ParamTraits
  897. template <class P>
  898. struct ParamTraits<absl::optional<P>> {
  899. typedef absl::optional<P> param_type;
  900. static void Write(base::Pickle* m, const param_type& p) {
  901. const bool is_set = static_cast<bool>(p);
  902. WriteParam(m, is_set);
  903. if (is_set)
  904. WriteParam(m, p.value());
  905. }
  906. static bool Read(const base::Pickle* m,
  907. base::PickleIterator* iter,
  908. param_type* r) {
  909. bool is_set = false;
  910. if (!iter->ReadBool(&is_set))
  911. return false;
  912. if (is_set) {
  913. P value;
  914. if (!ReadParam(m, iter, &value))
  915. return false;
  916. *r = std::move(value);
  917. }
  918. return true;
  919. }
  920. static void Log(const param_type& p, std::string* l) {
  921. if (p)
  922. LogParam(p.value(), l);
  923. else
  924. l->append("(unset)");
  925. }
  926. };
  927. template <>
  928. struct ParamTraits<absl::monostate> {
  929. typedef absl::monostate param_type;
  930. static void Write(base::Pickle* m, const param_type& p) {}
  931. static bool Read(const base::Pickle* m,
  932. base::PickleIterator* iter,
  933. param_type* r) {
  934. return true;
  935. }
  936. static void Log(const param_type& p, std::string* l) { l->append("()"); }
  937. };
  938. // base/util types ParamTraits
  939. template <typename TypeMarker, typename WrappedType, WrappedType kInvalidValue>
  940. struct ParamTraits<base::IdType<TypeMarker, WrappedType, kInvalidValue>> {
  941. using param_type = base::IdType<TypeMarker, WrappedType, kInvalidValue>;
  942. static void Write(base::Pickle* m, const param_type& p) {
  943. WriteParam(m, p.GetUnsafeValue());
  944. }
  945. static bool Read(const base::Pickle* m,
  946. base::PickleIterator* iter,
  947. param_type* r) {
  948. WrappedType value;
  949. if (!ReadParam(m, iter, &value))
  950. return false;
  951. *r = param_type::FromUnsafeValue(value);
  952. return true;
  953. }
  954. static void Log(const param_type& p, std::string* l) {
  955. LogParam(p.GetUnsafeValue(), l);
  956. }
  957. };
  958. template <typename TagType, typename UnderlyingType>
  959. struct ParamTraits<base::StrongAlias<TagType, UnderlyingType>> {
  960. using param_type = base::StrongAlias<TagType, UnderlyingType>;
  961. static void Write(base::Pickle* m, const param_type& p) {
  962. WriteParam(m, p.value());
  963. }
  964. static bool Read(const base::Pickle* m,
  965. base::PickleIterator* iter,
  966. param_type* r) {
  967. UnderlyingType value;
  968. if (!ReadParam(m, iter, &value))
  969. return false;
  970. *r = param_type(value);
  971. return true;
  972. }
  973. static void Log(const param_type& p, std::string* l) {
  974. LogParam(p.value(), l);
  975. }
  976. };
  977. // IPC types ParamTraits -------------------------------------------------------
  978. // A ChannelHandle is basically a platform-inspecific wrapper around the
  979. // fact that IPC endpoints are handled specially on POSIX. See above comments
  980. // on FileDescriptor for more background.
  981. template <>
  982. struct COMPONENT_EXPORT(IPC) ParamTraits<IPC::ChannelHandle> {
  983. typedef ChannelHandle param_type;
  984. static void Write(base::Pickle* m, const param_type& p);
  985. static bool Read(const base::Pickle* m,
  986. base::PickleIterator* iter,
  987. param_type* r);
  988. static void Log(const param_type& p, std::string* l);
  989. };
  990. template <>
  991. struct COMPONENT_EXPORT(IPC) ParamTraits<LogData> {
  992. typedef LogData param_type;
  993. static void Write(base::Pickle* m, const param_type& p);
  994. static bool Read(const base::Pickle* m,
  995. base::PickleIterator* iter,
  996. param_type* r);
  997. static void Log(const param_type& p, std::string* l);
  998. };
  999. template <>
  1000. struct COMPONENT_EXPORT(IPC) ParamTraits<Message> {
  1001. static void Write(base::Pickle* m, const Message& p);
  1002. static bool Read(const base::Pickle* m,
  1003. base::PickleIterator* iter,
  1004. Message* r);
  1005. static void Log(const Message& p, std::string* l);
  1006. };
  1007. // Windows ParamTraits ---------------------------------------------------------
  1008. #if BUILDFLAG(IS_WIN)
  1009. template <>
  1010. struct COMPONENT_EXPORT(IPC) ParamTraits<HANDLE> {
  1011. typedef HANDLE param_type;
  1012. static void Write(base::Pickle* m, const param_type& p);
  1013. static bool Read(const base::Pickle* m,
  1014. base::PickleIterator* iter,
  1015. param_type* r);
  1016. static void Log(const param_type& p, std::string* l);
  1017. };
  1018. template <>
  1019. struct COMPONENT_EXPORT(IPC) ParamTraits<MSG> {
  1020. typedef MSG param_type;
  1021. static void Write(base::Pickle* m, const param_type& p);
  1022. static bool Read(const base::Pickle* m,
  1023. base::PickleIterator* iter,
  1024. param_type* r);
  1025. static void Log(const param_type& p, std::string* l);
  1026. };
  1027. #endif // BUILDFLAG(IS_WIN)
  1028. //-----------------------------------------------------------------------------
  1029. // Generic message subclasses
  1030. // defined in ipc_logging.cc
  1031. COMPONENT_EXPORT(IPC)
  1032. void GenerateLogData(const Message& message, LogData* data, bool get_params);
  1033. #if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
  1034. inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
  1035. const std::string& output_params = msg->output_params();
  1036. if (!l->empty() && !output_params.empty())
  1037. l->append(", ");
  1038. l->append(output_params);
  1039. }
  1040. template <class ReplyParamType>
  1041. inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
  1042. const Message* msg) {
  1043. if (msg->received_time() != 0) {
  1044. std::string output_params;
  1045. LogParam(reply_params, &output_params);
  1046. msg->set_output_params(output_params);
  1047. }
  1048. }
  1049. inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
  1050. if (msg->sent_time()) {
  1051. // Don't log the sync message after dispatch, as we don't have the
  1052. // output parameters at that point. Instead, save its data and log it
  1053. // with the outgoing reply message when it's sent.
  1054. LogData* data = new LogData;
  1055. GenerateLogData(*msg, data, true);
  1056. msg->set_dont_log();
  1057. reply->set_sync_log_data(data);
  1058. }
  1059. }
  1060. #else
  1061. inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
  1062. template <class ReplyParamType>
  1063. inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
  1064. const Message* msg) {}
  1065. inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
  1066. #endif
  1067. } // namespace IPC
  1068. #endif // IPC_IPC_MESSAGE_UTILS_H_